
本文共 5926 字,大约阅读时间需要 19 分钟。
目录
什么是vueX?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
如何引用?
准备工作
js引入方式<script src="/path/to/vue.js"></script><script src="/path/to/vuex.js"></script>npm引入方式npm install vuex --save模块化的打包系统中import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)
1、创建index.js文件
import Vue from 'vue';import Vuex from 'vuex';Vue.use(Vuex);导入对应的组件状态管理文件import State from './state';统一在vuex的store对象中管理const store = new Vuex.Store(State);导出export default store;
2、创建state.js文件
export default { state: { test: 0, }, mutations:{ 'test': function(state, value) { state.test = value; } }, getters:{ 'test': function(state) { return state.test; } }};--提交值this.$store.commit('key',更新的内容);--获取值 用变量进行接受this.$store.getters.key
3、引入项目中
在vue入口中引入store文件import store from './store';根组件注入store 的机制new Vue({ el: '#app', store: store,});
state 单一状态树 当前状态
单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性 (opens new window)中返回某个状态:
// 创建一个 Counter 组件const Counter = { template: `<div>{ { count }}</div>`, computed: { count () { return store.state.count } }}在store.js中:state: { test: 0, },
每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
Vue.use(Vuex):通过调用此vuex 外,在根组件中引入store,可以注入到每一个子组件中。子组件就能实时得到相应的数据
mapState:组件需要获取多个状态,生成计算属性,函数返回的是一个对象。
computed:监控自己定义的百年来那个,改变量不在data中定义,直接在computed中定义,最好的场景就是页面动态显示的结果,可以放到此处进行计算监控和显示
computed: { localComputed () { /* ... */ }, // 使用对象展开运算符将此对象混入到外部对象中 ...mapState({ // ... })}
Getter 获取状态
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
getters: { test:function(state){ return state.test; } }this.$store.getters.test;
Mutation 提交状态
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
提交载荷(Payload)
可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
使用常量替代 Mutation 事件类型
使用文件单独放置常量,来进行系统引用
export const SOME_MUTATION = ‘SOME_MUTATION’
Mutation 必须是同步函数
mutations:{ 'test': function(state, value) { state.test = value; } } this.$store.commit('test',内容);
Action
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation
actions: { increment ({ commit }) { commit('test') }}
分发 Action
Action 通过 store.dispatch 方法触发
store.dispatch('increment')
Actions 支持同样的载荷方式和对象方式进行分发:
// 以载荷形式分发store.dispatch('test', { amount: 10})// 以对象形式分发store.dispatch({ type: 'test', amount: 10})
在组件中分发 Action
import { mapActions } from 'vuex'export default { // ... methods: { ...mapActions([ 'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')` // `mapActions` 也支持载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)` ]), ...mapActions({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')` }) }}
组合 Action
actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) }}
Module模块
为了解决store 对象变得相当臃肿问题,vuex允许我们将store分割成模块,每个模块都有自己的state、mutation、action、getter、子嵌套模块
const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... }}const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})store.state.a // -> moduleA 的状态store.state.b // -> moduleB 的状态
命名空间
加入namespaced: true 开启命名空间
const store = new Vuex.Store({ modules: { account: { namespaced: true, // 模块内容(module assets) state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响 getters: { isAdmin () { ... } // -> getters['account/isAdmin'] }, actions: { login () { ... } // -> dispatch('account/login') }, mutations: { login () { ... } // -> commit('account/login') }, // 嵌套模块 modules: { // 继承父模块的命名空间 myPage: { state: () => ({ ... }), getters: { profile () { ... } // -> getters['account/profile'] } }, // 进一步嵌套命名空间 posts: { namespaced: true, state: () => ({ ... }), getters: { popular () { ... } // -> getters['account/posts/popular'] } } } } }})
以下分为两种使用情况
在带命名空间的模块内访问全局内容(Global Assets)
此处不是太理解…后面视频学习
在带命名空间的模块注册全局 action
root: true, 开启当前模块action全局模式
{ actions: { someOtherAction ({ dispatch}) { dispatch('someAction') } }, modules: { foo: { namespaced: true, actions: { someAction: { root: true, handler (namespacedContext, payload) { ... } // -> 'someAction' } } } }}
调试日志加载、开启严格模式、
仅供开发环境使用
import createLogger from 'vuex/dist/logger'日志:plugins: [createLogger()]严格模式:strict: trueconst store = new Vuex.Store({ plugins: [createLogger()],State,strict: true});
测试mutation、测试 Action、测试 Getter
需要插件和专属配置支持、比较麻烦
热重载
需要支持 mutation 和模块,你需要使用 store.hotUpdate() 方法:
// store.jsimport Vue from 'vue'import Vuex from 'vuex'import mutations from './mutations'import moduleA from './modules/a'Vue.use(Vuex)const state = { ... }const store = new Vuex.Store({ state, mutations, modules: { a: moduleA }})if (module.hot) { // 使 action 和 mutation 成为可热重载模块 module.hot.accept(['./mutations', './modules/a'], () => { // 获取更新后的模块 // 因为 babel 6 的模块编译格式问题,这里需要加上 `.default` const newMutations = require('./mutations').default const newModuleA = require('./modules/a').default // 加载新模块 store.hotUpdate({ mutations: newMutations, modules: { a: newModuleA } }) })}
在此声明,以上内容部分列子来于官方文档
发表评论
最新留言
关于作者
