vuex 是一个vue配套的数据管理插件,大概意思是把公用的数据放到一个全局的变量(状态树)里面,每个文件引入都是同一个store,然后store里面包含同一份数据和修改数据的方法,这样就保证了同一个数据源。
使用vuex主要用两点。
一、创建store文件。
store文件主要包括:
- state - 存放初始数据,与vue组件里面的data基本上是一致的,只是从data提取出公共部分到state里面而已,state不需要写成函数,直接写对象就可以。
- getters - 这个与vue组件里面的computed 类似,如果需要对state数据进行筛选、修饰等操作可以用getters设置
- mutations - 改变state的方式,state的数据是不能直接修改的,需要调用mutations方法才能修改,除了直接调用mutations还可以通过 store.commit(mutaions的名字, ...)这样更新数据。
- actions - 异步修改state的方式,action会接收context,context里面包含state、commit等
- module - 如果需要分模块或者说是按命名空间来管理就需要用到这个功能
store/index.js文件的完整写法,大家可以按照需要拆分到单个文件:
// store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //通过模块【命名空间】的方式设置store modules: { testMoudle: { //这个参数不能丢,丢了之后就注意模块不成功 namespaced: true, state: { moudleName: 'moudleName', }, getters: { getDecMoudleName(state) { return `${state.moudleName} from getters` }, }, mutations: { setMoudleName(state, name) { state.moudleName = name }, resetMoudleName(state) { state.moudleName = 'moduleName' }, }, }, }, //在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到 //在生产环境需要关闭,考虑到性能原因 strict: process.env.NODE_ENV !== 'production', state: { todos: [ { id: 1, text: '中华人民共和国...', done: true }, { id: 2, text: '中华人民共和国...', done: false }, ], count: 1, }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) }, }, mutations: { increment(state) { state.count++ }, decrement(state) { state.count-- }, setCount(state, value) { state.count = value }, }, actions: { incrementAction(context) { setTimeout(() => { context.commit('setCount', 10) }, 4000) }, }, })
入口文件引入main.js :
import Vue from 'vue' import App from './App.vue' import store from './store/index.js' Vue.config.productionTip = false new Vue({ render: h => h(App), store, }).$mount('#app')
在组件中调用
//Parent.vue <template> <div class="box"> <h3>普通状态使用</h3> <div>count: {{count}}</div> <div>countAlias: {{countAlias}}</div> <div> <button @click="increment">+ 增加</button> <button @click="decrement">- 减少</button> <button @click="reset(110)">重置</button> <button @click="incrementAction">异步重置</button> </div> <h4>正常list:</h4> <ul> <li v-for="item in list" :key="item.id">{{item.id}}: {{item.text}}</li> </ul> <h4>操作过的list:</h4> <ul> <li v-for="item in doneTodos" :key="item.id">{{item.id}}: {{item.text}}</li> </ul> <h3>模块状态使用</h3> <div>moudleName: {{moudleName}}</div> <div> <button @click="setMoudleName('hello modulename')">setMoudleName</button> <button @click="resetMoudleName">resetMoudleName</button> </div> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions, createNamespacedHelpers, } from 'vuex' const { mapState: mapMoudleState, mapMutations: mapMoudelMutations, } = createNamespacedHelpers('testMoudle') export default { name: 'Parent', computed: { ...mapState({ // 箭头函数可使代码更简练 count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count` countAlias: 'count', list(state) { return state.todos }, }), ...mapGetters(['doneTodos']), ...mapMoudleState(['moudleName']), }, methods: { ...mapMoudelMutations(['setMoudleName', 'resetMoudleName']), ...mapMutations([ 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')` // `mapMutations` 也支持载荷: 'decrement', // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ reset: 'setCount', // 将 `this.add()` 映射为 `this.$store.commit('increment')` }), ...mapActions(['incrementAction']), }, created() { setTimeout(() => { this.info = { userInfo: { name: 'hello world', }, address: 'xxx, xxx, xxx', } }, 1000) }, } </script>