1. Vuex 是用来做什么的 ?
官方解释: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
多个组件中共享状态
2. Vuex 安装
npm install vuex --save
创建文件: src/store/index.js, 文件内容如下:
import Vue from 'vue';
import Vuex from 'vuex';
// 1. 安装插件
Vue.use(Vuex)
// 2. 创建对象
const store = new Vuex.Store({
})
// 3. 导入 store 对象
export default store
再 main.js 中导入 store 对象
import store from './store'
new Vue({
el: '#app',
store,
render: h => h(App)
})
3. Vue.js devtools 浏览器插件
多个界面修改 vuex 状态时,这个工具会对状态进行跟踪,当出现问题时,可以更好的调试错误
4. getters 的使用详解
当某一个数据需要经过一系列的操作后再返回时,可以使用 getters 处理,其作用其实相当于组件的计算属性 computed
const store = new Vuex.Store({
state: {
counter: 6
},
getters: {
power(state) {
return state.counter * state.counter
}
}
})
然后在组件模板中可以直接调用 getters 中的 power
{{ $store.getters.power }}
getters 的其他用法参考下方代码示例:
{{ $store.getters.more20Stu }}
{{ $store.getters.more20StuCount }}
{{ $store.getters.moreAgeStu(20) }}
const store = new Vuex.Store({
state: {
students: [
{ id: 1, name: "wang", age: 18 },
{ id: 2, name: "liang", age: 21 },
{ id: 3, name: "zhang", age: 30 },
],
},
getters: {
more20Stu(state) {
// 获取年龄大于20的
return state.students.filter(s => s.age > 20)
},
more20StuCount(state, getters) {
// 获取年龄大于20的个数
return getters.more20Stu.length
},
moreAgeStu(state) {
// 如果要传参数,需要返回一个函数
return age => {
return state.students.filter(s => s.age > age)
}
}
}
})
5. mutations 的使用详解
store 状态更新的唯一方式: 提交 Mutation
Mutation 主要包括两部分: 事件类型 (type)、回调函数 (handler)
mutation 的定义方式:
increment 称为事件类型,回调函数的第一个参数就是 state
mutations 中的方法第二个参数被称为 mutations 的载荷 (payload)
mutations: {
increment(state) {
state.counter++
},
decrement(state, num) {
state.counter -= num
},
}
通过 mutation 更新 state 数据
this.$store.commit("increment");
this.$store.commit("decrement", num);// 传参
通过 commit 进行提交是一种普通的提交方式,vue 还提供了另外一种风格,它是一个包含 type 属性的对象
this.$store.commit({
type: "add",
num: 10,
age: 20,
});
此时要注意 mutation 中的方法的第二个参数的值,和普通提交方式可不一样
add(state, payload) {
console.log(payload) // {type: 'add', num: 10, age: 20}
}
6. actions 的使用详解
通常情况下, vuex 要求 mutations 中的方法必须是同步方法。主要的原因是当我们使用 devtools 时,devtools 可以帮助我们捕捉 mutation 的快照,但如果是异步操作,那么 devtools 将不能很好的追踪这个操作什么时候完成
基础使用
this.$store.dispatch("update");
const store = new Vuex.Store({
state: {
counter: 6,
},
mutations: {
change(state) {
state.counter += 10
}
},
actions: {
update(context) {
setTimeout(() => {
context.commit('change')
}, 1000)
}
}
})
当需要传递参数时,可使用 dispatch 的第二个参数
this.$store.dispatch("update", {
name: "liang",
age: 23,
});
actions: {
update(context, payload) {
console.log(payload) // {name: 'liang', age: 23}
setTimeout(() => {
context.commit('change')
}, 1000)
}
}
因为 actions 中是异步操作,所以当异步操作结束后应该通知外面我已操作完成
this.$store.dispatch("update", () => {
console.log("异步操作结束");
});
actions: {
update(context, payload) {
setTimeout(() => {
context.commit('change')
payload()
}, 1000)
}
}
当需要传入参数时,可以这样写
this.$store.dispatch("update", {
payload: {
name: "liang",
age: 23,
},
success: () => {
console.log("异步操作结束");
},
});
actions: {
update(context, params) {
console.log(params.payload)
setTimeout(() => {
context.commit('change')
params.success()
}, 1000)
}
},
更优雅的写法 Promise:
this.$store
.dispatch("update", {
name: "liang",
age: 23,
})
.then((result) => {
console.log("result: ", result);
});
actions: {
update(context, payload) {
return new Promise((resolve, reject) => {
console.log(payload)
setTimeout(() => {
context.commit('change')
resolve('异步操作结束')
}, 1000)
});
}
}
7. modules 的使用详解
vue 使用单一状态树,那么也就意味着很多状态都会交给 vuex 管理,当应用变得非常复杂时,store 对象就有可能变得相当臃肿,为了解决这个问题,vuex 允许我们将 store 分割成模块,每个模块拥有自己的 state、mutations、actions、getters 等
// state
{{ $store.state.a.name }}
// getters
{{ $store.getters.name }}
{{ $store.getters.fullname }}
// mutations
this.$store.commit("updateName");
// actions
this.$store.dispatch("save");
const store = new Vuex.Store({
state: {
counter: 6,
},
modules: {
a: {
state: {
name: 'liang'
},
mutations: {
updateName(state) {
state.name = 'zhang'
}
},
getters: {
name(state) {
return state.name + ' 666'
},
// 在模块的 getters 中有第三个参数
fullname(state, getters, rootState) {
return getters.name + ' ' + rootState.counter
}
},
actions: {
save(context) {
setTimeout(() => {
context.commit('updateName')
}, 1000);
}
}
}
}
})
当我们的 vuex 帮助我们管理过多内容时,好的项目结构可以让我们的代码更加清晰