前言
在对于一些要时常大量抓取适当已经请求过来的数据的系统,在路由的转换中我们不想连着路由一起把数据倒来倒去,这个时候我们就需要一个可以存取大量数据的静态存储数据库,这个东西就是我们要讲到的-------状态机Vuex
官方说法:Vuex 是专门为 Vue.js 设计的状态管理库,它采用集中式存储管理应用的所有组件的状态。
原理
其实在原理上仍然是Vue的双向响应式原理,根据这个框架本身对数据进行劫持和订阅观察,但是他的存取则是新的规则,有新的限制
核心还是
Object.defineProperty(obj,obj.attr,descriptor)
参数:
obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
工具
工具 | 作用 |
---|---|
State | 用于数据的存储,是store中的唯一数据源 |
Getter | 类似于计算属性,就是对State中的数据进行二次的处理,比如筛选和对多个数据进行求值等 |
Mutation | 类似事件,是改变Store中数据的唯一途径,只能进行同步操作 |
Action | 类似Mutation,通过提交Mutation来改变数据,而不直接操作State,可以进行异步操作 |
Module | 当业务复杂的时候,可以把store分成多个模块进行管理,便于维护 |
为项目配置状态机
一般在项目中
基本上这个东西是这样的
import Vue from "vue";
import Vuex from "vuex"; //当然你要先npm下vuex啦 npm install vuex --save
Vue.use(Vuex); //配置进vue里
export default new Vuex.Store({ // 创建状态机实例
state: {
user: {
userName: "",
avtived: false
}
},
mutations: {
setUser(state, data) {
state.user.userName = data.userName;
state.user.avtived = data.avtived;
}
},
actions: {
setUser({ commit }, data) {
// 模拟异步处理
setTimeout(() => {
commit("setUser", data);
}, 3000);
}
},
getters: {
getUser(state) {
return state.user;
}
}
});
运用
State(其实你可以认为是Vue实例或者其中一个组件的data)
在组件中,通常我们可以用计算属性(computed)来获取state状态并进行处理
下面这个就可以遍历出一个产品清单
<template>
<div id="app">
<h2>product-one</h2>
<ul>
<li v-for="(item,index) in product" :key="index">
<div class="name" v-text="item.name"></div>
<div class="price" v-text="item.price"></div>
</li>
</ul>
</div>
</template>
<script>
export default {
components:{
},
data() {
return {
}
},
created(){
},
computed:{
product(){
return this.$store.state.product //获取状态机中状态
}
},
watch:{
},
methods: {
}
};
</script>
<style>
#app{
padding: 1rem;
}
ul{
list-style: none;
padding: 0;
}
</style>
Getter(可以认为是vue实例或其中一个组件中的computed)
Vuex 允许我们在 store 中定义“getter”。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
product:[
{name:'apple', price: '2'},
{name:'banana', price: '3'},
{name:'pear', price: '4'},
{name:'melon', price: '5'}
],
count:0,
str:'江西九江',
},
//Getter 接受 state 作为其第一个参数
getters:{
changeProduct: (state) => {
return state.product.map(val => {
return {
name: '**' + val.name + '--',
price: val.price*2
}
})
return state.product
}
},
mutations: {
},
actions: {
},
modules: {
}
})
Mutation(类似于methods但是只能同步操作不支持异步)
mutation 必须是同步函数,即是他不支持异步,无法发起请求
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
mutations: {
decrePrice(state){
state.product.forEach(val => {
val.price -= 1
})
}
},
mutations就类似事件,子组件中用this.$store.commit(‘事件名’)来获取
<template>
<div id="app">
<h2>product-two</h2>
<ul>
<li v-for="(item,index) in product" :key="index">
<div class="name">水果名:{{item.name}}</div>
<div class="price">价格:{{item.price}}</div>
</li>
</ul>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
components:{
},
data() {
return {
str:'中国'
}
},
created(){
this.decrePrice()
},
computed:{
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters({
product:'changeProduct'
})
},
watch:{
},
methods: {
decrePrice(){
return this.$store.commit('decrePrice')
}
}
};
</script>
Action
类似于 mutation,不同在于:
(1)Action 提交的是 mutation,而不是直接变更状态。
(2)Action 可以包含任意异步操作
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
分发dispatch action
子组件中,用this.$store.dispatch(‘action的名字’)来获取。
actions: {
decrePriceAction(context){
setTimeout(()=>{
context.commit('decrePrice')
}, 2000)
}
},
Module
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 的状态
严格模式
开启严格模式,仅需在创建 store 的时候传入 strict: true:
const store = new Vuex.Store({
// ...
strict: true
})
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
#开发环境与发布环境
不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。