先给出官网地址
官方解释: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
vuex主要是是做数据交互,父子组件传值可以很容易办到,但是兄弟组件间传值(兄弟组件下又有父子组件),或者大型spa单页面框架项目,页面多并且一层嵌套一层的传值,异常麻烦,用vuex来维护共有的状态或数据会显得得心应手。
npm install --save vuex
【1】在src文件夹下新增一个store文件夹,里面添加一个index.js文件
【2】在main.js文件中引入store文件下的index.js
// main.js内部对vuex的配置
import store from '@/store/index.js'
new Vue({
el: '#app',
store, // 将store暴露出来
template: ' ',
components: { App }
});
【3】store文件下的index.js配置
import Vue from 'vue'; //首先引入vue
import Vuex from 'vuex'; //引入vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// state 类似 data
//这里面写入数据
},
getters:{
// getters 类似 computed
// 在这里面写个方法
},
mutations:{
// mutations 类似methods
// 写方法对数据做出更改(同步操作)
},
actions:{
// actions 类似methods
// 写方法对数据做出更改(异步操作)
}
})
在store中定义商品的原价,计算折扣价,根据用户输入的数量和商品原价计算出总价
【1】我们约定store中的数据是以下形式
import Vue from 'vue'; //首先引入vue
import Vuex from 'vuex'; //引入vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
price: 100, // 原价
total: '', // 总价
},
getters:{
// 折扣价
discount(state, getters) {
return state.price*0.8
}
},
mutations:{
// 计算总价:第一个参数为默认参数state, 后面的参数为页面操作传过来的参数
getTotal(state, n) {
return state.total = state.price * n;
}
},
actions:{
// 这里主要是操作异步操作的,使用起来几乎和mutations方法一模一样
// 除了一个是同步操作,一个是异步操作,一个使用commit调用,一个使用dispatch调用
// 这里就不多介绍了,有兴趣的可以自己去试一试,
// 比如你可以用setTimeout去尝试一下
}
})
【2】在页面中使用store中的数据
原价:{{price}}
8折:{{discount}}
数量:
总价:{{total}}
【3】页面效果
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
store.commit('increment', 10)
// ...
mutations: {
increment (state, n) {
state.count += n
}
}
在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读
store.commit('increment', {
amount: 10
})
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
提交 mutation 的另一种方式是直接使用包含 type 属性的对象
store.commit({
type: 'increment',
amount: 10
})
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
【1】mapState
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用mapState辅助函数帮助我们生成计算属性,有了对象展开运算符... 我们可以将mapState函数与页面局部的计算属性混合使用,修改上面的案例如下
import { mapState } from 'vuex'
export default {
computed: {
// 当前页面的计算属性
localCoputed() {
return 'test'
},
// 使用对象展开运算符将 state 混入 computed 对象中
...mapState([
'price',
'total'
]),
},
如果你想将一个 state属性另取一个名字,使用对象形式:
...mapState({
goodsPrice: 'price',
priceTotal: 'total'
}),
【2】mapGetters
mapGetters辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
import { mapState, mapGetters } from 'vuex'
export default {
computed: {
// 当前页面的计算属性
localCoputed() {
return 'test'
},
// 使用对象展开运算符将 state 混入computed 对象中
...mapState([
'price',
'total'
]),
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'discount'
]),
},
如果你想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
priceDiscount: 'discount'
}),
【3】mapMutations
mapMutations辅助函数将组件中的 methods 映射为store.commit调用, 修改上面案例
import { mapMutations } from 'vuex'
export default {
methods: {
// 使用对象展开运算符将 mutation 混入 methods 对象中
...mapMutations([
'getTotal',
]),
},
如果你想将一个 mutation 另取一个名字,使用对象形式:
...mapMutations({
allTotal: 'getTotal',
}),
那么,问题来了,之前我们也说过,mutations对象中的方法是可以传参的(payload),那么在mapMutations中如何传参呢?
其实很简单:像写一般的方法一样,直接在方法名后面的( )中将需要传递的参数写进去
...mapMutations([
'getTotal', // 将this.getTotal(quantity)映射为this.$store.commit('getTotal', quantity)
]),
【4】mapActions
使用 mapActions 辅助函数将组件的 methods 映射为store.dispatch调用
import { mapActions} from 'vuex'
export default {
methods: {
// 使用对象展开运算符将 action 混入 methods 对象中
...mapActions([
'increment', // 将this.increment()映射为this.$store.dispatch('increment')
]),
},
如果你想将一个 action 另取一个名字,使用对象形式:
...mapActions({
add: 'increment',
}),
在项目比较复杂的时候,数据全部写在一个state 方法全部集中一个mutations中,将会使我们的文件显得太过于臃肿,而且不易维护,那怎么办呢?还是那句话办法总比问题多,vuex为我们提供了module这样一个模块的概念。我们可以利用它来根据我们个个组件或者页面所需要的数据一一分割成不同的模块,看下面示例
const moduleA = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const moduleB = {
state: {},
mutations: {},
actions: {},
getters: {}
}
export default new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
// 在各自的模块内部使用
state.price // 这种使用方式和单个使用方式一样,直接使用就行
//在组件中使用
store.state.a.price // 先找到模块的名字,再去调用属性
store.state.b.price // 先找到模块的名字,再去调用属性