【Vue】状态管理
页面应用需要Vuex管理全局/模块的状态,大型单页面组件如果靠事件(events)/属性(props)通讯传值会把各个组件耦合在一起。因
此需要Vuex统一管理,当然如是小型单页面应用,引用Vuex反而会增加复杂度。因此需要衡量引用Vuex增加的收益是否大于成本。
快速入门
1. 安装vuex库
cnpm install -S vuex
2. 创建Vuex.Store
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ //组件数据源,单一的state属性 state: { clickCount: 0 }, //相当于属性,封装获取state getters: { getClickCount: state => { return state.clickCount; } }, //封装引起状态变化的方法 mutations: { increment(state) { state.clickCount++; } }, //类似于 mutation,不同在于actions支持异步,不是直接变更状态,而是提交到mutation actions: { increment(context) { context.commit('increment') }, async incrementAsync({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { try { commit('increment'); resolve(new Date().getTime() + ' 成功执行'); } catch (e) { reject(e); } }, 1000) }); } } }); export default store;
3. Vue实例加入store
new Vue({ router: router, store: store, render: h => h(App), }).$mount('#app')
4. 组件获取store值
<script> import { mapGetters } from "vuex"; export default { computed: mapGetters({ count: ["getClickCount"] }), }; </script>
5. 组件触发更新
<script> export default { data() { return { times: 0 }; }, methods: { increment() { this.times++; //分发到action this.$store.dispatch("incrementAsync"); //提交到mutations this.$store.commit("increment"); }, }, }; </script>
解析
Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
State - 数据源
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。
Vue通过store选项,调用Vue.use(Vuex)注入到每一个子组件中(类似路由)
组件获取State
computed: { count () { return this.$store.state.count } }
或者使用辅助函数mapState
computed: mapState({ // 箭头函数可使代码更简练 count: state => state.count })
Getter - 数据封装读取(类似属性)
Getter 接受 state 作为其第一个参数
getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) }, getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } }
通过属性访问
store.getters.doneTodos
通过方法访问
store.getters.getTodoById(2)
Getters 也提供了一个辅助函数方便访问(mapGetters )
Mutation - 进行状态更改的地方
定义Mutation
mutations: { increment (state, n) { state.count += n } }
组件触发变更
store.commit('increment', 1)
Mutations也提供辅助函数(mapMutations)
import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')` // `mapMutations` 也支持载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')` }) } }
注意事项
- Mutation 必须是同步函数
- 最好提前在你的 store 中初始化好所有所需属性。
- 需要在对象上添加新属性时使用 Vue.set 或 替换旧对象
Action - 对Mutation封装
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
定义Action
actions: { increment ({ commit }) { commit('increment') } }
组件分发Action
store.dispatch('increment')
支持异步方式分发
actions: { async incrementAsync({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { try { commit('increment'); resolve(new Date().getTime() + ' 成功执行'); } catch (e) { reject(e); } }, 1000) }); } }
组件调用异步分发
this.$store.dispatch("incrementAsync").then( (data) => { console.log(data); }, (err) => { console.log(err); } );
参考文章
转发请标明出处:https://www.cnblogs.com/WilsonPan/p/12773090.html
赞 (0)