Vue-04
- (二十八)、Vuex
- 1.Vuex的简介
- (1).vuex是什么
- (2).什么时候使用Vuex
- (3).Vuex工作原理图
- 2.求和案列_纯Vue版本
- 3.求和案列_Vuex
- (1).初始化状态
- (2).操作状态
- 4.求和案列_Vuex的getters
- (1).Vuex的getters类似于 Vue的computed
- 5.求和案列_Vuex中的mapSteat和mapGetters
- (1).靠自己写优化
- (2). 利用mapState和mapGetter
- 6.求和案列_Vuex中的mapMutations
- 7.求和案列_Vuex中的mapActions
- 8.求和案列_Vuex综合应用
- (二十九)、路由
- 1.相关理解
- (1).vue-route的理解
- (2).SPA的理解
- 2.路由的基本使用(一级路由)
- (1).搭建静态页面
- (2).安装vue-route
- 3.一个路径匹配多个组件
- 4.二级、三级路由
- (1).二级路由
- (2).三级目录
- 5.给路由传递Params参数 (使用params)
- (1).传递参数、参数收取
- 6.给路由传递query参数 (使用query)
- (1).传递参数、参数获取
- (2).一个路由用两种方式传参
- 7.命名路由简化跳转、传参
- (1).命名路由
- 8.路由的props配置 (插值语法)
- (1).props映射自定义的静态数据给当前的路由
- (2).映射params参数为props传给路由组件 (只兼容params)⭐
- (3).propos是一个函数 (兼容params和query)
- (4).props函数里面有一个参数 (常用⭐⭐⭐⭐)
- 9.编程式路由导航
- (1).编程式路由的前进和倒退
(二十八)、Vuex
1.Vuex的简介
(1).vuex是什么
- 专门在Vue中实现集中式状态管理的一个插件,对Vue应用中的多个组件的共享状态进行集中式的管理(读/写),也可以认为是一种组件间通信的方式,且适用于任意组件间通信。
- github 站点: https://github.com/vuejs/vuex
- 在线文档: https://vuex.vuejs.org/zh/guide/
(2).什么时候使用Vuex
- 多个组件依赖同一状态。
- 来自不同组件的行为需要变更容易状态。
- 多个组件要共享状态。
(3).Vuex工作原理图
2.求和案列_纯Vue版本
App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{
Count,
}
}
</script>
<style>
</style>
Count.vue
<template>
<div>
<h2>当前求和未: {{ sum }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsync">异步加</button>
</div>
</template>
<script>
export default {
name: "Count",
data() {
return {
sum: 0, //总和
n: 1, //
};
},
methods: {
increment() {
this.sum += this.n;
},
decrement() {
this.sum -= this.n;
},
incrementOdd() {
if (this.sum%2){ // 0 为假、1为真
this.sum += this.n;
}
},
// 异步+
incrementAsync() {
setTimeout(()=>{
// 函数体
this.sum += this.n;
},500)
},
},
};
</script>
<style>
</style>
修改代码为:
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
3.求和案列_Vuex
(1).初始化状态
安装vuex: 如果是vue2那么就要安装下面的vue@3
假如安装的不是这个版本就会发现:不存在$store
npm install vuex@3
- 搭建环境
- 我们引入vue目的是为了使用Vue.use()。引入我们刚才下载的vuex。然后应用Vuex。再然后创建store。最后抛出 store。
store.js
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// TODO: 创建Store 用于管理: state对象、mutations对象
const store=new Vuex.Store()
// TODO: 抛出store
export default store
- 我们这里的任务需要引入vuex。然后利用使用store.js创建的store。
main.js
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
查看组件的vc
2.初始化状态
App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{
Count,
}
}
</script>
<style>
</style>
store.js
就是初始化变量
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
}
就是响应的操作
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数
const actions_jsxs = {
jia(a, b) {
console.log(a, b);
}
}
传送到我们创建的store。 且下面的两个属性不能变。固定的
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs
})
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数
const actions_jsxs = {
jia(a, b) {
console.log(a, b);
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs
})
// TODO: 抛出store
export default store
main.js
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
count.vue
获取$store中我们存的数据
<h2>当前求和未: {{ $store.state.sum }}</h2>
<template>
<div>
<h2>当前求和未: {{ $store.state.sum }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button >-</button>
<button >奇数再加</button>
<button >异步加</button>
</div>
</template>
<script>
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
methods: {
increment() {
this.sum += this.n;
},
},
mounted() {
console.log('vc',this)
},
};
</script>
<style>
</style>
(2).操作状态
App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{
Count,
}
}
</script>
<style>
</style>
store.js
1.设置状态 2.设置响应 3.设置加工状态
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
context.commit('JIA_jsxs',value); // 通知mutations去
console.log(context, value);
},
Async_jia(context,value){
setTimeout(() =>{
context.commit('Async_jsxs',value);
},500)
},
describe_jia(context,value){
context.commit('describe_jsxs',value);
},
incrementOdd_jia(context,value){
context.commit('incrementOdd_jsxs',value);
}
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs={
JIA_jsxs(state_1,value){ // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum+=value
},
Async_jsxs(state_2,value){
state_2.sum+=value
},
describe_jsxs(state_3,value){
state_3.sum-=value
},
incrementOdd_jsxs(state_4,value){
if(state_4.sum%2){
state_4.sum+=value;
}
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations:mutations_jsxs
})
// TODO: 抛出store
export default store
main.js
1. 传入 $store
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
count.vue
1. 设置分发
<template>
<div>
<h2>当前求和未: {{ $store.state.sum }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="describe">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsyn">异步加</button>
</div>
</template>
<script>
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
methods: {
increment() {
this.$store.dispatch('jia',this.n)
},
incrementAsyn(){
this.$store.dispatch('Async_jia',this.n)
},
describe(){
this.$store.dispatch('describe_jia',this.n)
},
incrementOdd(){
this.$store.dispatch('incrementOdd_jia',this.n)
}
},
mounted() {
console.log('vc',this)
},
};
</script>
<style>
</style>
4.求和案列_Vuex的getters
我们的vc管理的store中有一个getters
(1).Vuex的getters类似于 Vue的computed
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{
Count,
}
}
</script>
<style>
</style>
store.js
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
context.commit('JIA_jsxs', value); // 通知mutations去
console.log(context, value);
},
Async_jia(context, value) {
setTimeout(() => {
context.commit('Async_jsxs', value);
}, 500)
},
describe_jia(context, value) {
context.commit('describe_jsxs', value);
},
incrementOdd_jia(context, value) {
context.commit('incrementOdd_jsxs', value);
},
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs = {
JIA_jsxs(state_1, value) { // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum += value
},
Async_jsxs(state_2, value) {
state_2.sum += value
},
describe_jsxs(state_3, value) {
state_3.sum -= value
},
incrementOdd_jsxs(state_4, value) {
if (state_4.sum % 2) {
state_4.sum += value;
}
}
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
// TODO: 抛出store
export default store
Count.vue
<h2>乘以100之后: {{$store.getters.demo}}</h2>
<template>
<div>
<h2>当前求和未: {{ $store.state.sum }}</h2>
<h2>乘以100之后: {{$store.getters.demo}}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="describe">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsyn">异步加</button>
</div>
</template>
<script>
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
methods: {
increment() {
this.$store.dispatch('jia',this.n)
},
incrementAsyn(){
this.$store.dispatch('Async_jia',this.n)
},
describe(){
this.$store.dispatch('describe_jia',this.n)
},
incrementOdd(){
this.$store.dispatch('incrementOdd_jia',this.n)
}
},
mounted() {
console.log('vc',this)
},
};
</script>
<style>
</style>
我们要注意的是: 这里的 getters的一个对象。里面的的对象需要时函数。并且getters和state是同级的,
结果
5.求和案列_Vuex中的mapSteat和mapGetters
我们的的count.vue调用总和的的时候很麻烦,我们想办法优化一下
(1).靠自己写优化
<h2>当前求和未: {{ sum }}</h2>
<h2>乘以100之后: {{beiSum}}</h2>
computed:{
// 自己计算属性: 靠state
sum(){
return this.$store.state.sum
},
// 自己计算属性: 靠getters
beiSum(){
return this.$store.getters.demo
}
},
<template>
<div>
<h2>当前求和未: {{ sum }}</h2>
<h2>乘以100之后: {{beiSum}}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="describe">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsyn">异步加</button>
</div>
</template>
<script>
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
computed:{
// mapState生成计算属性
// 自己计算属性
sum(){
return this.$store.state.sum
},
beiSum(){
return this.$store.getters.demo
}
},
methods: {
increment() {
this.$store.dispatch('jia',this.n)
},
incrementAsyn(){
this.$store.dispatch('Async_jia',this.n)
},
describe(){
this.$store.dispatch('describe_jia',this.n)
},
incrementOdd(){
this.$store.dispatch('incrementOdd_jia',this.n)
}
},
mounted() {
console.log('vc',this)
},
};
</script>
<style>
</style>
(2). 利用mapState和mapGetter
main.js
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
name: 'jsxs'
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
store.js
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
name: 'jsxs'
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
context.commit('JIA_jsxs', value); // 通知mutations去
console.log(context, value);
},
Async_jia(context, value) {
setTimeout(() => {
context.commit('Async_jsxs', value);
}, 500)
},
describe_jia(context, value) {
context.commit('describe_jsxs', value);
},
incrementOdd_jia(context, value) {
context.commit('incrementOdd_jsxs', value);
},
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs = {
JIA_jsxs(state_1, value) { // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum += value
},
Async_jsxs(state_2, value) {
state_2.sum += value
},
describe_jsxs(state_3, value) {
state_3.sum -= value
},
incrementOdd_jsxs(state_4, value) {
if (state_4.sum % 2) {
state_4.sum += value;
}
}
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
// TODO: 抛出store
export default store
Count.vue
<h2>当前求和未: {{ sum_t }}</h2>
<h2>乘以100之后: {{beiSum}}</h2>
<h2>名字是: {{usernames}}</h2>
// Todo: 这里需要使用到{}
import {mapGetters, mapState} from 'vuex'
computed:{
// 为什么要用三个点,目的是把mapState给摊开。为什么要摊开,因为不能有 { {} }
...mapState({
sum_t:'sum', // 第一个是现在页面调用的,第二个是store区域的state
usernames:'name'
}),
...mapGetters({
beiSum:'demo' //第一个参数是现在页面调用的,第二个是getters区域的
})
},
<template>
<div>
<h2>当前求和未: {{ sum_t }}</h2>
<h2>乘以100之后: {{beiSum}}</h2>
<h2>名字是: {{usernames}}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="describe">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsyn">异步加</button>
</div>
</template>
<script>
// Todo: 这里需要使用到{}
import {mapGetters, mapState} from 'vuex'
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
computed:{
// 为什么要用三个点,目的是把mapState给摊开。为什么要摊开,因为不能有 { {} }
...mapState({
sum_t:'sum',
usernames:'name'
}),
...mapGetters({
beiSum:'demo'
})
},
methods: {
increment() {
this.$store.dispatch('jia',this.n)
},
incrementAsyn(){
this.$store.dispatch('Async_jia',this.n)
},
describe(){
this.$store.dispatch('describe_jia',this.n)
},
incrementOdd(){
this.$store.dispatch('incrementOdd_jia',this.n)
}
},
};
</script>
<style>
</style>
6.求和案列_Vuex中的mapMutations
假如说actions中的方法没有逻辑,那么我们可以直接在Vue中直接传入Mutations。
main.js
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
main.js
注释普通+和-
// jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
// context.commit('JIA_jsxs', value); // 通知mutations去
// console.log(context, value);
// },
// describe_jia(context, value) {
// context.commit('describe_jsxs', value);
// },
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
name: 'jsxs'
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
// jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
// context.commit('JIA_jsxs', value); // 通知mutations去
// console.log(context, value);
// },
Async_jia(context, value) {
setTimeout(() => {
context.commit('Async_jsxs', value);
}, 500)
},
// describe_jia(context, value) {
// context.commit('describe_jsxs', value);
// },
incrementOdd_jia(context, value) {
context.commit('incrementOdd_jsxs', value);
},
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs = {
JIA_jsxs(state_1, value) { // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum += value
},
Async_jsxs(state_2, value) {
state_2.sum += value
},
describe_jsxs(state_3, value) {
state_3.sum -= value
},
incrementOdd_jsxs(state_4, value) {
if (state_4.sum % 2) {
state_4.sum += value;
}
}
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
// TODO: 抛出store
export default store
count.vue
调用的一定要添加参数
<button @click="increment(n)">+</button>
<button @click="describe(n)">-</button>
传递普通+
methods:{
// increment(value) {
// this.$store.commit('JIA_jsxs',value)
// },
...mapMutations({ //这里相当于上面的操作
increment: "JIA_jsxs",
}),
传递普通-
// describe() { //这里相当于上面的操作
// this.$store.commit("describe_jia", this.n);
// },
...mapMutations({
describe:'describe_jsxs'
}),
}
<template>
<div>
<h2>当前求和未: {{ sum_t }}</h2>
<h2>乘以100之后: {{ beiSum }}</h2>
<h2>名字是: {{ usernames }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option></select
> <button @click="increment(n)">+</button>
<button @click="describe(n)">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementAsyn">异步加</button>
</div>
</template>
<script>
// Todo: 这里需要使用到{}
import { mapGetters, mapState, mapMutations } from "vuex";
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
computed: {
// 为什么要用三个点,目的是把mapState给摊开。为什么要摊开,因为不能有 { {} }
...mapState({
sum_t: "sum",
usernames: "name",
}),
...mapGetters({
beiSum: "demo",
}),
},
methods: {
// 靠自己写方法、直接提交到Mutations
// increment(value) {
// this.$store.commit('JIA_jsxs',value)
// },
...mapMutations({
increment: "JIA_jsxs",
}),
incrementAsyn() {
this.$store.dispatch("Async_jia", this.n);
},
// describe() {
// this.$store.commit("describe_jia", this.n);
// },
...mapMutations({
describe:'describe_jsxs'
}),
incrementOdd() {
this.$store.dispatch("incrementOdd_jia", this.n);
},
},
};
</script>
<style>
</style>
7.求和案列_Vuex中的mapActions
App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{
Count,
}
}
</script>
<style>
</style>
main.js
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
store.js
保持不动
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
name: 'jsxs'
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
// jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
// context.commit('JIA_jsxs', value); // 通知mutations去
// console.log(context, value);
// },
Async_jia(context, value) {
setTimeout(() => {
context.commit('Async_jsxs', value);
}, 500)
},
// describe_jia(context, value) {
// context.commit('describe_jsxs', value);
// },
incrementOdd_jia(context, value) {
context.commit('incrementOdd_jsxs', value);
},
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs = {
JIA_jsxs(state_1, value) { // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum += value
},
Async_jsxs(state_2, value) {
state_2.sum += value
},
describe_jsxs(state_3, value) {
state_3.sum -= value
},
incrementOdd_jsxs(state_4, value) {
if (state_4.sum % 2) {
state_4.sum += value;
}
}
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
// TODO: 抛出store
export default store
count.vue
methods{
// incrementOdd(value) {
// this.$store.dispatch("incrementOdd_jia", value);
// },
// incrementAsyn() {
// this.$store.dispatch("Async_jia", this.n);
// },
...mapActions({
incrementOdd:'incrementOdd_jia', //可以替换掉上面的
incrementAsyn:'Async_jia' // 可以替换上面的
})
}
<template>
<div>
<h2>当前求和未: {{ sum_t }}</h2>
<h2>乘以100之后: {{ beiSum }}</h2>
<h2>名字是: {{ usernames }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option></select
> <button @click="increment(n)">+</button>
<button @click="describe(n)">-</button>
<button @click="incrementOdd(n)">奇数再加</button>
<button @click="incrementAsyn(n)">异步加</button>
</div>
</template>
<script>
// Todo: 这里需要使用到{}
import { mapGetters, mapState, mapMutations,mapActions } from "vuex";
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
computed: {
// 为什么要用三个点,目的是把mapState给摊开。为什么要摊开,因为不能有 { {} }
...mapState({
sum_t: "sum",
usernames: "name",
}),
...mapGetters({
beiSum: "demo",
}),
},
methods: {
// 靠自己写方法、直接提交到Mutations
// increment(value) {
// this.$store.commit('JIA_jsxs',value)
// },
...mapMutations({
increment: "JIA_jsxs",
}),
// describe() {
// this.$store.commit("describe_jia", this.n);
// },
...mapMutations({
describe:'describe_jsxs'
}),
// incrementOdd(value) {
// this.$store.dispatch("incrementOdd_jia", value);
// },
// incrementAsyn() {
// this.$store.dispatch("Async_jia", this.n);
// },
...mapActions({
incrementOdd:'incrementOdd_jia',
incrementAsyn:'Async_jia'
})
},
};
</script>
<style>
</style>
8.求和案列_Vuex综合应用
App.vue
<template>
<div>
<Count/>
<Person/>
</div>
</template>
<script>
import Count from './components/Count.vue'
import Person from './components/Person.vue'
export default {
name:'App',
components:{
Count,
Person
}
}
</script>
<style>
</style>
main.js
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import store from './vuex/store' // 引入vuex
Vue.config.productionTip = false;
const vm=new Vue({
store: store, // TODO: 这里只有当我们应用了vuex才会被Vue自动管理。 --> store.js--->Vue.use()
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
store.js
import Vue from 'vue' // 目的是调用: use()
import Vuex from 'vuex' // 引入插件vuex
Vue.use(Vuex) // 应用Vuex
// 初始化状态->需要写成一个对象,要管理n多个组件的状态
const state_jsxs = {
sum: 0,
name: 'jsxs'
}
// 创建一个actions,值为一个对象,包含n个响应组件"动作"的函数---> 可以拿到分发的值
const actions_jsxs = {
// jia(context, value) { // context 是一个迷你版的$store。我们要用context.commit()去通知mutations加工状态。 value是分发传递的值
// context.commit('JIA_jsxs', value); // 通知mutations去
// console.log(context, value);
// },
Async_jia(context, value) {
setTimeout(() => {
context.commit('Async_jsxs', value);
}, 500)
},
// describe_jia(context, value) {
// context.commit('describe_jsxs', value);
// },
incrementOdd_jia(context, value) {
context.commit('incrementOdd_jsxs', value);
},
}
// 加工状态: 这里可以拿到状态设定的值
const mutations_jsxs = {
JIA_jsxs(state_1, value) { // Todo: 这里的第一个参数是是一个对象里面可以获取state状态(),value是分发传递的值
state_1.sum += value
},
Async_jsxs(state_2, value) {
state_2.sum += value
},
describe_jsxs(state_3, value) {
state_3.sum -= value
},
incrementOdd_jsxs(state_4, value) {
if (state_4.sum % 2) {
state_4.sum += value;
}
}
}
// getters中配置的是state经过加工后的值--- 类似于Vue中的computed
const getters_jsxs = {
// TODO: 必须需要是返回值
demo(state_5, value) { // 第一个参数是: $state。第二个参数是传递过来的值。
return state_5.sum*100
}
}
// TODO: 创建Store 用于管理: state对象、mutations对象
const store = new Vuex.Store({
state: state_jsxs,
actions: actions_jsxs,
mutations: mutations_jsxs,
getters:getters_jsxs
})
// TODO: 抛出store
export default store
count.vue
<template>
<div>
<h2>当前求和未: {{ sum_t }}</h2>
<h2>乘以100之后: {{ beiSum }}</h2>
<h2>名字是: {{ usernames }}</h2>
<!-- v-model.number意思是: 我们接受到的数据是数值 -->
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option></select
> <button @click="increment(n)">+</button>
<button @click="describe(n)">-</button>
<button @click="incrementOdd(n)">奇数再加</button>
<button @click="incrementAsyn(n)">异步加</button>
</div>
</template>
<script>
// Todo: 这里需要使用到{}
import { mapGetters, mapState, mapMutations,mapActions } from "vuex";
export default {
name: "Count",
data() {
return {
n: 1, //
};
},
computed: {
// 为什么要用三个点,目的是把mapState给摊开。为什么要摊开,因为不能有 { {} }
...mapState({
sum_t: "sum",
usernames: "name",
}),
...mapGetters({
beiSum: "demo",
}),
},
methods: {
// 靠自己写方法、直接提交到Mutations
// increment(value) {
// this.$store.commit('JIA_jsxs',value)
// },
...mapMutations({
increment: "JIA_jsxs",
}),
// describe() {
// this.$store.commit("describe_jia", this.n);
// },
...mapMutations({
describe:'describe_jsxs'
}),
// incrementOdd(value) {
// this.$store.dispatch("incrementOdd_jia", value);
// },
// incrementAsyn() {
// this.$store.dispatch("Async_jia", this.n);
// },
...mapActions({
incrementOdd:'incrementOdd_jia',
incrementAsyn:'Async_jia'
})
},
};
</script>
<style>
</style>
Person.vue
获取总和
<template>
<div class="p">
<h2>我是Person组件</h2>
<h3>求和为: {{sum}}</h3>
</div>
</template>
<script>
name:'Person';
export default {
computed:{
sum(){
return this.$store.state.sum;
}
}
}
</script>
<style>
.p{
background-color: beige;
padding: 10px
}
</style>
(二十九)、路由
1.相关理解
(1).vue-route的理解
- vue的一个插件库
- 专门用来实现一个SPA应用。
- 基于vue的项目基本都会用到此库。
- 中文文档: https://router.vuejs.org/
- 下载:
npm install vue-router -S
。
(2).SPA的理解
- 单页面web应用 (single page web application)。
- 整个应用只有一个完成的页面。
- 点击页面中的连接不会刷新页面,只会做页面的局部更新。
- 数据都需呀通过ajax请求获取,并在前端异步展现。
2.路由的基本使用(一级路由)
(1).搭建静态页面
APP.vue
<template>
<div>
<div>
<Header></Header>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<About></About>
<Home></Home>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
name:'App'
import Header from './components/Header.vue'
import About from './pages/About.vue'
import Home from './pages/Home.vue'
export default {
components:{
Header,
About,
Home
}
}
</script>
<style>
</style>
Header.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>React Router Demo</h2></div>
</div>
</div>
</div>
</template>
<script>
name:'Header'
export default {
}
</script>
<style>
</style>
About.vue
<template>
<div>
<h2>about</h2>
</div>
</template>
<script>
name:'About'
export default {
}
</script>
<style>
</style>
Home.vue
<template>
<div>
<h2>home</h2>
</div>
</template>
<script>
name:'Home'
export default {
}
</script>
<style>
</style>
(2).安装vue-route
Vue2.0版本的需要下载这个
npm install vue-router@3
如果下载最新版本的话,一i的那个会报错的。
router/index.js
在这里我们主要配置路由和路由跳转的组件
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router=new VueRouter({
routes:[// 一堆路由。一个对象就是一个路由
{
path:'/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component:Home // 组件名
},
{
path:'/about',
component:About
},
],
})
// 抛出我们创建的路由器
export default router
main.js
我们需要引入我们创建的路由
import Vue from 'vue' // 引入阉割版本的vue
import App from './App.vue' // 引入App.vue组件
import router from './router/index' //引入我们刚才编写的router配置
Vue.config.productionTip = false;
const vm=new Vue({
router: router, // 传入路由
render: h => h(App)
}).$mount('#app');
console.log('vm',vm)
App.vue
更换路由跳转标签
这里我们也不需要注册路由跳转的组件。直接由路由管理了
<!-- 原始Html页面使用a标签进行页面跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 在Vue中使用router-link实现路径改变 -->
<!-- router-link帮我们封装了active-class:"高亮的类名"。所以在引号里面我们添加高亮的样式即可。但因为我们引用了Bootstrap.css。有一个已经写好的active样式。所以active-class="active"-->
<router-link class="list-group-item " active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link >
<!-- <About></About>
<Home></Home> -->
<!-- 展示我们路径改变后的组件组件 -->
<router-view></router-view>
<template>
<div>
<div>
<Header></Header>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始Html页面使用a标签进行页面跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 在Vue中使用router-link实现路径改变 -->
<!-- router-link帮我们封装了active-class:"高亮的类名"。所以在引号里面我们添加高亮的样式即可。但因为我们引用了Bootstrap.css。有一个已经写好的active样式。所以active-class="active"-->
<router-link class="list-group-item " active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link >
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- <About></About>
<Home></Home> -->
<!-- 展示我们路径改变后的组件组件 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
name:'App'
import Header from './components/Header.vue'
// TODO: 因为这两个组件交给路由器管理了,所以这个我们可以去掉
// import About from './pages/About.vue'
// import Home from './pages/Home.vue'
export default {
components:{
Header,
// About,
// Home
},
mounted() {
console.log(this)
},
}
</script>
<style>
</style>
compoments/Header.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>React Router Demo</h2></div>
</div>
</div>
</div>
</template>
<script>
name:'Header'
export default {
}
</script>
<style>
</style>
pages/About.vue
<template>
<div>
<h2>about</h2>
</div>
</template>
<script>
name:'About'
export default {
}
</script>
<style>
</style>
pages/About.vue
<template>
<div>
<h2>home</h2>
</div>
</template>
<script>
name:'Home'
export default {
}
</script>
<style>
</style>
当我们index.js里面使用到 Vue.use(Router)的时候会展示如下
3.一个路径匹配多个组件
index.js
如果我们需要在一个路径下由多个组件需要在这里引入对应的组件,并用components租车。
routes:[
{
path:'/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
components:{
Home, // 组件名
Home2
}
},
]
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import Home2 from '../pages/Home2.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router=new VueRouter({
routes:[// 一堆路由。一个对象就是一个路由
{
path:'/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
components:{
Home, // 组件名
Home2
}
},
{
path:'/about',
component:About
},
],
})
// 抛出我们创建的路由器
export default router
App.vue
我们假如对试图起名字,那么我们就只能读去定名的部分。不起名字就是默认全部
<!-- 展示我们路径改变后的组件组件 -->
<router-view ></router-view>
<router-view name="Home1"></router-view>
<router-view name="Home2"></router-view>
<template>
<div>
<div>
<Header></Header>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始Html页面使用a标签进行页面跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 在Vue中使用router-link实现路径改变 -->
<!-- router-link帮我们封装了active-class:"高亮的类名"。所以在引号里面我们添加高亮的样式即可。但因为我们引用了Bootstrap.css。有一个已经写好的active样式。所以active-class="active"-->
<router-link class="list-group-item " active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link >
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- <About></About>
<Home></Home> -->
<!-- 展示我们路径改变后的组件组件 -->
<router-view ></router-view>
<router-view name="Home1"></router-view>
<router-view name="Home2"></router-view>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
name:'App'
import Header from './components/Header.vue'
// TODO: 因为这两个组件交给路由器管理了,所以这个我们可以去掉
// import About from './pages/About.vue'
// import Home from './pages/Home.vue'
export default {
components:{
Header,
// About,
// Home
},
mounted() {
console.log(this)
},
}
</script>
<style>
</style>
4.二级、三级路由
(1).二级路由
Messages.vue
<template>
<div>
<ul>
<li><a href="/message1">message001</a> </li>
<li><a href="/message2">message002</a> </li>
<li><a href="/message/3">message003</a> </li>
</ul>
</div>
</template>
<script>
export default {
name:'message',
};
</script>
<style>
</style>
News.vue
<template>
<div>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</div>
</template>
<script>
export default {
name: "New",
};
</script>
<style>
</style>
index.js
1.我们在这里引入: 二级目录的组件。
然后在一级目录下的属性写上 : Children:[{}]
2.路径的两种写法:
(1). path: '/home/message', //因为我们是二级目录所以我们需要加上上一级目录。
(2).path: 'message', 我们可以把前面的目录和/一起删除.
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: '/home/message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages
},
{
path: '/home/News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级、三级目录
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: '/home/message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages
},
{
path: '/home/News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Home.vue
1.接受:
<li>
<router-link
class="list-group-item"
active-class="active"
to="/home/News" // 这里只有一种形式 几级就有几个/
>News</router-link
>
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link
class="list-group-item"
active-class="active"
to="/home/News"
>News</router-link
>
</li>
<li>
<router-link
class="list-group-item"
active-class="active"
to="/home/message"
>Message</router-link
>
</li>
</ul>
<router-view></router-view>
</div>
</div>
</template>
<script>
name: "Home";
export default {};
</script>
<style>
</style>
(2).三级目录
Details.vue
创建第三级目录
<template>
<div>
<ul>
<li>ID: ??</li>
<li>Title: ??</li>
<li>CONTENT: ??</li>
</ul>
</div>
</template>
<script>
export default {
name:'Detail',
data() {
return {
message:[
{id:'001',title:'消息1',content:'你好,文本1'},
{id:'002',title:'消息2',content:'你好,文本2'},
{id:'003',title:'消息3',content:'你好,文本3'},
]
}
},
}
</script>
<style>
</style>
index.js
第二级目录下继续放childre
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
path: 'detail',
component: Details
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},]
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
path: 'detail',
component: Details
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Messages.vue
访问目录中....
<ul>
<li v-for="item in message" :key="item.id">
<router-link to="/home/message/detail">{{item.title}}</router-link
>
</li>
</ul>
<template>
<div>
<ul>
<li v-for="item in message" :key="item.id">
<router-link to="/home/message/detail">{{item.title}}</router-link
>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "message",
data() {
return {
message: [
{ id: "001", title: "消息1", content: "你好,文本1" },
{ id: "002", title: "消息2", content: "你好,文本2" },
{ id: "003", title: "消息3", content: "你好,文本3" },
],
};
},
};
</script>
<style>
</style>
5.给路由传递Params参数 (使用params)
(1).传递参数、参数收取
index.js
接受参数:
path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
component: Details
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Message.vue
传递参数
1. 注意这里需要加:
2. 这里我们需要使用飘号 ``
3. 传递参数用得是 ${}
<router-link :to="`/home/message/detail/${item.id}/${item.title}/${item.content}`">{{item.title}}</router-link>
<template>
<div>
<ul>
<li v-for="item in message" :key="item.id">
<router-link :to="`/home/message/detail/${item.id}/${item.title}/${item.content}`">{{item.title}}</router-link
>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "message",
data() {
return {
message: [
{ id: "001", title: "消息1", content: "你好,文本1" },
{ id: "002", title: "消息2", content: "你好,文本2" },
{ id: "003", title: "消息3", content: "你好,文本3" },
],
};
},
};
</script>
<style>
</style>
Detail.vue
index.js和detail.vue的属性名一定要保持一致。其余的不用
eg: id 和 id
<template>
<div>
<ul>
<li>ID: {{ $route.params.id }}</li>
<li>Title: {{ $route.params.title }}</li>
<li>CONTENT: {{ $route.params.content }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
我们这里传参主要借助于:我们的插件里面的$route
6.给路由传递query参数 (使用query)
(1).传递参数、参数获取
messages.vue
<!-- 路由切换时,携带query参数 -->
<router-link :to="`/home/message/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{item.title}}</router-link
>
<template>
<div>
<ul>
<li v-for="item in message" :key="item.id">
<!-- 路由切换时: 携带params参数 -->
<!-- <router-link :to="`/home/message/detail/${item.id}/${item.title}/${item.content}`">{{item.title}}</router-link
> -->
<!-- 路由切换时,携带query参数 -->
<router-link :to="`/home/message/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{item.title}}</router-link
>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "message",
data() {
return {
message: [
{ id: "001", title: "消息1", content: "你好,文本1" },
{ id: "002", title: "消息2", content: "你好,文本2" },
{ id: "003", title: "消息3", content: "你好,文本3" },
],
};
},
};
</script>
<style>
</style>
index.js
path:'detail', // query参数无需声明即可接受
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
// path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
path:'detail', // query参数无需声明即可接受
component: Details
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Detail.vue
这里我们需要使用到 query
<ul>
<li>ID: {{ $route.query.id }}</li>
<li>Title: {{ $route.query.title }}</li>
<li>CONTENT: {{ $route.query.content }}</li>
</ul>
<template>
<div>
<ul>
<li>ID: {{ $route.query.id }}</li>
<li>Title: {{ $route.query.title }}</li>
<li>CONTENT: {{ $route.query.content }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
(2).一个路由用两种方式传参
id用params传参,其余的用query
path: 'detail/:id' // 只输入id即可
其余的按部就班....
7.命名路由简化跳转、传参
(1).命名路由
index.js
我们通过命名,可以在传参的时候可以用名字来代替较为麻烦的路径
children:[
{
// path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
path:'detail', // query参数无需声明即可接受
component: Details,
name:'xiangqing' // 命名
}
]
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
// path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
path:'detail', // query参数无需声明即可接受
component: Details,
name:'xiangqing'
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Details.vue
是对象的形式。
<router-link
:to="{ name: 'xiangqing',
params: {}, // params和query的顺序不是固定的,假如为空,可以省略
query: { id: item.id, title: item.title, content: item.content },
}"
>{{ item.title }}</router-link
>
<template>
<div>
<ul>
<li v-for="item in message" :key="item.id">
<!-- 路由切换时: 携带params参数 -->
<!-- <router-link :to="`/home/message/detail/${item.id}/${item.title}/${item.content}`">{{item.title}}</router-link
> -->
<!-- 路由切换时,携带query参数 -->
<!-- <router-link :to="`/home/message/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{item.title}}</router-link
> -->
<!-- 命名路由跳转、传参 -->
<router-link
:to="{
name: 'xiangqing',
params: {}, // params和query的顺序不是固定的,假如为空,可以省略
query: { id: item.id, title: item.title, content: item.content },
}"
>{{ item.title }}</router-link
>
</li>
</ul>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "message",
data() {
return {
message: [
{ id: "001", title: "消息1", content: "你好,文本1" },
{ id: "002", title: "消息2", content: "你好,文本2" },
{ id: "003", title: "消息3", content: "你好,文本3" },
],
};
},
};
</script>
<style>
</style>
8.路由的props配置 (插值语法)
我们通过插值语法获取信息太过繁琐。用Computed手动计算太过于冗余。所以Vue使用props接受比较简介
(1).props映射自定义的静态数据给当前的路由
index.js
props:{carName:'马自达-阿特兹'} //通过props映射自定义的静态数据给当前的路由
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
// path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
path:'detail', // query参数无需声明即可接受
component: Details,
name:'xiangqing',
props:{carName:'马自达-阿特兹'} //通过props映射自定义的静态数据给当前的路由
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Details.vue
props:['carName'], // 接受传递过来的而参数
<template>
<div>
<ul>
<!-- <li>ID: {{ $route.query.id }}</li>
<li>Title: {{ $route.query.title }}</li>
<li>CONTENT: {{ $route.query.content }}</li> -->
<li>carName:{{carName}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
props:['carName'], // 接受传递过来的而参数
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
(2).映射params参数为props传给路由组件 (只兼容params)⭐
index.js
props:true //只能映射params参数为props传给路由组件
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
// path:'detail', // query参数无需声明即可接受
component: Details,
name:'xiangqing',
// props:{carName:'马自达-阿特兹'} //通过props映射自定义的静态数据给当前的路由
props:true //映射params参数为props传给路由组件
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
Details.vue
<li>ID: {{ id }}</li>
<li>Title: {{ title }}</li>
<li>CONTENT: {{ content }}</li>
props:['id','title','content'], // 接受传递过来的而参数
<template>
<div>
<ul>
<li>ID: {{ id }}</li>
<li>Title: {{ title }}</li>
<li>CONTENT: {{ content }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
props:['id','title','content'], // 接受传递过来的而参数
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
只能是params。query的不行
(3).propos是一个函数 (兼容params和query)
index.js
props(){
return {id: '001', title: '123', content: "4545"}
}
// TODO: 该文件是Vue路由器文件,路由管理着所有的路由
import Vue from 'vue' // 引入阉割版本的vue
import VueRouter from 'vue-router' // 引入路由插件
// TODO:引入我们需要的组件
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
// TODO: 引入我们的二级
import News from '../pages/New.vue'
import Messages from '../pages/Messages.vue'
// TODO: 引入我们的三级
import Details from '../pages/Detail.vue'
Vue.use(VueRouter) // 使用路由
// 创建一个路由器,管理所有的路由
const router = new VueRouter({
routes: [// 一堆路由。一个对象就是一个路由
{
path: '/home', // 假如说访问的路径名是这个的话,我们就展示下面这个组件
component: Home, // 组件名
children: [ // TODO: 因为是一级路由的子目录所以放在children这个数组种
{
path: 'message', //因为我们是二级目录所以我们需要加上上一级目录
component: Messages,
children:[
{
path: 'detail/:id/:title/:content', // 我们这里放置占位符,用来声明接受params参数
// path:'detail', // query参数无需声明即可接受
component: Details,
name:'xiangqing',
// props:{carName:'马自达-阿特兹'} //通过props映射自定义的静态数据给当前的路由
// props:true //映射params参数为props传给路由组件
props(){
return {id: '001', title: '123', content: "4545"}
}
}
]
},
{
path: 'News', //因为我们是二级目录所以我们需要加上上一级目录
component: News
},
]
},
{
path: '/about',
component: About
},
],
})
// 抛出我们创建的路由器
export default router
details.vue
<template>
<div>
<ul>
<li>ID: {{ id }}</li>
<li>Title: {{ title }}</li>
<li>CONTENT: {{ content }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
props:['id','title','content'], // 接受传递过来的而参数
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
(4).props函数里面有一个参数 (常用⭐⭐⭐⭐)
index.js
props(route) { //此处接受的router是vc的$store
return route.params
}
details.vue
<template>
<div>
<ul>
<li>ID: {{ id }}</li>
<li>Title: {{ title }}</li>
<li>CONTENT: {{ content }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
props:['id','title','content'], // 接受传递过来的而参数
mounted() {
console.log(this);
},
};
</script>
<style>
</style>
9.编程式路由导航
(1).编程式路由的前进和倒退
- this.$router.push(path); 相当于点击路由连接(
可以返回当前路由界面
)。 - this.%router.replace(path): 用新路由替换当前路由(
不可以返回当前路由界面
) - this.$router.back(); 请求(返回)上一个记录路由
- this.$router.go(-1):请求(返回上一个记录路由)
- this.$router.go(1):请求下一个路由
Message.vue
css属性的 replace也是不留痕迹的
<template>
<div>
<ul>
<li v-for="item in message" :key="item.id">
<!-- 路由切换时: 携带params参数 -->
<!-- <router-link :to="`/home/message/detail/${item.id}/${item.title}/${item.content}`">{{item.title}}</router-link
> -->
<!-- 路由切换时,携带query参数 -->
<!-- <router-link :to="`/home/message/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{item.title}}</router-link
> -->
<!-- 命名路由跳转、传参 -->
<router-link
:to="{
name: 'xiangqing',
params: { id: item.id, title: item.title, content: item.content }, // params和query的顺序不是固定的,假如为空,可以省略
query: {},
}"
>{{ item.title }}</router-link
>
<button @click="pushShow(item)">push</button>
<button @click="replaceShow(item)">replace</button>
</li>
</ul>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "message",
data() {
return {
message: [
{ id: "001", title: "消息1", content: "你好,文本1" },
{ id: "002", title: "消息2", content: "你好,文本2" },
{ id: "003", title: "消息3", content: "你好,文本3" },
],
};
},
methods: {
pushShow(item) {
this.$router.push({
name: "xiangqing",
params: { id: item.id, title: item.title, content: item.content }, // params和query的顺序不是固定的,假如为空,可以省略
query: {},
});
},
replaceShow(item) {
this.$router.replace({
name: "xiangqing",
params: { id: item.id, title: item.title, content: item.content }, // params和query的顺序不是固定的,假如为空,可以省略
query: {},
})
},
},
};
</script>
<style>
</style>