文章目录
搭建Vuex的运行环境
首先我们使用:
来安装Vuex
现在vue3成为了默认版本,所以我们使用如上的命令安装的是vuex的4版本
vue2中,要用vuex的3版本
vue3中,要用vuex的4版本
如果你使用的是vue2,那么你安装vuex的命令为:
npm i vuex@3
然后我们在main.js中引入,并使用use来使用这个插件:
import Vuex from 'vuex'
Vue.use(Vuex)
完成了上面的步骤之后,我们就可以在创建vm(或者组件实例对象vc)的时候传入一个store配置项,这个配置项在vm(或者组件实例对象vc)中体现为$store。
接下来最关键的一步:我们要创建这个store。我们单独把它写在一个js文件中。
这里的js文件我们一般有两种创建方法:
①src文件夹下创建一个vuex文件夹,把store.js文件放在里面:
②src文件夹下创建一个store文件夹,把index.js文件放在里面:
index.js:
//该文件用于创建Vuex中最为核心的store
//引入Vuex
import Vuex from 'vuex'
//准备actions——用于响应组件中的动作
const actions = {}
//准备mutations——用于操作数据(state)
const mutations = {}
//准备state——用于存储数据
const state = {}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
接下来我们把写好的store放在vm身上:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import Vuex from 'vuex'
import store from 'store/index'
Vue.use(Vuex)
new Vue({
render: h => h(App),
store
}).$mount('#app')
如果这样的话最后运行时会报错的:
也就是说Vue.use(Vuex)
要在import store from 'store/index'
这句话之前进行,那么我们这样修改:
注意:
在脚手架里面,它会先把所有的import语句按照顺序先执行完,再去执行其他语句!
所以你不能单纯的调换两个语句的位置去改变他们两句话的执行顺序。
正确的修改方式:
index.js:
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//准备actions——用于响应组件中的动作
const actions = {}
//准备mutations——用于操作数据(state)
const mutations = {}
//准备state——用于存储数据
const state = {}
Vue.use(Vuex)
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
main.js:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import store from 'store/index'
new Vue({
render: h => h(App),
store
}).$mount('#app')
接下来我们就可以在任意vm或组件实例上看到$store:
Vuex版求和案例
我们之前使用的是Vue版进行编写,接下来我们使用Vuex进行编写。
Count组件:
<template>
<div>
<h1>当前求和为:{{$store.state.sum}}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">当前求和为奇数再加</button>
<button @click="incrementWait">等一等再加</button>
</div>
</template>
<script>export default {
name:'MyCount',
data() {
return {
n:1, //用户选择的数字
}
},
methods: {
increment(){
this.$store.commit('JIA',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
},
incrementOdd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
},
},
mounted() {
console.log('Count',this)
},
}</script>
<style lang="css">button{
margin-left: 5px;
}</style>
index.js:
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
/* jia(context,value){
console.log('actions中的jia被调用了')
context.commit('JIA',value)
},
jian(context,value){
console.log('actions中的jian被调用了')
context.commit('JIAN',value)
}, */
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被调用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
}
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state,value){
console.log('mutations中的JIA被调用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
}
}
//准备state——用于存储数据
const state = {
sum:0 //当前的和
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
注意点:
- 在模板中呈现共享数据,要在$store中的state对象中去寻找
- actions中的方法有两个参数,其中context代表上下文,你也可以把它理解成一个mini版的store,借助这个上下文你可以更好的编写事务逻辑
我们可以把上下文打出来看看:
Tips:这里的dispatch()可以帮助我们完成繁冗的代码逻辑,如下图:
过程如下:
如果我们要处理的事务需要许多行代码,那么我们可以有规则、有目的的把他们的逻辑分开写在其他的子方法中
- mutations中的方法有两个参数,其中state就是你的状态(数据)
- mutations中的方法,名字一般全部大写,这样是为了与actions中的方法区分开来
- 我们一般在actions中写事务逻辑,mutations中不会涉及事务逻辑的处理
- 如果我们在actions中没有进行事务逻辑的处理直接调用的commit方法,那我们可以直接绕开actions(也就是不使用dispatch方法),而是直接在事件回调的时候直接调用commit
注意:
我们前面说过在上下文中可以拿到state,既然这样我们干嘛不直接在actions方法中就把数据修改了?
首先这样写代码是可以运行的,但是开发者工具会失效。这种写法是及其不推荐的!
Vuex开发者工具使用
因为Vuex的开发团队与Vue是同一个,他们的开发者工具在同一个地方,其中vuex位于第二栏:
Base State里面记录的是state里面的初始数据,就拿我们刚才的案例来说:
当我们按+之后,上面会显示你的mutations操作:
这也印证了如下所示的图:开发者工具是与mutations直接对话的。(你actions里面的操作被触发了,是不会被捕获的)
我们再多点几次+,我们可以选取任意一次查看,但是绿色框永远对应现在页面的状态:
接下来我们把鼠标悬浮在其中一个mutations方法上,会发现有几个按钮:
- 右边的按钮:点击后页面会回退到执行此mutations方法时的状态
- 中间的按钮:点击后删除此项mutations方法以及其依赖项
也就是说我如果点击第一个,那后面的几个都会消失:
因为后一次JIA方法需要上一次执行完JIA方法之后的结果
- 左边的按钮:点击之后它会把当前及其前面的mutations方法删除,把他们影响后的数据放在Base State中
举个例子:
本来Base State中的sum是0