本篇文章主要重点介绍在学习Vuex基础之后的更深一层次的内容,如果还没掌握基础的,可以先去看一下【Vuex基础详解】
首先,我们从一个案例出发,之后引出后面要谈论的store中的getters,以及Vuex使用中四个map方法的使用以及Vuex的模块化+命名空间
之前一篇文章只介绍了单组件怎么使用Vuex,本文中将结合多组件使用Vuex以及多组件共享Vuex数据以及同步行为
Test1.vue:
<template>
<div>
<h1>当前的数值为:{{num}}h1><hr>
<h2>当前值*5为:{{enlarge}}h2>
<button @click="increment">+button>
<button @click="decrement">-button>
div>
template>
<script>
export default {
name:'CountA',
methods:{
// 把行为通过dispatch传递到Vuex中
increment(){
this.$store.dispatch('increment', this.num)
},
decrement(){
this.$store.dispatch('decrement',this.num)
}
},
computed:{
enlarge(){
//利用Vuex中的getters获取到值
return this.$store.getters.enlarge
},
// 使用计算属性读取到Vuex中的数据
num(){
return this.$store.state.num;
},
},
}
script>
<style scoped>
style>
test2.vue:
<template>
<div>
<h1>电影列表h1>
<h2>添加喜欢的歌曲h2>
<input type="text" v-model="name" placeholder="请输入歌曲名字"><button @click="addMusic">添加button>
<h4>歌曲展示区h4>
<ul v-for="m,index in musics" :key="index">
<li>{{m}}li>
ul>
div>
template>
<script>
export default {
name:'PersonA',
data(){
return{
name:'',
}
},
methods:{
//同样,把行为传递给Vuex
addMusic(){
this.$store.dispatch('addMusic', this.name)
this.name = ''
}
},
//同样的方法,用计算属性加工读取state中对应的值
computed:{
musics(){
return this.$store.state.musics;
}
}
}
script>
<style>
style>
src/store/index.js:
//该文件用于创建Vuex中最核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用vuex
Vue.use(Vuex);
const actions = {
increment(context, value){
//把行为传递给Mutations
context.commit('INCREMENT', value);
},
decrement(context, value){
//把行为传递给Mutations
context.commit('DECREMENT', value);
},
// 简单逻辑业务
addMusic(context, value){
if(value !== ''){
context.commit('ADDMUSIC', value)
}
}
}
const mutations ={
//操作数据,实际上的响应行为
INCREMENT(state){
state.num += 1;
},
DECREMENT(state){
state.num -= 1;
},
ADDMUSIC(state,value){
state.musics.push(value);
}
}
const state = {
num:0, //count组件需要的数据
musics:['孤勇者', '阴天快乐', '单车', '红玫瑰', '稻香', '晴天'], //persons组件需要的数据
}
//利用getters方法获取值
const getters = {
enlarge(state){
return state.num * 5
}
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
上述代码中,我们在Vuex的基础使用上增加了用store的getters来读取放大5倍后的数值,虽然这个操作在计算属性中就可以完成,但在实际开发中当我们用到Vuex的时候,state中的数据需要经过加工后再使用时,可以使用getters加工
用到getters的部分:
src/store/index.js:
//利用getters方法获取值
const getters = {
enlarge(state){
return state.num * 5
}
}
//创建并暴露store
export default new Vuex.Store({
......
getters
})
组件中读取数据:
两种方式:要么直接用插值语法,要么用计算属性返回,看自己选择
方式一:
<h1>getters加工后的值为:{{$store.getters.enlarge}}h1>
方式二:
<h1>getters加工后的值为{{enlarge}}h1>
......
......
<script>
...
copmputed:{
enlarge(){
//利用Vuex中的getters获取到值
return this.$store.getters.enlarge
}
}
...
script>
接下来将详细介绍4个map方法的使用
mapState方法: 用于帮助我们映射State中的数据为计算属性,简单理解来说就是用到Vuex中数据的时候,我们用计算属性加工的动作都可用此方法精简
...
computed:{
//借助mapState生成计算属性(对象写法)
...mapState({key:'value',...})
//借助mapState生成计算属性(数组写法,前提是组件中使用的计算属性命名和store中方法的命名一致)
...mapState(['name',....])
}
...
mapGetters方法:用于帮助我们映射getters中的数据为计算属性,原理和mapState一样
...
computed:{
//借助mapGetters生成计算属性(对象写法)
...mapGetters({key:'value',....})
//(数组写法,前提同上)
...mapGetters(['name',.....])
}
...
mapActions方法:用于帮助我们生成与Actions
对话的方法,即this.$store.dispatch(...)
.
methods:{
//借助mapActions生成对应方法(对象写法)
...mapActions({key:'value',.....})
//(数组写法,前提同上)
...mapActions(['name',......])
}
**mapMutations方法:**用于帮助我们生成与Mutations
对话的方法,即this.$store.commit(...)
.
methods:{
//借助mapMutations生成对应方法(对象写法)
...mapMutations({key:'value',.....})
//(数组写法,前提同上)
...mapMutations(['name',......])
}
以上四个方法,作用都是在我们使用Vuex时帮助我们简化代码,在实际开发过程中,能有效提高我们的工作效率
值得注意的点是:
1.使用到哪个方法,就必须先引入对应方法:
import {mapGetters, mapState, mapActions, mapMutations} from 'vuex’
2.虽然有每个方法都有两种写法(对象,数组),但在使用数组写法时,需保持组件中computed或methods中的方法命名要和store中对应方法的名字一致,否则就会报错
3.在使用mapsActions和mapMutations时,如果需要传递参数,则要模板绑定方法时就要传入对应参数,否则参数默认为事件对象.。
页面中效果:
完整代码如下:
test1.vue:
<template>
<div>
<h1>当前的数值为:{{num}}h1><hr>
<h2>当前值*5为:{{enlarge}}h2>
<button @click="increment">+button>
<button @click="decrement">-button>
div>
template>
<script>
import {mapGetters, mapState, mapActions, mapMutations} from 'vuex'
export default {
name:'CountA',
methods:{
// 把行为通过dispatch传递到Vuex中
// increment(){
// this.$store.dispatch('increment', this.num)
// },
//使用mapActions简写
...mapActions({increment:'increment'}),
// decrement(){
// this.$store.dispatch('decrement',this.num)
// }
//使用mapMutation简写,这里直接访问Mutations是因为本行为并不包含逻辑处理和请求那些,可选择直接跳过Actions
...mapMutations({decrement:'DECREMENT'})
},
computed:{
...mapGetters({enlarge:'enlarge'}),
// enlarge(){
// //利用Vuex中的getters获取到值
// return this.$store.getters.enlarge
// },
//使用mapState读取
...mapState({num:'num'})
},
}
script>
<style scoped>
style>
test2.vue:
<template>
<div>
<h1>电影列表h1>
<h2>添加喜欢的歌曲h2>
<input type="text" v-model="name" placeholder="请输入歌曲名字"><button @click="addMusic(name)">添加button>
<h4>歌曲展示区h4>
<ul v-for="m,index in musics" :key="index">
<li>{{m}}li>
ul>
div>
template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name:'PersonA',
data(){
return{
name:'',
}
},
methods:{
//同样,把行为传递给Vuex
// addMusic(){
// this.$store.dispatch('addMusic', this.name)
// },
//使用mapActions
...mapActions({addMusic:'addMusic'})
},
//同样的方法,用计算属性加工读取state中对应的值
computed:{
//使用mapState读取
// musics(){
// return this.$store.state.musics;
// }
...mapState({musics:'musics'})
}
}
script>
<style>
style>
src/store/index.js:
//该文件用于创建Vuex中最核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用vuex
Vue.use(Vuex);
const actions = {
increment(context, value){
//把行为传递给Mutations
context.commit('INCREMENT', value);
},
decrement(context, value){
//把行为传递给Mutations
context.commit('DECREMENT', value);
},
// 简单逻辑业务
addMusic(context, value){
if(value !== ''){
context.commit('ADDMUSIC', value)
}else{
alert('输入的名字不能为空');
}
}
}
const mutations ={
//操作数据,实际上的响应行为
INCREMENT(state){
state.num += 1;
},
DECREMENT(state){
state.num -= 1;
},
ADDMUSIC(state,value){
state.musics.push(value);
}
}
const state = {
num:0, //count组件需要的数据
musics:['孤勇者', '阴天快乐', '单车', '红玫瑰', '稻香', '晴天'], //persons组件需要的数据
}
//利用getters方法获取值
const getters = {
//加工state中的数据
enlarge(state){
return state.num * 5
},
//读取state中的数据
num(state){
return state.num;
},
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
以上就是map相关4个方法的简单使用
在以后的开发场景中,我们对于Vuex的使用肯定会比较频繁,随之对应的组件一多,对Vuex的访问以及行为动作会变得越来越多,如果不做处理和规划,则会造成代码冗余量高,且不便维护的问题,所以就可以使用模块化编码,提高代码可读性和可维护性。
修改src/store/index.js文件:
....
//把test1.vue中需要用到的操作从新规划,把对应的操作再归类
const test1 = {
namespaced:true, //首先开启命名空间,否则无法找对应位置
state:{.....},
mutations{....},
actions:{.....}.
getters:{.....}
};
const test2 = {
namespaced:true, //首先开启命名空间,否则无法找对应位置
state:{.....},
mutations{....},
actions:{.....}.
getters:{.....}
}
....
//创建并暴露Store
export default new Vuex.Store({
modules:{
test1:'test1',
test2:'test2',
}
})
此时组件中调用store中对应方法:
//这里采用数组方式传参,所以与之对应的方法名必须一致
//读取state数据
...mapState('test1',['num',......])
//读取getters中的数据
...mapGettrts('test1',['enlarge',.....])
//调用dispatch()
...mapActions('test1',{increment:'increment',.....})
//调用commit()
...mapMutations('test1',{decremet:'DECREMENT'})
以上就是我对Vuex中map相关方法以及模块化编码的理解,在写完这些笔记之后,觉得自己对Vuex相关的知识又更加巩固了,哈哈哈,记得点赞收藏加关注哟!!!!