vuex 状态管理
简介
vuex是专门用来管理vue.js应用程序中状态的一个插件。他的作用是将应用中的所有状态都放在一起,集中式来管理。需要声明的是,这里所说的状态指的是vue组件中data里面的属性。
vuex结构示意图
安装
- 官网直接下载引用
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="/path/to/vuex.js"></script>
- CDN引用
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script>
- npm 安装使用
npm install vuex --save
在模块化开发中,必须要使用Vue.use()来安装vuex
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
核心
vuex的核心是store对象,或者说vuex其实就是一个store对象,每个vue应用仅且仅有一个store对象
创建store
const store = new Vuex.Store({...});
store的对象参数包含5个对象
- state 存放状态 (state中的数据只能通过mutations进行修改)
- getters state的计算属性(相当于computed)
- mutations 改变状态的逻辑,操作状态,只能进行同步操作(相当于methods)
- actions 改变状态的逻辑,操作状态,提交给mutations,只能进行异步操作
- mudules 将store模块化
store对象的完整结构
const store = new Vuex.Store({ state: { // 存放状态 }, getters: { // state的计算属性 }, mutations: { // 更改state中状态的逻辑,同步操作 }, actions: { // 提交mutation,异步操作 }, // 如果将store分成一个个的模块的话,则需要用到modules。 //然后在每一个module中写state, getters, mutations, actions等。 modules: { a: moduleA, b: moduleB, // ... } });
store中获取状态
获取state中的状态
const app = new Vue({ el: '#app', // 把 store 对象注入到vue实例 store, components: { Counter }, template: ` <div> <counter></counter> </div> ` });
这样可以在子组件中使用this.$store.state.count访问到state里面的count这个状态
const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { // 获取store中的状态 return this.$store.state.count; } } }
getters
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数。此时可以用到getters,getters可以看作是store的计算属性,其参数为state。
const store = new Vuex.Store({ state: { todos: [ {id: 1, text: 'reading', done: true}, {id: 2, text: 'playBastketball', done: false} ] }, getters: {
//state是getters的默认参数 doneTodos(state){ return state.todos.filter(todo => todo.done); } } });
获取getters中派生的状态(不会同步到state)
store.getters.doneTodos // [{ id: 1, text: 'reading', done: true }] //在组件中,则要写在计算属性中, computed: { do() { return this.$store.getters.doneTodos; } }
mutations
mutations: {
//state是mutations的默认参数,n是可选参数(载荷) increment(state, n){ state.count += n; } } store.commit('increment', 10);
这样可以在子组件中使用this.$store.commit('increment',10)访问到mutations里面的函数
<script> export default { name:'DO', methods:{ add(){ this.$store.commit('increment',10) } } } </script>
还可以使用type属性来提交mutation
// mutations保持不变 mutations: { increment(state, payload){ state.count += payload.amount; //此时荷载为一个对象 } } store.commit({ type: 'increment', amount: 10 });
actions
context是actions中函数的默认参数
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state){ state.count++; } }, actions: { incre(context){
... //异步操作 context.commit('increment'); //发送异步结果给mutations中的increment } } });
这样可以在子组件中使用this.$store.dispatch('incre')访问到actions里面函数
<script> export default { name:'DO', methods:{ plus(){ this.$store.dispatch('incre') } } } </script> //调用 <div> <button @click="plus">+</button> </div?
mudules
每个module拥有自己的state, getters, mutation, action,mudules(一般不再细分其他分类),mudules中state,getters等的使用和store对象一样
1 const moduleA = { 2 state: {...}, 3 getters: {...}, 4 mutations: {....}, 5 actions: {...} 6 } 7 8 const moduleB = { 9 state: {...}, 10 getters: {...}, 11 mutations: {....}, 12 actions: {...} 13 } 14 15 const store = new Vuex.Store({ 16 modules: { 17 a: moduleA, 18 b: moduleB 19 } 20 }); 21 22 store.state.a // 获取moduleA的状态 23 store.state.b // 获取moduleB的状态