第5章:vuex
第5章:vuex
- 1 求和案例 纯vue版
- 2 vuex工作原理图
- 3 vuex案例
- 3.1 搭建vuex环境
- 错误写法
- 正确写法
- 3.2 求和案例vuex版
- 细节分析
- 源代码
- 4 getters配置项
- 4.1 细节
- 4.2 源代码
- 5 mapState与mapGetters
- 5.1 总结
- 5.2 细节分析
- 5.3 源代码
- 6 mapActions与mapMutations
- 6.1 总结
- 6.2 细节
- 6.3 源代码
- 7 多组件共享数据
- 7.1 细节
- 7.2 源代码
- 8 vuex模块化 + namespace
- 8.1 总结
- 8.2 第一部分
- 细节问题
- 8.3 第二部分
- 细节问题
- 8.4 源代码
1 求和案例 纯vue版
这里只需要住一个问题,就是Count组件的v-model.number=“n”,如果没有number,这个n就是个字符串。
src/components/Count.vue
<template><div><h1>当前求和为:{{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, //用户选择的数字sum:0 //当前的和}},methods: {increment(){this.sum += this.n},decrement(){this.sum -= this.n},incrementOdd(){if(this.sum % 2){this.sum += this.n}},incrementWait(){setTimeout(()=>{this.sum += this.n},500)},},}
</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>
src/main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)//创建vm
new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this}
})
2 vuex工作原理图
以求和案例为例,用sum来表示当前的和,vuex会交时state保管,此时sum为0。
- State是一个Object类型对象,可以存储很多数据,例如todos,sum等。
接下来过程如下:
- Count组件调用dispatch,它是一个函数,要传两个参数,一个是进行的动作类型,一个是数据,即dispatch(‘jia’,2)。
- Actions也是一个Object类型对象,此时Actions对象里面必然有一组key value为jia:function,此时函数被调用,就收到了2,function函数里面就会调用commit(‘jia’,2)。
- Mutations也是一个Object类型对象,此时Mutations对象里面必然有一组key value为jia:function,function会拿到两个东西,一个是state,一个是2,随后function里面就写state.sum += 2即可,然后底层就自动走了Mutate。
- 最终state里面保存的sum的值就变为了2。
- vuex会重新解析组件,再重新渲染页面,于是页面的sum也变成了2
Actions设计的目的是为了和后端交互的,例如dispatch(‘chu’),有动作类型,但没有所对应的值,此时就要问后端了,后端服务器返回9,如下:
如果你并不需要和后端交互,就可以直接和Mutations交互,如下:
注意到Devtools即开发者工具是和Mutations进行交互的。
Actions、Mutations和State统一经过一个东西的管理,如下:
也就是说调用dispatch等方法时,是由store提供的,如下:
3 vuex案例
3.1 搭建vuex环境
2022年2月7日,Vue3已经成为了默认版本,vuex也同时更新到4版本,即执行命令:npm i vuex,安装的是vuex的4版本,而vuex的4版本只能在vue3使用。
- Vue2中,要用vuex的3版本,执行命令:npm i vuex@3
- Vue3中,要用vuex的4版本
错误写法
首先在src下面创建一个store文件夹,如下:
index里面代码如下:
紧接着在main.js引入store,由于文件名称是index.js,所以可以直接省略名字,脚手架认识,如下:
此时好像环境搭建完毕,但这样会出错,如下:创建store实例之前就要使用Vue.use(Vuex)
回到main.js代码分析,首先得把绿色框文件里得代码执行完了,我才能收到store,随后才走粉色框代码。
- 这样就导致了先创建store实例,因为绿色框文件即index.js创建了一个store实例。
哪怕换顺序也没用,import语句有优先级,会优先执行,不管顺序。
- 即首先扫描所有import语句,按照import语句代码顺序,全部先执行import语句。
正确写法
首先在src下面创建一个store文件夹,如下:
index里面代码如下:
紧接着在main.js引入store,由于文件名称是index.js,所以可以直接省略名字,脚手架认识,如下:
3.2 求和案例vuex版
细节分析
一般来说共享是由两个及以上的组件才叫共享,如下:
但在这个案例中仅仅使用了Count组件,主要是为了学习vuex的开发流程。
细节一:actions
actions中函数的第一个参数是context,称之为miniStore,其内容如下:
actions中函数的第二个参数就是所传递的值。
一般commit的时候会大写JIA,目的是做个区分,一看到大写JIA,就知道是mutations里的。
细节一:mutations
mutations中函数的第一个参数是state,并且进行了加工,加上了get和set,如下:
mutations中函数的第二个参数就是所传递的值。
细节三
如下所示,绿色框函数要作一些判断,它是有存在意义的,而红色框函数没有任何存在意义,因此删掉
删掉之后,直接调用commit即可,如下:
源代码
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/store/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,
})
src/App.vue
<template><div><Count/></div>
</template><script>import Count from './components/Count'export default {name:'App',components:{Count},mounted() {// console.log('App',this)},}
</script>
src/main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)//创建vm
new Vue({el:'#app',render: h => h(App),store,beforeCreate() {Vue.prototype.$bus = this}
})
4 getters配置项
4.1 细节
当前有一个新需求:还要显示当前求和放大十倍后的结果。
最好不要像如下这样写,考虑一下,假设程序员要对state的sum进行一些加工,而且是一些很复杂的数学运算,而且很多程序员要使用这样的功能,这样就不适合像如下这样写。
- 使用计算属性也不行,它不能跨组件
直接在store的index文件夹进行配置,如下:
- state就如同data,而getters就如同computed一样
组件中读取数据:$store.getters.bigSum
。直接看代码即可
4.2 源代码
在求和案例vuex版基础上,要修改的代码有:
src/components/Count.vue
<template><div><h1>当前求和为:{{$store.state.sum}}</h1><h3>当前求和放大10倍为:{{$store.getters.bigSum}}</h3><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.$store)},}
</script><style lang="css">button{margin-left: 5px;}
</style>
src/store/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 //当前的和
}
//准备getters——用于将state中的数据进行加工
const getters = {bigSum(state){return state.sum*10}
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
5 mapState与mapGetters
5.1 总结
5.2 细节分析
我们多配置两个数据,分别为school和subject,如下:当使用state的很多数据时候,会多次调用store.state.xxx,这样很麻烦。
最简单的方式是用计算属性解决,但是要程序员一次一次的配置,也会很麻烦。
vuex的设计者提供了mapState方法,它可以帮我们批量生成粉色框的代码,因为它们共同点都是从state读取数据。
首先要引入mapState,如下:
看看mapState输出是什么
比如要生成state的sum相对应函数,如下:
我们可以写简写形式,即前面的’he’去掉’',但sum不行,它是一个表达式,其余的也同理,如下:
输出x,可以看到,它为我们生成了函数,如下:
在computed里面配置mapstate
我们会发现,像上述这样配置,会发生报错,这是因为mapState本身是一个对象,computed又是对象,不可能直接在对象里面写对象。
在对象里面写对象的方法
先看一个例子
直接在对象前面加三个点,意思是把obj2里面的每一组key和value展开放入到obj里面
最终输出如下:
因此我们要在mapState加三个点,如下:
还有一种数组写法,并且要求同名,如下:
由于同名可以简写,简写的时候必须要’',以sum:'sum’为例,如果简写成sum,最终含义就是sum:sum,进而去读取sum变量,这就报错了。
举个例子,只有是变量的时候,简写才能直接不要’‘,如下:
由于a是变量,所以简写不需要’’
所以最终简写形式如下:
对于getters同理也有mapGetters,一样的用法,直接看代码即可。
5.3 源代码
在求和案例vuex版基础上,要修改的代码有:
src/components/Count.vue
<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{bigSum}}</h3><h3>我在{{school}},学习{{subject}}</h3><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>import {mapState,mapGetters} from 'vuex'export default {name:'Count',data() {return {n:1, //用户选择的数字}},computed:{//靠程序员自己亲自去写计算属性/* sum(){return this.$store.state.sum},school(){return this.$store.state.school},subject(){return this.$store.state.subject}, *///借助mapState生成计算属性,从state中读取数据。(对象写法)// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState(['sum','school','subject']),/* ******************************************************************** *//* bigSum(){return this.$store.getters.bigSum}, *///借助mapGetters生成计算属性,从getters中读取数据。(对象写法)// ...mapGetters({bigSum:'bigSum'})//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters(['bigSum'])},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() {const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>
src/store/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, //当前的和school:'尚硅谷',subject:'前端'
}
//准备getters——用于将state中的数据进行加工
const getters = {bigSum(state){return state.sum*10}
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
6 mapActions与mapMutations
6.1 总结
6.2 细节
我们需要优化的是方法,如下:
首先使用mapMutations修改,如下:
但当点击+1之后,发生如下错误:
我们让JIA输出value看看什么情况,如下:
可以看到,这个value是一个事件,如下:
可以看到,mapMutations生成的函数,需要传递参数。
可以看到,我们调用函数时,并没有传递参数,所以默认传的参数是event,如下:
因此在调用函数时,要传入参数,如下:
如果不想在函数里面传参,还可以用下面这个方法(但我觉得复杂了):
我们采取函数传参的方法,此时mapMutations还可以使用数组方法,并使用简写形式,如下:
此时调用函数处为:
mapActions同理,不再过多说明,直接看源代码。
6.3 源代码
在求和案例vuex版基础上,要修改的代码有:
src/components/Count.vue
<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{bigSum}}</h3><h3>我在{{school}},学习{{subject}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">当前求和为奇数再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>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']),/* ******************************************************************** *///借助mapGetters生成计算属性,从getters中读取数据。(对象写法)// ...mapGetters({bigSum:'bigSum'})//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters(['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(['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(['jiaOdd','jiaWait'])},mounted() {const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>
src/store/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, //当前的和school:'尚硅谷',subject:'前端'
}
//准备getters——用于将state中的数据进行加工
const getters = {bigSum(state){return state.sum*10}
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
7 多组件共享数据
7.1 细节
看如下需求:sum和persons可以同时共享
细节一
首先是创建Person组件,并在App引入。
紧接着在vuex添加person数据,如下:
紧接着在Person组件引入数据,如下:
- 这里有两种写法,但我们使用红色框的写法,如果我们使用绿色框的写法,就避免了一个问题,不利于学习
- 因此在Person组件不使用简写方式,而在Count组件使用简写方式,这样利于学习
细节二
现在看看PersonList是怎么进行共享的,先看Count组件,借助mapState读取。
而Person组件是利用计算属性读取的,如下:
sum属性也同理,可以去看看。
7.2 源代码
在求和案例vuex版基础上,要修改的代码有:
src/components/Count.vue
<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{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="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">当前求和为奇数再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用户选择的数字}},computed:{//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState(['sum','school','subject','personList']),//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters(['bigSum'])},methods: {//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations({increment:'JIA',decrement:'JIAN'}),//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},mounted() {// const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})// console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>
src/components/Person.vue
<template><div><h1>人员列表</h1><h3 style="color:red">Count组件求和为:{{sum}}</h3><input type="text" placeholder="请输入名字" v-model="name"><button @click="add">添加</button><ul><li v-for="p in personList" :key="p.id">{{p.name}}</li></ul></div>
</template><script>import {nanoid} from 'nanoid'export default {name:'Person',data() {return {name:''}},computed:{personList(){return this.$store.state.personList},sum(){return this.$store.state.sum}},methods: {add(){const personObj = {id:nanoid(),name:this.name}this.$store.commit('ADD_PERSON',personObj)this.name = ''}},}
</script>
src/store/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},ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}
}
//准备state——用于存储数据
const state = {sum:0, //当前的和school:'尚硅谷',subject:'前端',personList:[{id:'001',name:'张三'}]
}
//准备getters——用于将state中的数据进行加工
const getters = {bigSum(state){return state.sum*10}
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
src/App.vue
<template><div><Count/><hr><Person/></div>
</template><script>import Count from './components/Count'import Person from './components/Person'export default {name:'App',components:{Count,Person},mounted() {// console.log('App',this)},}
</script>
8 vuex模块化 + namespace
8.1 总结
8.2 第一部分
细节问题
细节一 配置store
一开始我们是怎么配置store的,如下:
但现在有个问题,以mutation为例,假设是一个电商系统,我们已经实现了求和模块、人员模块,那还要继续写订单模块,商品模块等,这样mutation内容就很多了,很难维护,还有就是所有程序员都操作一个mutation,也容易造成git版本控制冲突。
因此分类整理,相当于分别管理求和的store和人员的store,如下:
紧接着使用配置,如下:
还可以使用简写形式,如下:
细节二 Count组件读取store
由于是初学者,暴露时不使用简写形式,便于学习,如下:
mapstate
第一种读取数据方式如下,会发现比较复杂,如下:
第二种就是利用mapstate的语法,先不管personList,如下:
但这样写会报错,因为没使用namespace,所以要加上,如下:当添加上namespace后,就可以了。
接下来考虑personList(也要加上namespace)如下:
mapmutation mapaction mapgetters
同理,如下:
8.3 第二部分
细节问题
细节一 Person组件读取store
之前Person组件不使用简写方式,就是因为在这里要学习不使用map方法时如何读取store。
读取state
可以看到,用如下的读取方式:
commit
不用简写形式调用Mutations时使用commit,在这里的语法形式如下:
增加一些功能
我们还需要练习getters和dispatch的调用方法,因此在actions和getters上添加一些功能。如下:
getters
在内容添加firstPersonName,如下:
因此需要使用计算属性,这里的写法很独特。
这里有一个方法,就是输出store看看它究竟是什么写法,如下:
所以应该这样写,如下:
dispatch
然后调用dispatch,和getters类似的写法,如下:
细节二 store配置管理问题
直接将person和count拆分管理,如下:
然后在index里面引入就行,如下:
细节三 发请求
在person中添加actions,这个api可以返回一个小语录,这个小语录作为名字,如下:
紧接着在person组件配置,如下:
8.4 源代码
在求和案例vuex版基础上,要修改的代码有:
src/components/Count.vue
<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{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="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">当前求和为奇数再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用户选择的数字}},computed:{//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState('countAbout',['sum','school','subject']),...mapState('personAbout',['personList']),//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters('countAbout',['bigSum'])},methods: {//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},mounted() {console.log(this.$store)},}
</script><style lang="css">button{margin-left: 5px;}
</style>
src/components/Person.vue
<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><button @click="addPersonServer">添加一个人,名字随机</button><ul><li v-for="p in personList" :key="p.id">{{p.name}}</li></ul></div>
</template><script>import {nanoid} from 'nanoid'export default {name:'Person',data() {return {name:''}},computed:{personList(){return this.$store.state.personAbout.personList},sum(){return this.$store.state.countAbout.sum},firstPersonName(){return this.$store.getters['personAbout/firstPersonName']}},methods: {add(){const personObj = {id:nanoid(),name:this.name}this.$store.commit('personAbout/ADD_PERSON',personObj)this.name = ''},addWang(){const personObj = {id:nanoid(),name:this.name}this.$store.dispatch('personAbout/addPersonWang',personObj)this.name = ''},addPersonServer(){this.$store.dispatch('personAbout/addPersonServer')}},}
</script>
src/store/count.js
//求和相关的配置
export default {namespaced:true,actions:{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:{JIA(state,value){console.log('mutations中的JIA被调用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被调用了')state.sum -= value},},state:{sum:0, //当前的和school:'尚硅谷',subject:'前端',},getters:{bigSum(state){return state.sum*10}},
}
src/store/index.js
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)//创建并暴露store
export default new Vuex.Store({modules:{countAbout:countOptions,personAbout:personOptions}
})
src/store/person.js
//人员管理相关的配置
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {namespaced:true,actions:{addPersonWang(context,value){if(value.name.indexOf('王') === 0){context.commit('ADD_PERSON',value)}else{alert('添加的人必须姓王!')}},addPersonServer(context){axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(response => {context.commit('ADD_PERSON',{id:nanoid(),name:response.data})},error => {alert(error.message)})}},mutations:{ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}},state:{personList:[{id:'001',name:'张三'}]},getters:{firstPersonName(state){return state.personList[0].name}},
}
src/App.vue
<template><div><Count/><hr><Person/></div>
</template><script>import Count from './components/Count'import Person from './components/Person'export default {name:'App',components:{Count,Person},mounted() {// console.log('App',this)},}
</script>
相关文章:

第5章:vuex
第5章:vuex 1 求和案例 纯vue版2 vuex工作原理图3 vuex案例3.1 搭建vuex环境错误写法正确写法 3.2 求和案例vuex版细节分析源代码 4 getters配置项4.1 细节4.2 源代码 5 mapState与mapGetters5.1 总结5.2 细节分析5.3 源代码 6 mapActions与mapMutations6.1 总结6.2…...

[Python入门学习记录(小甲鱼)]第5章 列表 元组 字符串
第5章 列表 元组 字符串 5.1 列表 一个类似数组的东西 5.1.1 创建列表 一个中括号[ ] 把数据包起来就是创建了 number [1,2,3,4,5] print(type(number)) #返回 list 类型 for each in number:print(each) #输出 1 2 3 4 5#列表里不要求都是一个数据类型 mix [213,"…...

Docker 学习(四)——Dockerfile 创建镜像
Dockerfile是一个文本格式的配置文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在D…...

Java多线程与高并发专题——为什么 Map 桶中超过 8 个才转为红黑树?
引入 JDK 1.8 的 HashMap 和 ConcurrentHashMap 都有这样一个特点:最开始的 Map 是空的,因为里面没有任何元素,往里放元素时会计算 hash 值,计算之后,第 1 个 value 会首先占用一个桶(也称为槽点ÿ…...
LeetCode hot 100—二叉树的中序遍历
题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示例 3: 输入:root […...

代码随想录算法训练营第35天 | 01背包问题二维、01背包问题一维、416. 分割等和子集
一、01背包问题二维 二维数组,一维为物品,二维为背包重量 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner scanner new Scanner(System.in);int n scanner.nextInt();int bag scanner.nextInt();int[…...

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景
中国联通软件研究院(简称联通软研院)在全面评估与广泛调研后,在 2021年底决定采用OceanBase 作为基础,自研分布式数据库产品CUDB(即China Unicom Database,中国联通数据库)。目前,该…...

IDEA 接入 Deepseek
在本篇文章中,我们将详细介绍如何在 JetBrains IDEA 中使用 Continue 插件接入 DeepSeek,让你的 AI 编程助手更智能,提高开发效率。 一、前置准备 在开始之前,请确保你已经具备以下条件: 安装了 JetBrains IDEA&…...

斗地主小游戏
<!DOCTYPE html> <html><head><meta charset="utf-8"><title>斗地主</title><style>.game-container {width: 1000px;height: 700px;margin: 0 auto;position: relative;background: #35654d;border-radius: 10px;padding…...

如何改变怂怂懦弱的气质(2)
你是否曾经因为害怕失败而逃避选择?是否因为不敢拒绝别人而让自己陷入困境?是否因为过于友善而被人轻视?如果你也曾为这些问题困扰,那么今天的博客就是为你准备的。我们将从行动、拒绝、自我认知、实力提升等多个角度,…...

C# OnnxRuntime部署DAMO-YOLO人头检测
目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name:input tensor:Floa…...

基于GeoTools的GIS专题图自适应边界及高宽等比例生成实践
目录 前言 一、原来的生成方案问题 1、无法自动读取数据的Bounds 2、专题图高宽比例不协调 二、专题图生成优化 1、直接读取矢量数据的Bounds 2、专题图成果抗锯齿 3、专题成果高宽比例自动调节 三、总结 前言 在当今数字化浪潮中,地理信息系统(…...

各种DCC软件使用Datasmith导入UE教程
3Dmax: 先安装插件 https://www.unrealengine.com/zh-CN/datasmith/plugins 左上角导出即可 虚幻中勾选3个插件,重启引擎 左上角选择文件导入即可 Blender导入Datasmith进UE 需要两个插件, 文章最下方链接进去下载安装即可 一样的,直接导出,然后UE导入即可 C4D 直接保存成…...

尚硅谷爬虫note15
一、当当网 1. 保存数据 数据交给pipelines保存 items中的类名: DemoNddwItem class DemoNddwItem(scrapy.Item): 变量名 类名() book DemoNddwItem(src src, name name, price price)导入: from 项目名.items import 类…...

云原生系列之本地k8s环境搭建
前置条件 Windows 11 家庭中文版,版本号 23H2 云原生环境搭建 操作系统启用wsl(windows subsystem for linux) 开启wsl功能,如下图 安装并开启github加速器 FastGithub 2.1 下载地址:点击下载 2.2 解压安装文件fastgithub_win-x64.zip 2…...

关于tomcat使用中浏览器打开index.jsp后中文显示不正常是乱码,但英文正常的问题
如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head标签加入: <meta charset"UTF-8"> 以jsp为例子,我们…...

mysql foreign_key_checks
foreign_key_checks是一个用于设置是否在DML/DDL操作中检查外键约束的系统变量。该变量默认启用,通常在正常操作期间启用以强制执行参照完整性。 功能描述 foreign_key_checks用于控制是否在DML(数据操纵语言)和DDL(数据定义…...

开发环境搭建-06.后端环境搭建-前后端联调-Nginx反向代理和负载均衡概念
一.前后端联调 我们首先来思考一个问题 前端的请求地址是:http://localhost/api/employee/login 后端的接口地址是:http://localhost:8080/admin/employee/login 明明请求地址和接口地址不同,那么前端是如何请求到后端接口所响应回来的数…...

REST API前端请求和后端接收
1、get请求,带"?" http://localhost:8080/api/aop/getResult?param123 GetMapping("getResult")public ResponseEntity<String> getResult(RequestParam("param") String param){return new ResponseEntity<>("12…...

道可云人工智能每日资讯|《奇遇三星堆》VR沉浸探索展(淮安站)开展
道可云元宇宙每日简报(2025年3月5日)讯,今日元宇宙新鲜事有: 《奇遇三星堆》VR沉浸探索展(淮安站)开展 近日,《奇遇三星堆》VR沉浸探索展(淮安站)开展。该展将三星堆文…...

服务器数据恢复—raid5阵列中硬盘掉线导致上层应用不可用的数据恢复案例
服务器数据恢复环境&故障: 某公司一台服务器,服务器上有一组由8块硬盘组建的raid5磁盘阵列。 磁盘阵列中2块硬盘的指示灯显示异常,其他硬盘指示灯显示正常。上层应用不可用。 服务器数据恢复过程: 1、将服务器中所有硬盘编号…...

【Pandas】pandas Series swaplevel
Pandas2.2 Series Computations descriptive stats 方法描述Series.argsort([axis, kind, order, stable])用于返回 Series 中元素排序后的索引位置的方法Series.argmin([axis, skipna])用于返回 Series 中最小值索引位置的方法Series.argmax([axis, skipna])用于返回 Series…...

esp32s3聊天机器人(二)
继续上文,硬件软件准备齐全,介绍一下主要用到的库 sherpa-onnx 开源的,语音转文本、文本转语音、说话人分类和 VAD,关键是支持C#开发 OllamaSharp 用于连接ollama,如其名C#开发 虽然离可玩还有一段距离࿰…...

pyside6学习专栏(九):在PySide6中使用PySide6.QtCharts绘制6种不同的图表的示例代码
PySide6的QtCharts类支持绘制各种型状的图表,如面积区域图、饼状图、折线图、直方图、线条曲线图、离散点图等,下面的代码是采用示例数据绘制这6种图表的示例代码,并可实现动画显示效果,实际使用时参照代码中示例数据的格式将实际数据替换即可…...

DVI分配器2进4出,2进8出,2进16出,120HZ
DVI(Digital Visual Interface)分配器GEFFEN/HDD系列是一种设备,它能够将一个DVI信号源的内容复制到多个显示设备上。根据您提供的信息,这里我们关注的是具有2个输入端口和多个(4个、8个或16个)输出端口的D…...

迷你世界脚本文字板接口:Graphics
文字板接口:Graphics 彼得兔 更新时间: 2024-08-27 11:12:18 具体函数名及描述如下: 序号 函数名 函数描述 1 makeGraphicsText(...) 创建文字板信息 2 makeflotageText(...) 创建漂浮文字信息 3 makeGraphicsProgress(...) 创建进度条信息…...

5分钟速览深度学习经典论文 —— attention is all you need
《Attention is All You Need》是一篇极其重要的论文,它提出的 Transformer 模型和自注意力机制不仅推动了 NLP 领域的发展,还对整个深度学习领域产生了深远影响。这篇论文的重要性体现在其开创性、技术突破和广泛应用上,是每一位深度学习研究…...

Cursor + IDEA 双开极速交互
相信很多开发者朋友应该和我一样吧,都是Cursor和IDEA双开的开发模式:在Cursor中快速编写和生成代码,然后在IDEA中进行调试和优化 在这个双开模式的开发过程中,我就遇到一个说大不大说小不小的问题: 得在两个编辑器之间来回切换查…...

HDFS的设计架构
HDFS 是 Hadoop 生态系统中的分布式文件系统,设计用于存储和处理超大规模数据集。它具有高可靠性、高扩展性和高吞吐量的特点,适合运行在廉价硬件上。 1. HDFS 的设计思想 HDFS 的设计目标是解决大规模数据存储和处理的问题,其核心设计思想…...

为wordpress自定义一个留言表单并可以在后台进行管理的实现方法
要为WordPress添加留言表单功能并实现后台管理,你可以按照以下步骤操作: 1. 创建留言表单 首先,你需要创建一个留言表单。可以使用插件(如Contact Form 7)或手动编写代码。 使用Contact Form 7插件 安装并激活Contact Form 7插件。 创建…...