部分内容摘自Vuex的官方文档
👉Vuex👈
什么是Vuex
我们的组件与组件之间或者组件与实例之间都是需要一些数据的互相通信的,是可以通过props进行传递,但当组件嵌套的过于深层,或者我们应用的复杂度越来越高的时候,这种传统的数据传递方式就显得有些麻烦,所以我们可以使用Vuex进行数据的互通。
😊引用官网定义😊:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
核心概念
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
-
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
-
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
案例解析
看文本哪有看代码过瘾😀👇,我们通过一个简单的计数器例子来解释
这种方式虽然可以实现计数增加或者减少,但是我们追踪不到状态的变化,对于后期的维护和调试造成不小的麻烦,所以下面这种写法是错误的
代码👇,我们可以通过store.state
来获取状态对象
<div id="app">
<btn type="decrement"></btn>
<show-count></show-count>
<btn type="increment"></btn>
</div>
<script>
//定义全局组件实现显示计数器数字
Vue.component('show-count',{
template:`<span>{{$store.state.count}}</span>`
})
Vue.component('btn',{
props: ['type'],
template:`<button @click="handlerclick">{{btntext}}</button>`,
computed: {
btntext(){
return this.type==='decrement'?'-':'+'
}
},
methods: {
handlerclick(){
if(this.type==='increment'){
this.$store.state.count++
//可以通过this来获取模板文件的写法获取参数
}else{
store.state.count--
//也可以直接通过store.state来获取,同上面的写法并无差异
}
}
}
})
const store = new Vuex.Store({
state: {
count:0
},
})
var vm = new Vue({
store,
el:"#app",
data:{}
})
</script>
Matations
😀针对上面错误的方式,正确的方法是通过Matations来修改store中的state,即可追踪到状态的变化,当然这只是没有从后台获取数据的同步情况下,对应下下下面的图片中的红色线路😀
<div id="app">
<btn type="decrement"></btn>
<show-count></show-count>
<btn type="increment"></btn>
</div>
<script>
//显示数值,组件可通过$store.state.count,来获得store中的state的数据
Vue.component('show-count',{
template:`<span>{{$store.state.count}}</span>`
})
//按钮组件
Vue.component('btn',{
props: ['type'],//获取参数type
template:`<button @click="handlerclick">{{btntext}}</button>`,
computed: {//根据组件type来动态设置显示内容
btntext(){
return this.type==='decrement'?'-':'+'
}
},
methods: {//按钮组件的方法
handlerclick(){
if(this.type==='increment'){
store.commit('increment')//向commit传入mutation中的方法
}else{
this.$store.commit('decrement')
}
}
}
})
👆😀更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。可以向store.commit 传入mutation 来更改store中的state😀
😊需要在store中定义mutations,需要用它来修改state中的数据😀👇
//vuex插件
const store = new Vuex.Store({
state: {
count:0//计数存储在此
},
mutations: {
increment(state){
state.count++;//对state中的count做加法处理
},
decrement(state){
state.count--;//减法处理
}
},
})
var vm = new Vue({
store,//这里需要声明Vuex实例store
el:"#app",
data:{}
})
</script>
这样的话vue devtool就可以追踪到状态的变化了
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,再由mutation来修改store,而不是直接变更状态。
- Action 可以包含任意异步操作。
😀这就非常香了,这下可以通过Aciton来获取后台的数据再做处理,十分符合我们奇奇怪怪的业务逻辑,对应了下下下面的流程图的蓝色线路
👇看代🐎
<div id="app">
<btn type="decrement"></btn>
<show-count></show-count>
<btn type="increment"></btn>
</div>
<script>
Vue.component('show-count',{
template:`<span>{{$store.state.count}}</span>`
})
Vue.component('btn',{
props: ['type'],
template:`<button @click="handlerclick">{{btntext}}</button>`,
computed: {
btntext(){
return this.type==='decrement'?'-':'+'
}
},
methods: {
handlerclick(){
if(this.type==='increment'){
store.dispatch('add',{num:3})
//不同的是我们这里通过dispath来触发action,在将增加的数值以对象的形式传入
}else{
this.$store.commit('decrement')
}
}
}
})
const store = new Vuex.Store({
state: {
count:0
},
mutations: {
increment(state,value){
state.count+=value;
},
decrement(state){
state.count--;
}
},
actions: {
add(context,obj){
//context为add方法的参数,具体内容如下图,传入的数据要传入后面的参数,不可写在第一个
setTimeout(()=>{//这里通过定时器模拟后台获取数据的异步过程
context.commit('increment',obj.num)
//将对象中的num属性值拿出并传给matation的加法操作
},500)//停顿半秒
}
}
})
我们可以通过aciton中方法的参数,获得commit来搞一搞Matations
也可以将commit解构出来👇
actions: {
add({commit}){
setTimeout(()=>{
commit('increment',3)
},500)
}
}
👇vue实例定义,常规操作
var vm = new Vue({
store,
el:"#app",
data:{}
})
</script>
😀下面是Vuex的流程图😀