Vuex 状态管理
Vuex 配置选项
actions
用来定义事件处理方法,用于处理 state 数据。actions 类似于 mutations,不同之处在于 actions 是异步执行的,事件处理函数可以接收 {commit} 对象,完成 mutation 提交,从而方便 devtools 调试工具跟踪状态的 state 变化。
使用时,需要在 store 仓库中注册 actions 选项,在里面事件处理方法。事件处理方法接受 context 作为第 1 个参数,payload 作为第二个参数(根据需要进行选择)。
<body> <div id="app"> // 按钮绑定单击事件 <button @click="mut">查看 mutations 接收的参数</button> <button @click="act">查看 actions 接收的参数</button> </div> </body> <script> var store = new Vuex.Store({ state: { name: ‘Tom‘, age: 38, gander: ‘男‘ }, mutations: { test(state) { console.log(state) } }, actions: { test(context, param) { console.log(param) } } }) var vm = new Vue({ el: ‘#app‘, store, // mut 事件处理方法完成 mutation 提交 // act 事件处理方法完成 action 状态提交 methods: { mut() { this.$store.commit(‘test‘) }, act() { this.$store.dispatch({type: ‘test‘, name: ‘我是传递的参数‘}) } } }) </script>
计算机案例,实现在 actions 中通过 context 提交到 mutations
<body> <div id="app"> <button @click="calc">+</button> <p>{{ this.$store.state.count }}</p> </div> </body> <script> const store = new Vuex.Store({ state: { count: 0 }, // 修改 count 的值 mutations: { // mutations 中定义的 increment() 方法 increment(state) { state.count++ } }, // actions: { // add(context) { // context.commit(‘increment‘) // } // } actions: { // 使用 commit 推送一个名称为 incremenet 的 mutation add({commit}) { commit(‘increment‘) } } }) var vm = new Vue({ el: ‘#app‘, store, methods: { // 定义单击事件 calc() { // 通过 dispatch 来推送一个名称为 add 的 action // add 方法接收参数为 context 对象 this.$store.dispatch(‘add‘) } } }) </script>
mutations
该选项中处理方法接收 state 对象作为参数,即初始数据,使用时只需要在 state 实例配置对象中定义 state 即可。mutations 中的方法用来进行 state 数据造作,在组件中完成 mutations 提交就可以完成组件状态更新。
<body> <div id="app"> <!-- 按钮绑定单击事件--> <button @click="param">传递参数</button> <p>{{ this.$store.state.param }}</p> </div> </body> <script> var store = new Vuex.Store({ state: { param: ‘‘ }, mutations: { // 定义 mutations 的事件处理方法 receive,接收数据类型为 state、param receive(state, param) { // 将 param 的 name 的值 赋值给 state 的 param state.param = param.name } }, actions: { param(context) { // 传入对象形式的参数 context.commit({type: ‘receive‘, name: ‘我是传递的参数‘}) // 通过 context 对象提交名为 receive 的 mutation,并将 ‘我是传递参数’ 作为参数传递 // context.commit(‘receive‘, ‘我是传递的参数‘) } } }) var vm = new Vue({ el: ‘#app‘, store, methods: { // 注册事件处理方法 param ,并且通过单击事件绑定到页面中的 ”传递参数“ 按钮上,实现单击按钮,页面展示 param 的值 param() { this.$store.dispatch(‘param‘) } } }) </script>
mutations 是异步函数,组件状态发生变化时,触发 mutations 中的事件处理方法来更新页面状态的变化,这是一种同步。同步方法是同步执行的,主要可以记录当前状态的变化,同步到页面中。在 mutations 中如果有异步操作,devtools 很难追踪状态的改变。
<body> <div id="app"> <button @click="async">异步操作</button> <p>{{ this.$store.state.count }}</p> </div> </body> <script> var store = new Vuex.Store({ state: { count: 0 }, mutations: { receive(state) { setTimeout(function () { state.count++ }, 100) console.log(state.count) } } }) var vm = new Vue({ el: ‘#app‘, store, methods: { async() { this.$store.commit(‘receive‘) } } }) </script>
getters
store 实力允许在 store 中定义 getters 属性,类似于 Vue 实例的 computed。get 返回值会更具他的依赖进行处理然后缓存起来,且只有当他的依赖值发生改变时才会被重新计算。
<body> <div id="app"> <p>{{ this.$store.getters }}</p> </div> </body> <script> const store = new Vuex.Store({ state: { todos: [ {id: 1, text: ‘完成‘, done: true}, {id: 2, text: ‘未完成‘, done: false} ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } }) var vm = new Vue({ el: ‘#app‘, store }) </script>
getters 还可获取其定义方法中的数组、以及 length 值
<body> <div id="app"> <p>{{ this.$store.getters }}</p> <p>{{ this.$store.getters.doneTodosCount }}</p> </div> </body> <script> const store = new Vuex.Store({ state: { todos: [ {id: 1, text: ‘完成‘, done: true}, {id: 2, text: ‘未完成‘, done: false} ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) }, doneTodosCount: (state, getters) => { return getters.doneTodos.length } } }) var vm = new Vue({ el: ‘#app‘, store }) </script>
列表查询功能
<body> <div id="app"> <h2>列表查询</h2> <input type="text" v-model="id"> <button @click="search">搜索</button> <p>搜索结果: {{ this.$store.getters.search }}</p> <ul> <li v-for="item in this.$store.state.todos"> {{ item }}</li> </ul> </div> </body> <script> const store = new Vuex.Store({ state: { todos: [ {id: 1, text: ‘list1‘}, {id: 2, text: ‘list2‘} ], id: 0 }, mutations: { search(state, id) { state.id = id } }, getters: { search: state => { return state.todos.filter(todo => todo.id == state.id) } } }) var vm = new Vue({ el: ‘#app‘, store, methods: { search() { this.$store.commit(‘search‘, this.id) } } }) </script>
modules
在 store 中定义模块对象。实际开发中,页面组件存在多种状态,且通过单一状态树形式实现数据状态的可跟踪状态,Vue 为了解决当前这种复杂应用状态,提出了类似于模块化开发的方式对 store 对象仓库进行标准化管理