vuex
Posted ccyinghua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vuex相关的知识,希望对你有一定的参考价值。
vuex-集中式管理数据
vuex官网:https://vuex.vuejs.org/zh-cn/
一、安装
cnpm install vuex --save-dev
二、vuex数据流示意图
三、使用vuex
import Vuex from \'vuex\'; Vue.use(Vuex);
// 创建store实例 const store = new Vuex.Store({ // 存储state状态值 state: {
...
}, // 类似于事件集合,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,是同步函数 mutations: {
...
}, // 更改store状态的唯一方法是提交mutation,mutation已经对状态进行更改,actions就是用来提交mutation的,可以包含任意异步操作。 actions: {
...
}, // 被认为是store的计算属性,getters接受state作为第一个参数 getters: {
...
} }) /* eslint-disable no-new */ new Vue({ // 使用store,将store实例注入到根组件下的所有子组件中 // 子组件可以通过this.$store来访问store对象 store // store:store (key:value,key和value名字相同时,可省略value) })
四、核心概念
1、state
state负责存储所有的状态数据,可以直接用 this.$store.state 获取store的状态数据。
html: <div>count: {{ count }}</div> script: // 创建store实例 const store = new Vuex.Store({ state:{ count:0 } }) export default{ computed:{ count(){ return this.$store.state.count; } } };
结果--> count:0
也可以使用 mapState辅助函数 将state映射到计算属性中去。
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from \'vuex\' export default { // ... computed: mapState({ // 映射 this.count 为 store.state.count count: state => state.count }) }
2、getters
getters被认为是store的计算属性,接受state作为第一个参数,对state进行二次加工,通过 this.$store.getters 访问。
html: <div>用户名: {{ userName }}</div> script: // 创建store实例 const store = new Vuex.Store({ state:{ name:\'Jack\' }, getters:{ // 被认为是store的计算属性,对state数据进行二次处理,从而被其他地方进行调用 userName(state){ return state.name + \',Hello\'; } } }) export default{ computed:{ userName(){ return this.$store.getters.userName; } } };
结果---> 用户名: Jack,Hello
mapGetters 辅助函数 仅仅是将store中的getter映射到局部计算属性。
import { mapGetters } from \'vuex\' export default { // ... computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters([ // 映射 `this.doneTodosCount` 为 `store.getters.doneTodosCount` \'doneTodosCount\',// ... ]) } }
3、mutations
mutations类似于事件,更改store状态的事件函数,是改变状态的唯一方法,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。只能是同步的。
<div>数量: {{ count }}</div> export default{ computed:{ name(){ return this.$store.state.count; } } } const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 变更状态 state.count++ } } })
mutation更改了store 状态,并不代表更改成功,需要提交才能触发mutation的方法。
在组件中提交mutation,你可以在组件中使用 this.$store.commit(\'xxx\')
提交 mutation,或者使用 mapMutations
辅助函数将组件中的 methods 映射为 store.commit
调用。
<a href="javascript:;" @click="click">点击</a> export default { methods: { click() { this.$store.commit(\'increment\'); } } }
import { mapMutations } from \'vuex\' export default { // ... methods: mapMutations([ \'increment\', // 将 `this.increment()` 映射为 `this.$store.commit(\'increment\')` ]) } <button @click="increment">点击</button>
4、actions
actions类似于mutations,用于改变状态,不过不同的是通过提交mutations来触发mutations改变store状态,可以包含任意异步操作。
<div>数量: {{ count }}</div> <div>用户名: {{ name }}</div> const store = new Vuex.Store({ state:{ count:0, name:\'Jack\' }, mutations:{ // 改变状态的唯一方法,但也要提交才有用 increment(state){ state.count++; }, updateName(state,userName){ // 也可接受第二个参数 state.name = userName; } }, actions:{ // 提交mutations incrementAction(context){ // 提交increment,代替method的add点击事件中的this.$store.commit(\'increment\'); context.commit(\'increment\'); }, updateNameAction(context,userName){ // 提交updateName context.commit(\'updateName\',userName); } } }) export default{ computed:{ count(){ return this.$store.state.count; }, name(){ return this.$store.state.name; } } }
actions通过 this.$store.dispatch(\'increment\') 来触发,或者通过辅助函数 mapActions (与mapMutations类似) 将组件的 methods 映射为 store.dispatch
调用。
<a href="javascript:;" @click="add">点击</a> export default{ methods:{ add(){ // this.$store.commit(\'increment\'); // 提交increment事件类型来触发mutations,实现count++ // this.$store.commit(\'updateName\',\'Tom\'); // 用户名变成Tom // vuex中定义了actions提交mutations,这里就不需要提交mutations来触发事件了,只要触发actions就行 this.$store.dispatch(\'incrementAction\'); this.$store.dispatch(\'updateNameAction\',\'Tom\'); } } }
import {mapActions} from \'vuex\' export default { methods: mapActions([ \'increment\', // 将 `this.increment()` 映射为 `this.$store.dispatch(\'increment\')` ]) } <button @click="increment">点击</button>
五、demo实例
demo下载地址:https://github.com/ccyinghua/vuex-demo
1、简易vuex
main.js
import store from \'./store.js\' //挂到Vue实例身上 new Vue({ store, el: \'#app\', render: h => h(App) })
App.vue
import {mapGetters,mapActions} from \'vuex\' export default{ computed:mapGetters([ \'count\', \'getOdd\' ]), methods:mapActions([ \'increment\', \'decrement\', \'clickOdd\', \'clickAsync\' ]) }
//store.js
import Vue from \'vue\' import Vuex from \'vuex\' Vue.use(Vuex); var state = { count:10 } const mutations = { increment(state){ //事件;处理状态(数据)变化; state.count++; }, decrement(state){ state.count--; } } const actions = { increment: ({ // 提交mutations commit }) => { commit(\'increment\') }, decrement: ({ commit }) => { commit(\'decrement\') }, clickOdd: ({ commit, state }) => { if(state.count % 2 == 0){ commit(\'increment\') } }, clickAsync: ({ commit }) => { new Promise((resolve) => { setTimeout(function(){ commit(\'increment\'); resolve(); },1000) }) } } const getters = { count(state){ return state.count; }, getOdd(state){ return state.count % 2 == 0 ? \'偶数\' : \'奇数\'; } } //需要导出Store对象 export default new Vuex.Store({ state, mutations, actions, getters })
2、复杂vuex
main.js
import store from \'./store/\' //挂到Vue实例身上 new Vue({ store, el: \'#app\', render: h => h(App) })
App.vue
import {mapGetters,mapActions} from \'vuex\' export default{ computed:mapGetters([ \'count\', \'getOdd\' ]), methods:mapActions([ \'increment\', \'decrement\', \'clickOdd\', \'clickAsync\' ]) }
store文件夹--index.js
import Vue from \'vue\' import Vuex from \'vuex\' Vue.use(Vuex); import mutations from \'./mutations\' import actions from \'./actions\' //需要导出Store对象 export default new Vuex.Store({ modules:{ mutations }, actions })
store文件夹-types.js
// 使用常量替代 Mutation 事件类型,详见官网 export const INCREMENT = \'INCREMENT\'; export const DECREMENT = \'DECREMENT\';
store文件夹-getters.js
export default{ count: (state) => { return state.count; }, getOdd: (state) => { return state.count % 2 == 0 ? \'偶数\' : \'奇数\' } }
store文件夹-mutations.js
import { INCREMENT, DECREMENT } from \'./types\' import getters from \'./getters\' const state = { count:20 } const mutations = { [INCREMENT](state){ state.count++; }, [DECREMENT](state){ state.count--; } } export default{ state, mutations, getters }
store文件夹-actions.js
import * as types from \'./types\' export default{ increment: ({ commit }) => { commit(types.INCREMENT) }, decrement: ({ commit }) => { commit(types.DECREMENT) }, clickOdd: ({ commit, state }) => { if(state.mutations.count % 2 == 0){ commit(types.INCREMENT) } }, clickAsync: ({ commit }) => { new Promise((resolve) => { setTimeout(function(){ commit(types.INCREMENT); },1000) }) } }
以上是关于vuex的主要内容,如果未能解决你的问题,请参考以下文章