Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
用于管理全局状态,保存的值可供所有组件使用,例如用户登录后的id和token之类
首先了解一下vuex的结构:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { // 存放数据 和data类似
},
getters: { // 相当于计算属性
},
mutations: { // 用来修改state和getters里面的数据(同步操作)
},
actions: { // vuex中用于发起异步操作
},
modules: {// 模块
}
})
State:存放数据
// vuex
state: { // 存放数据
name: 'admin',
id: '123'
}
// 组件中使用 两种方式
// 一直接调用
this.$store.state.name // admin
// 二 mapState 配合组件的computed 直接生成计算属性
computed: {
...mapState({
userName: state => state.name
})
}
// 可指定该值在组件中的名称,在mapState方法参数就是state所以不需要 this 和 $
// 可加上计算 (或者其他操作)
newId: state => 'new' + state.id
// 该方法返回的是对象 ...(拓展运算符)将mapState中的每一项都按照格式放在computed中
Getter:类似组件中的计算属性
state: {
num1: 1,
num2: 2
},
getters: {
sum: state => {
return state.num1 + state.num2 // 3
}
}
// 在方法中一个参数是 state
// 第二个参数是 其他的getter值
newSum: (state, getters) => {
return state.num1 + state.num2 + getters.sum // 6
}
// 使用也是两种
// 直接调用
this.$store.getters.sum
// mapGetters 和 mapState 类似
computed: {
...mapGetters([
'getSum': sum
])
}
Mutations: vuex修改值必须经过的一环
因为要实现响应式的数据必须遵守vuex的规矩使用mutation修改state的值并且为了让vuex更好的追踪到值 mutations 中的操作必须是同步的!
state: {
num: 1
},
mutations: {
numChange (state) {
state.num++
}
}
// 调用mutations 中的函数需要固定的格式
this.$store.commit('numChange') // 调用完方法state中的值+1 num:2
// mutations 中的函数 除了第一个参数是state,有第二个参数为可自定义的传参 payload
mutations: {
numChange (state,payload) {
state.num+=payload
}
}
// 调用
this.$store.commit('numChange',10) // 调用完方法state中的值+10 num:11
传多个参数时payload建议改成对象格式,在对象中存放参数
注:vue2的响应式并不是很完美所以官方提示我们修改值时需要遵守一些规则:
-
最好提前在你的 store 中初始化好所有所需属性。
-
当需要在对象上添加新属性时,你应该使用
Vue.set(obj, 'newProp', 123)
, -
以新对象替换老对象。利用拓展运算符给老对象赋值
Actions:
在actions中的操作可以是同步也可以是异步的(请求之类的异步),让vuex更加灵活
state: {
num: 0
},
mutations: {
numChange (state) {
state.num++
}
},
// 如上文所说想修改state中的值,需要调用mutations
actions: {
numChange (context) {
// 异步操作
setTimeout(() => {
context.commit('numChange')
}, 1000)
}
}
// 组件中调用和mutations类似 也有第二个可传参数
this.$store.dispatch('numChange', 10)
可能大家但看到过这种写法 numChange ( { commit } ) {}
没有使用context,是因为context是上下文环境并且本身就是一个对象,这里的写法其实就是 对象的解构赋值,让代码更加易懂
Modules:
通俗一点来说就是将每一个 store 单独定义,再汇总到一处,使代码更加有条理性
import user from './user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
settings
},
state
})
export default store
如上就是将user和settings两个模块合并汇总
// 这就是user模块的内容
const user = {
state: {
},
mutations: {
},
actions: {
}
}
export default user
最外层为根节点,user和settings为子模块,此时子模块中的actions 提供上下文环境第三项:context.rootState 为根节点状态 numChange ({ state, commit, rootState })
getters 提供第三个参数rootState为根节点 sum (state, getters, rootState)
命名空间等等知识点用的比较少,了解不深入给大家附上官方文档:vuex
个人理解有限,了解不够深入的,欢迎交流学习