Vuex安装与初始化操作

安装vuex
npm install --save vuex
在main.js中引入vuex
import Vue from 'vue'
import store from './store' //引入Vuex的store
new Vue({
el: '#app',
store //注册上Vuex的store; 所有组件对象都多了一个属性 $store
})
然后新建store.js文件,模板如下
//vuex最和核心的管理对象store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//相当于data对象的状态对象
const state={}
//包含了n个直接更新状态的方法的对象
const mutations={}
//包含了n个间接更新状态的方法的对象,action的请求是提交给mutations的
const actions={ }
//包含多个getter计算属性对象
const getters={ }
//Store为大写
//小写的话报错 Uncaught TypeError: __WEBPACK_IMPORTED_MODULE_1_vuex__.a.store is not a constructor
export default new Vuex.Store({ state, mutations, actions, getters})
store对象属性

Vuex 三种使用方式
方式一:一个文件管理Vuex
需求一:点击’+'按钮,对数字加一

代码结构:

Counter.Vue
<template>
<div>
<p>click {{count}} times, count is {{evenOrOdd}}</p>
<button @click="increment">+</button>
</div>
</template>
- 首先需要将需要管理的状态 count 在store中进行管理,在
store.js中的state中添加count属性
store.js
//相当于data对象的状态对象
const state={
count:0 //指定初始化数据
}
- 接着,需要将
@click="increment"所需要的方法写出
<template>
<div>
<p>click {{count}} times, count is </p>
<button @click="increment">+</button>
</div>
</template>
<script>
export default {
methods: {
increment () {
this.$store.dispatch('increment') //调用action中的increment方法来进行数据操作
}
}
</script>
- 写出相对应的action与mutation
//包含了n个间接更新状态的方法的对象,action的请求是提交给mutations的
const actions={
increment({commit}){commit('INCREMENT') } //提交一个mutation请求
}
//包含了n个直接更新状态的方法的对象
const mutations={ INCREMENT(state){state.count++;}
}
Action 与 mutation的区别
- Action提交的是mutation,而不是直接变更状态
- Action 可以包含任意异步操作,比如axios 异步请求
actions: {
increment (context) {
context.commit('increment')
}
}
Action 函数接收一个与store实例具有相同方法和属性的context对象,因此可以调用 context.commit 提交一个 mutation, 或者通过 context.state 和 context.getters 来获取state 和getters。
但是在实际使用中,经常会用ES5参数解构来简化代码,于是就经常这样写
actions: {
increment ({ commit }) { // let {commit}= context相当于 let commit= context.commit
commit('increment')
}
}
需求二:点击’+'按钮,对数字加减之后,需要显示出这个数是偶数还是奇数

- 此要求,需要在count基础之上,对count进行属性计算操作,先通过Vuex获取所定义的计算属性
<p>click {{count}} times, count is {{evenOrOdd}}</p>
<script>
export default {
computed: {
evenOrOdd () {
return this.$store.getters.evenOrOdd
}
},
}
</script>
- 在store.js中的getters中填写相对应的计算属性
//包含多个getter计算属性对象
const getters={
evenOrOdd(state){//当读取属性值时自动调用并返回属性值
return state.count % 2 === 0 ? '偶数' : '奇数';
}
}
Getter 计算属性
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
通过Vuex辅助函数简化操作
<template>
<div>
<p>click {{count}} times, count is {{evenOrOdd}}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import {mapState, mapGetters, mapActions} from 'vuex'
export default {
/*computed: {
count () {return this.$store.state.count},
evenOrOdd () {return this.$store.getters.evenOrOdd}
},*/
computed: {
...mapState(['count']),
...mapGetters(['evenOrOdd'])
},
/*methods: {
increment () { this.$store.dispatch('increment')},
decrement () { this.$store.dispatch('decrement')}
}*/
methods: {
...mapActions(['increment', 'decrement'])
}
}
</script>
方式二:根据功能拆分使用
也就是说,将state、mutations、actions、getters都拆分出去
拆分后,代码结构如下

- 首先需要创建index.js文件,作为入口
//Vuex核心管理模块store对象
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state';
import mutations from './mutations';
import actions from './actions';
import getters from './getters';
Vue.use(Vuex);
export default new Vuex.Store({state,mutations,actions,getters})
- 其次,分别改造所需要的文件
state.js
//状态对象模块
export default {
count:0 //指定初始化数据
}
getters.js
//包含多个getter计算属性对象
export default {
evenOrOdd(state){//当读取属性值时自动调用并返回属性值
return state.count % 2 === 0 ? '偶数' : '奇数';
}
}
mutation-types.js 用来管理actions与mutation方法名称常量
//包含n个mutation名称常量
export const INCREMENT = 'increment' // 添加
export const DECREMENT = 'decrement' // 减少
actions.js
//包含了n个间接更新状态的方法的对象,action的请求是提交给mutations的
import {INCREMENT, DECREMENT} from './mutation-types'
export default {
increment({commit}) {commit(INCREMENT)}, //提交一个mutation请求
decrement({commit}) {commit(DECREMENT)},
}
mutations.js
//包含了n个直接更新状态的方法的对象
import {INCREMENT, DECREMENT} from './mutation-types'
export default {
[INCREMENT](state) {
state.count++;
},
[DECREMENT](state) {
state.count--;
}
}
方式三:按对象模块进行拆分

需求:需要操作两个对象,分别是 count,countTwo
当需要管理的对象多的时候,就可以将状态对象进行模块化拆分,结构如下

count与countTwo分别用number.js与number-two.js来进行管理
- 首先对stroe的
index.js文件进行修改,引入number与number_two模块
//Vuex核心管理模块store对象
import Vue from 'vue'
import Vuex from 'vuex'
import number from './modules/number';
import number_two from './modules/number-two';
Vue.use(Vuex);
export default new Vuex.Store({
modules: //引入number 与 number_two两个模块
number,
number_two
}
})
number.js与number-two.js两个模块都可看作单独的模块
number.js
import {INCREMENT, DECREMENT} from '../mutation-types'
const state = {count:0}//指定初始化数据
const mutations = {
[INCREMENT](state) { state.count++;},
[DECREMENT](state) {state.count--;}
}
const actions = {
increment({commit}) {commit(INCREMENT) },//提交一个mutation请求
decrement({commit}) {commit(DECREMENT)},
}
const getters = {
//当读取属性值时自动调用并返回属性值
evenOrOdd(state){return state.count % 2 === 0 ? '偶数' : '奇数'; }
}
export default { state, mutations,actions,getters}
number-two.js
import {INCREMENT_TWO, DECREMENT_TWO} from '../mutation-types'
const state = {count:0 }//指定初始化数据
const mutations = {
[INCREMENT_TWO](state) {state.count++;},
[DECREMENT_TWO](state) { state.count--;}
}
const actions = {
increment_two({commit}) { commit(INCREMENT_TWO)},//提交一个mutation请求
decrement_two({commit}) { commit(INCREMENT_TWO)},
}
const getters = {
evenOrOddTwo(state){return state.count % 2 === 0 ? '偶数' : '奇数';}
}
export default {state,mutations,actions,getters}
- 在调用属性时需要注意取值的方式
在没分模块之前想要取得state值与state计算属性,需要如下操作
computed: { count() { return this.$store.state.number.count; }, evenOrOdd() { return this.$store.getters.evenOrOdd }, },当分模块之后,取值方式就有变化了,需要添加上模块的路径
而取值计算属性与action等操作不变
computed: { countTwo() { return this.$store.state.number_two.count;//state后加上模块名 }, evenOrOddTwo() { return this.$store.getters.evenOrOddTwo } },