Vue总结(五)——Vuex入门
1、Vuex 概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
原理图
Vue components:组件
Actions(核心):动作
- 在Actions中发送ajax请求获取数据,再进行下一步;
- 如果知道要修改的数据,则不需要经过这一步,可以直接在页面上调用commit,和Mutation进行对话;
- 可以把一些业务逻辑写在这里,在数据进行修改前,进行一些判断等。
Backend API:后端接口
Mutations(核心)
- 用于加工或修改State(数据)的。
Devtools:
- Vue开发工具。
State(核心):
- 状态管理,对数据进行管理。
store:对Vuex的流程进行管理
- 对Actions(核心)、Mutations(核心)、State(核心)进行协调和管理。
- store.dispatch(‘动作类型’, ‘要修改的数据值’): 分发
- store.commit(‘动作类型’, ‘要修改的数据值’): 提交修改
流程分析
- 在组件页面中通过
store.dispatch('动作类型', '要修改的数据值')
调用Actions中和动作类型对应的函数,- 在Actions中通过Vuex上下文context,调用
context.commit('动作类型', '要修改的数据值')
,可以将数据提交给 mutations,动作类型和 mutations 中的函数名一致。
- Vuex上下文context,还可以拿到state中的变量值,如拿state中sum的值
context.state.sum
- mutations接收到数据之后,可以修改
state
中变量的值,如:state.sum += value
- 然后会使
state
中变量的值发生改变- 最后会将最新数据重新渲染到页面上。
2、何时使用?
多个组件需要共享数据时。
3、搭建vuex环境
注意:vue2中,要用vuex的3版本;vue3中,要用vuex的4版本。
步骤:
- 安装依赖
- 新建所需文件,并编写对应代码
- 注册配置对象
-
安装依赖
演示的使用的是Vue2版本的,所以Vuex要使用3版本的。
npm i vuex@3
-
创建文件:
src/store/index.js
index.js
//引入Vue核心库 import Vue from 'vue' //引入Vuex import Vuex from 'vuex' //应用Vuex插件 Vue.use(Vuex) //准备actions对象——响应组件中用户的动作 const actions = {} //准备mutations对象——修改state中的数据 const mutations = {} //准备state对象——保存具体的数据 const state = {} //创建并暴露store export default new Vuex.Store({ actions, mutations, state })
模块化引入:
- 会将
import
按照我们自己编写的顺序导入,不管import
之间有多少代码,都会将import
提前。 - 创建插件对象(如store)时,要先引入和应用对应的插件。
- 会将
-
在
main.js
中创建vm时传入store
配置项main.js
//引入Vue import Vue from 'vue' //引入App import App from './App.vue' //引入store import store from './store' //关闭Vue的生产提示 Vue.config.productionTip = false; //使用插件 Vue.use(vueResource); //创建vm new Vue({ el: '#app', render: h => h(App), store, })
4、基本使用
-
初始化数据、配置
actions
、配置mutations
,操作文件store.js
//引入Vue核心库 import Vue from 'vue' //引入Vuex import Vuex from 'vuex' //引用Vuex Vue.use(Vuex) //准备actions对象——响应组件中用户的动作,actions中的函数名一般小写 const actions = { //响应组件中加的动作 jia(context,value) { // console.log('actions中的jia被调用了',miniStore,value) context.commit('JIA',value) }, } //准备mutations对象——修改state中的数据,mutations中的函数名一般大写 const mutations = { //执行加 JIA(state,value) { // console.log('mutations中的JIA被调用了',state,value) state.sum += value } } //准备state对象——保存具体的数据,初始化数据 const state = { sum:0 } //创建并暴露store export default new Vuex.Store({ actions, mutations, state, })
-
组件中读取vuex中的数据:
$store.state.sum
-
组件中修改vuex中的数据:
$store.dispatch('action中的方法名',数据)
或$store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写
dispatch
,直接编写commit
5、案例
求和案例(Vuex实现):
- 点击“+”号,sum进行加1
- 点击“-”号,sum进行减1
- 点击“当前求和为奇数再加”,如果sum当前为奇数,sum就加1,否则保持不变
- 点击“等一等再加”,则等几秒钟sum才会加1
src/store/index.js
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex);
//准备actions——用于响应组件中的动作
const actions = {
//如果不用进行业务处理,可以直接绕过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,
})
src/main.js
注册store配置对象。
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入store
import store from './store'
//关闭Vue的生产提示
Vue.config.productionTip = false;
//创建vm
new Vue({
el: '#app',
render: h => h(App),
store
})
src/components/Count.vue
<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: 'Count',
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>
src/App.vue
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count'
export default {
name: 'App',
components: {Count},
}
</script>