Vuex:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
一.vuex基本使用
- 下载
- 引入
- 注册
- 实例化vuex 初始化vuex对象
- 挂载
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 7
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
二.state
1.概览:
大白话:声明在state上的变量,就相当于全局变量,可以在任意vue文件中访问到
官方术语:state是放置所有公共状态的属性,如果你有一个公共状态数据 , 你只需要定义在 state对象中
作用:共享状态数据
2.原始形式- 插值表达式:
- 组件中可以使用 this.$store 获取到vuex中的store对象实例,可通过state属性属性获取count
<template>
<div>
<h1>count:{{ $store.state.count }}</h1> //7
</div>
</template>
3.计算属性 - 将state属性定义在计算属性中
<template>
<div>
<router-view></router-view>
<h2>{{ count }}</h2>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
//state变量的优化使用
computed: {
//把state中的数据,定义到组件内的计算属性
count() {
return this.$store.state.count;
},
},
};
</script>
4.辅助函数 - mapState
- 第一步:导入mapState
- 第二步:采用数组形式引入state属性
- 第三步:利用延展运算符将导出的状态映射给计算属性
<template>
<div>
<h2>{{ count }}</h2>
</div>
</template>
<script>
//导入mapState
import { mapState } from "vuex";
export default {
//state变量的优化使用
computed: {
//利用延展运算符将导出的状态映射给计算属性
//采用数组形式引入state属性
...mapState(["count"]),
},
};
</script>
5.使用场景
当一个变量需要在多个vue文件中使用的时候,此刻这个变量可以声明在state中成为一个全局变量
三.mutations
1.概念:
大白话:mutations是专门用来修改state中的变量的对象(属性)
官方术语:state数据的修改只能通过mutations,并且必须是同步更新(也就是里面不能有异步代码),目的是形成数据快照
2.原始形式- $store
新建组件,内容为一个button按钮,点击按钮调用mutations
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 7
},
mutations: {
//state:这是个内置参数
//指得是mutations同级的state属性
//five:调用函数时传入的参数
addcount(state, five) {
state.count += five
}
}
})
<template>
<div>
<h2>{{ count }}</h2>
<!-- 调用mutations中的函数,必须通过commit方法进行调用
语法:$store.commit("需要调用的函数",传给调用函数的值)-->
<button @click="$store.commit('addcount', 5)">加五</button>
</div>
</template>
3.事件处理函数-this.$store
<template>
<div>
<h2>{{ count }}</h2>
<button @click="changecount(10)">加十</button>
</div>
</template>
<script>
export default {
methods: {
//定义事件处理函数来修改state的值
changecount(numb) {
this.$store.commit("addcount", numb);
},
},
};
</script>
4.辅助函数 - mapMutations
- 第一步:导入mapMutations
- 第二步:采用数组形式引入mutations
- 第三步:利用延展运算符将导出的状态映射给methods
<template>
<div>
<router-view></router-view>
<h1>count:{{ $store.state.count }}</h1>
<button @click="addcount(50)">加五十</button>
</template>
<script>
//1.引入辅助函数 mapMutations
import { mapState, mapMutations } from "vuex";
export default {
methods: {
//2.通过辅助函数引入addcount函数,并把addcount解构到methods中
...mapMutations(["addcount"]),
}
}
</script>
5.使用场景
当我们需要修改state中变量的值的时候,此刻需要用到mutations
注意:mutations只能同步修改
四.actions
1.概念:
大白话:action就是可以通过异步操作,通过调用mutations中的函数,从而修改state中的值
官方术语:state是存放数据的,mutations是同步更新数据的,actions则辅助进行异步操作的
2.原始形式- $store
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 7
},
mutations: {
//state:这是个内置参数
//指得是mutations同级的state属性
//five:调用函数时传入的参数
addcount(state, five) {
state.count += five
}
},
actions: {
Asynccount(store, numb) {
//store:内置的参数,指的是Vue.Store的实例
setTimeout(() => {
//因为store已经通过参数可以获取到了
//因此这里可以直接通过store调用commit方法
store.commit("addcount", numb)
}, 1000);
}
}
})
<template>
<h2>{{ count }}</h2>
<!-- 调用actions中的函数,必须通过dispatch方法调用
语法:$store.dispatch("调用函数名",传递给函数的值) -->
<button @click="$store.dispatch('Asynccount', 1000)">加一千</button>
</template>
3.事件处理函数-this.$store
<template>
<h2>{{ count }}</h2>
<button @click="change(6)">加六</button>
</template>
<script>
export default {
methods: {
change(numb) {
this.$store.dispatch("Asynccount", numb);
},
}
</script>
4.辅助函数 - mapActions
- 第一步:导入mapActions
- 第二步:采用数组形式引入actions
- 第三步:利用延展运算符将导出的状态映射给methods
<template>
<div>
<h1>count:{{ $store.state.count }}</h1>
<button @click="Asynccount(20)">加二十</button>
</template>
<script>
//1.引入辅助函数 mapMutations
import { mapState, mapMutations ,mapActions }from "vuex"
export default {
methods: {
//2.通过辅助函数引入mapActions并把Asyncconunt解构到methods中
...mapActions(["Asynccount"]),
}
}
</script>
5.使用场景
当我们需要修改state中变量的值的时候,此刻需要用到actions
注意:actions异步修改的时候才需要用到
五.gerters
1.概念:
大白话:除了state可以声明全局变量外,还可以利用gerters声明全局变量,只不过getters声明的变量从state派生出来的,getters就相当于vue中的computed计算属性
官方术语:除了state之外,有时候我们还需要从state中派生出一些状态,这些状态依赖state,此时会用到getters
2.原始形式- $store
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
//需求:页面中需要用到state中和list数组中大于5的数据
getters: {
//声明变量,值是个函数,这个函数必须有返回值
getlist: (state) => {
//state:内置参数,指的是和getters同级的state属性
return state.list.filter(item => item > 5)
}
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
<template>
//使用getters数据
<p>{{ $store.getters.getlist }}</p>
</template>
3.优化 - 计算属性
<template>
<div>
<h1>{{ changelist }}</h1>
</div>
</template>
<script>
export default {
//通过计算属性来显示getters里面的数据
computed: {
changelist() {
return this.$store.getters.changelist;
},
},
};
</script>
4.辅助函数 - mapGetters
<template>
<div>
<h1>{{ changelist }}</h1>
</div>
</template>
<script>
//1.引入辅助函数
import { mapGetters } from "vuex";
export default {
//通过计算属性来显示getters里面的数据
computed: {
// 2.解构
...mapGetters(["changelist"]),
},
};
</script>
5.使用场景
简化state值的获取
六.module
1.概念:
大白话:分模块管理我们的全局变量,这样有利于项目的后期维护
官方术语:由于单一状态树,应用的所有状态集中在一个比较大的state对象中,当应用变的复杂的时候,代码就变得相当臃肿了,vuex会变得越来越难维护,因此就有了vuex的模块化
2.模块化的简单应用:
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0,
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
mutations: {
addcount(state, num) {
state.count += num
}
},
actions: {
Aoscount(store, num) {
setTimeout(() => {
store.state.count += num
}, 1000);
}
},
getters: {
changelist(state) {
return state.list.filter(item => item > 5)
}
},
// 定义两个模块 user 和 setting,moudules同样拥有store的属性
modules:{
user:{
state:{
token:"123"
},
mutations:{},
actions:{},
getters:{},
modules:{}
},
setting:{
state:{
name:"张三"
}
}
}
})
<template>
<div>
<h2>{{ $store.state.user.token }}</h2>
<h2>{{ $store.state.setting.name }}</h2>
</div>
</template>
3.优化使用
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0,
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
mutations: {
addcount(state, num) {
state.count += num
}
},
actions: {
Aoscount(store, num) {
setTimeout(() => {
store.state.count += num
}, 1000);
}
},
getters: {
changelist(state) {
return state.list.filter(item => item > 5)
},
//把模块中的变量通过getters简化使用
token: state => state.user.token,
name: state => state.setting.name
},
// 定义两个模块 user 和 setting,moudules同样拥有store的属性
modules: {
user: {
state: {
token: "123"
},
mutations: {},
actions: {},
getters: {},
modules: {}
},
setting: {
state: {
name: "张三"
}
}
}
})
<template>
<div>
<h3>{{ token }}</h3>
<h3>{{ name }}</h3>
</div>
</template>
<script>
//1.引入辅助函数
import { mapGetters } from "vuex";
export default {
//通过计算属性来显示getters里面的数据
computed: {
// 2.通过辅助函数在计算属性中解构使用
...mapGetters(["changelist"]),
...mapGetters(["token", "name"]),
},
};
</script>
4.模块化中的命名空间
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应
// 定义两个模块 user 和 setting,moudules同样拥有store的属性
modules: {
user: {
state: {
token: "123"
},
mutations: {
changetoken(state) {
state.token = 666
}
},
actions: {
axtoken(store){
setTimeout(() => {
store.commit("changetoken")
}, 1000);
}
},
getters: {},
modules: {}
},
setting: {
state: {
name: "张三"
}
}
}
<template>
<div>
<h3>{{ token }}</h3>
<button @click="$store.commit('changetoken')">修改</button>
<button @click="$store.dispatch('axtoken')">异步修改</button>
</div>
</template>
如果我们想保证内部模块的高封闭性,我们可以采用namespaced来进行设置
// 定义两个模块 user 和 setting,moudules同样拥有store的属性
modules: {
user: {
namespaced: true,//true表示给user模块加了一道锁,此时模块不再是全局,而是局部,只属于user
state: {
token: "123"
},
mutations: {
changetoken(state) {
state.token = 666
}
},
actions: {
axtoken(store) {
setTimeout(() => {
store.commit("changetoken")
}, 1000);
}
},
getters: {},
modules: {}
},
setting: {
state: {
name: "张三"
}
}
}
<template>
<div>
<h3>{{ token }}</h3>
//具有独立命名空间的user模块,访问里面的函数时,要加上模块名
//语法:$store.commit('模块名/函数名')
//语法:$store.dispatch('模块名/函数名')
<button @click="$store.commit('user/changetoken')">修改</button>
<button @click="$store.dispatch('user/axtoken')">异步修改</button>
</div>
</template>
5.利用辅助函数调用
<template>
<div>
<h3>{{ token }}</h3>
<button @click="changetoken">辅助函数修改</button>
<button @click="axtoken">辅助函数异步修改</button>
</div>
</template>
<script>
//1.引入辅助函数
import { mapMutations, mapActions } from "vuex";
export default {
//通过辅助函数把user模块中的函数解构到methods中,然后可以直接使用
methods: {
//调用具有独立空间的模块中的函数,通过以下语法获取
//语法:mapMutations(‘模块名’,['函数名'])
...mapMutations("user", ["changetoken"]),
...mapActions("user", ["axtoken"]),
},
};
</script>