Table of contents
2. Auxiliary functions for component binding
1. Installation
npm install --save vuex
#OR
yarn add vuex
Note: The specified version can be added "@version number" after vuex; for example: yarn add [email protected]
Two, configuration
1. Create a js file (/src/store/index.js), the location is random,
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
// state 类似 data
state: {},
// getters 类似 computed
getters: {},
// mutations 类似methods
// 更改 store 中的状态的唯一方法(直接变更state中的数据)
// 写方法对数据做出更改(同步) 使用commit调用
mutations: {},
// 使用起来类似mutations方法,
// 不同点在于提交的是 mutation,而不是直接变更状态
// 异步操作,使用dispatch调用
actions: {},
// 模块
modules: {},
});
export default store;
2. Configure main.js
import Vue from "vue";
import App from "./App.vue";
// 1.引入上一步创建的js文件,路径按照自己创建的写
import store from "./store/index";
new Vue({
store, // 2.挂载
render: (h) => h(App),
}).$mount("#app");
Three, use
1. Basic use
/src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
// state 类似 data
state: {
product: "杯子",
price: 100,
discount: 0.6,
total: 0,
},
// getters 类似 computed
getters: {
// 折扣价
getDiscount(state) {
return state.price * state.discount;
},
},
// mutations 类似methods
// 写方法对数据做出更改(同步) 使用commit调用
mutations: {
// 计算总价
// 第 1 个参数:默认参数state,
// 第 2 个参数:store.commit 传入额外的参数,即 mutation 的 载荷(payload)
// 在大多数情况下,载荷应该是一个对象
// 使用常量替代 mutation 事件类型
GET_TOTAL(state, n) {
return (state.total = state.price * state.discount * n);
},
},
// 使用起来类似mutations方法,
// 不同点在于是异步操作,使用dispatch调用
actions: {},
// 模块
modules: {},
});
export default store;
use of the page
<template>
<div class="product">
<p>产品:{
{product}}</p>
<p>单价:{
{price}}</p>
<p>折扣:{
{discount}}</p>
<p>数量:<input type="text" v-model="number"></p>
<p>总价:{
{total}}</p>
<button @click="getTotal">计算总价</button>
</div>
</template>
<script>
export default {
name: "product",
// 组件
components: {},
data: function () {
return {
number: 0,
};
},
computed: {
product() {
return this.$store.state.product;
},
price() {
return this.$store.state.price;
},
discount(){
return this.$store.getters.getDiscount;
},
total() {
return this.$store.state.total;
},
},
methods: {
getTotal() {
this.$store.commit("GET_TOTAL", this.number);
},
},
// 页面初始化
created: function () {},
};
</script>
<style>
</style>
2. Auxiliary functions for component binding
mapStage
// 页面组件中
import { mapState } from "vuex";
export default {
computed: {
// 使用对象展开运算符将 state 混入 computed 对象中
...mapState([
// 映射 price 为 store.state.price
'price',
'total'
]),
}
}
If you want to rename the state property, use the object form
...mapState({
// 箭头函数可使代码更简练
goodsPrice: state => state.price,
// 传字符串参数 'total' 等同于 `state => state.total`
priceTotal: 'total'
}),
mapGetters
// 页面组件中
import { mapState, mapGetters } from "vuex";
export default {
computed: {
// 使用对象展开运算符将 state 混入 computed 对象中
...mapState([
// 映射 price 为 store.state.price
'price',
'total'
]),
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'getDiscount'
])
}
}
If you want to rename the state property, use the object form
...mapGetters({
discount: 'getDiscount'
}),
mapMutations
import { mapMutations } from 'vuex'
export default {
methods: {
// 使用对象展开运算符将 mutation 混入 methods 对象中
...mapMutations([
'GET_TOTAL',
]),
},
}
...mapMutations({
getTotal: 'GET_TOTAL',
}),
The parameters can be passed in directly when calling
<button @click="getTotal(number)">计算总价</button>
mapActions
The usage of mapActions is the same as that of mapMutations
3、Module
When the application becomes very complex, the store is divided into modules (module) . Each module has its own state, mutation, action, getter, and even nested submodules.
Directory Structure
Under the /src/store folder, it can be created according to the following project structure example
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
├── getters.js # 根级别的 getters
└── modules
├── A.js # A模块
└── B.js # B模块
// index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import getters from "./getters";
import mutations from "./mutations";
import actions from "./actions";
import user from "./modules/user";
const store = new Vuex.Store({
// state 类似 data
state: {},
// getters 类似 computed
getters,
mutations,
actions,
modules: {
user,
},
});
export default store;
// actions.js
const actions = {};
export default actions;
// mutations.js
const mutations = {
// 计算总价:第一个参数为默认参数state, 后面的参数为页面操作传过来的参数
getTotal(state, n) {
return (state.total = state.price * state.discount * n);
},
};
export default mutations;
// getters.js
const getters = {
// 折扣价
getDiscount(state) {
return state.price * state.discount;
},
};
export default getters;
// 模块基础代码
const module = {
state: {},
mutations: {},
actions: {},
getters: {},
};
export default module;
Namespaces
By default, the actions, mutations, and getters inside the module are registered globally , which can be added to namespaced: true
make it a module with a namespace.
const store = new Vuex.Store({
modules: {
A: {
namespaced: true,
// 模块内容(module assets)
state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
getters: {
aget () { ... } // -> getters['A/aget']
},
actions: {
aact () { ... } // -> dispatch('A/aact')
},
mutations: {
amutat () { ... } // -> commit('A/amutat')
},
// 嵌套模块
modules: {
// 继承父模块的命名空间
B: {
state: () => ({ ... }),
getters: {
bget () { ... } // -> getters['A/bget']
}
},
// 进一步嵌套命名空间
C: {
namespaced: true,
state: () => ({ ... }),
getters: {
cget () { ... } // -> getters['A/C/cget']
}
}
}
}
}
})