vuex入门及使用
一、什么是vuex
专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间的通信的方式,且适用于任意组件间的通信。
Github 地址: https://github.com/vuejs/vuex
二、vuex的工作原理图
理解原理图:
Vue Components 组件:客人
Vuex:餐厅
Actions:服务员
Mutation:后厨
State:菜品
1、客人来到餐厅
跟服务员说(发起dispatch请求)想吃蛋炒饭,服务员确认有没有蛋炒饭(验证),有的话,转告给(发起commit请求)后厨,后厨开始做菜(执行客人的命令),做好的菜(State)上传给客人。
2、如果客人和后厨认识,即可略过服务员,直接跟后厨说(发起dispatch请求)吃蛋炒饭,后厨直接做菜上传。
三、什么时候使用vuex
多个组件依赖于同一状态
来自不同组件的行为需要变更同一状态
四、vuex的核心概念
1、state
- vue管理的状态对象
- 是唯一的
2、actions
- 值为一个对象,包含多个响应用户动作的回调函数
- 通过 commit( )来触发 mutation 中函数的调用, 间接更新
- 触发actions 中的回调–在组件中使用: $store.dispatch(‘对应的 action 回调名’) 触发
- 可以包含异步代码(定时器, ajax 等等
3、mutations
- 值是一个对象,包含多个直接更新 state 的方法
- 在 action 中使用:commit('对应的 mutations 方法
- 不能写异步代码、只能单纯的操作 state
4、getters - 值为一个对象,包含多个用于返回数据的函数
- 使用: $store.getters.xxx
5、modules - 包含多个 module
- 一个 module 是一个 store 的配置对象
- 与一个组件(包含有共享数据)对应
五、案例 --模块化
1、创建一个vue项目,在idea中打开并在main.js中导入需要的文件
2、第一个组件 求和案例
<template>
<!-- src_求和案例 -->
<div>
<h1>当前求和为:{{sum}}</h1>
<h3>当前求和放大十倍为:{{bigSum}}</h3>
<h3>我在{{school}}学习{{subject}}</h3>
<h3 style="color: red">Person组件的总人数是:{{personList.length}}</h3>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="JIA(n)">+</button>
<button @click="JIAN(n)">-</button>
<button @click="jiaOdd(n)">当前求和为奇数再加</button>
<button @click="jiaWait(n)">等一等再加</button>
</div>
</template>
<script>
/*求和案例 mapState和mapGetters,mapMutations,mapActions的用法*/
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
name: "Count",
data(){
return{
n:1, //用户选择的数字
}
},
computed:{
//靠自己去写计算属性
//借助mapState生成计算属性 从state中读取数据(对象写法)
// ...mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
//借助mapState生成计算属性 从state中读取数据(数组写法) 名字必须一致
// ...mapState(['sum','school','subject','personList']),
//这样可以读取vuex两个模块的数据 但上面调用的话要countAbout. personAbout. 点出来
//...mapState(['countAbout','personAbout']),
...mapState('countAbout',['sum','school','subject']),
...mapState('personAbout',['personList']),
//借助mapGetters生成计算属性 (对象写法)
// ...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性 (数组写法)
...mapGetters('countAbout',['bigSum'])
},
methods:{
//靠自己去写方法
/*increment(){
this.$store.commit('JIA',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
},*/
//借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(对象写法)
// ...mapMutations({increment: 'JIA',decrement: 'JIAN'}),
// 借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(数组写法)
...mapMutations('countAbout',['JIA','JIAN']),
/*incrementOdd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
}*/
//借助mapActions生成对应方法 方法中调用dispatch去联系actions (对象方法)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
//借助mapActions生成对应方法 方法中调用dispatch去联系actions (数组方法)
...mapActions('countAbout',['jiaOdd','jiaWait'])
},
//借助mapstate生成计算属性 从state中读取数据 (对象写法)
mounted() {
// const x=mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
//console.log(x)
}
}
</script>
<style lang="css">
button{
margin-left: 5px;
}
</style>
3、第二个组件 人员案例 没有使用mapState和mapGetters,mapMutations,mapActions的用法
<template>
<div>
<h1>人员列表</h1>
<h3 style="color: red">Count组件求和为:{{sum}}</h3>
<h3>列表中第一个人的名字是:{{firstPersonName}}</h3>
<input type="text" placeholder="请输入名字" v-model="name">
<button @click="add">添加</button>
<button @click="addWang">添加一个姓王的人</button>
<ul>
<li v-for="p in personList" :key="p.id">{{p.name}}</li>
</ul>
</div>
</template>
<script>
// import {mapState} from 'vuex'
export default {
name: "Person",
data(){
return{
name:''
}
},
computed:{
// ...mapState(['personList']),
personList(){
return this.$store.state.personAbout.personList
},
sum(){
return this.$store.state.countAbout.sum
},
firstPersonName(){
return this.$store.getters['personAbout/firstPersonName']
}
},
methods:{
add(){
const person ={id:Math.ceil(Math.random()*10000),name:this.name}
this.$store.commit('personAbout/ADD_PERSON',person)
this.name = ''
},
addWang(){
const person ={id:Math.ceil(Math.random()*10000),name:this.name}
this.$store.dispatch('personAbout/addPersonWang',person)
this.name = ''
}
}
}
</script>
<style scoped>
</style>
所以在访问store中的数据时 使用/
this.$store.commit('personAbout/ADD_PERSON',person)
this.$store.dispatch('personAbout/addPersonWang',person)
mapState和mapGetters,mapMutations,mapActions的用法
1、生成计算属性
借助mapState生成计算属性 从state中读取数据(对象写法)
...mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
借助mapState生成计算属性 从state中读取数据(数组写法) 名字必须一致
...mapState(['sum','school','subject','personList']),
这个方式可以 读取vuex两个模块的数据 但上面调用的话要countAbout. personAbout. 点出来 记住一定要将store中index.js中的命名空间开启!
...mapState(['countAbout','personAbout']),
2、生成对应的方法
借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(对象写法)
...mapMutations({increment: 'JIA',decrement: 'JIAN'}),
借助mapMutations生成对应的方法 方法中会调用commit去联系mutations(数组写法)
...mapMutations('countAbout',['JIA','JIAN']),
借助mapActions生成对应方法 方法中调用dispatch去联系actions (对象方法)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
借助mapActions生成对应方法 方法中调用dispatch去联系actions (数组方法)
...mapActions('countAbout',['jiaOdd','jiaWait'])
借助mapstate生成计算属性 从state中读取数据 (对象写法)
mounted() {
const x=mapState({'he':'sum','xuexiao':'school','xueke':'subject'})
//console.log(x)
}
4、store中的index.js
//该文件用于创建vuex中最核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//求和功能的相关配置
const countOptions={
//开启命名空间
namespaced:true,
actions:{
jiaOdd(context,value) {
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value) {
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
},
mutations:{
JIA(state,value){
console.log('mutation中的JIA')
state.sum += value
},
JIAN(state,value){
state.sum -= value
},
},
state:{
sum:0, //当前的和
school: '尚硅谷',
subject:'前端',
},
getters:{
bigSum(state){
return state.sum*10
}
},
}
//人员功能的相关配置
const personOptions={
namespaced:true,
actions:{
addPersonWang(context,value){
if(value.name.indexOf('王')===0){
context.commit('ADD_PERSON',value)
}else{
alert("添加的人必须姓王")
}
}
},
mutations:{
ADD_PERSON(state,value){
console.log("add person 被调用了")
state.personList.unshift(value)
}
},
state:{
personList:[
{id:'001',name:'张三'}
],
},
getters:{
firstPersonName(state){
return state.personList[0].name
}
},
}
//创建store并导出
export default new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
附:运行结果
以下是store对象中的五个属性及用法
//state--用于存储数据
state: {},
//mutations--用于操作数据(state)
mutations: {},
//actions---用于响应组件中的动作
actions: {},
//modules--用于存放多个组件的不同数据及操作加工等
modules: {},
//getters:用于将state中的数据进行加工
getters:{}