Vue Vuex学习(vuex模块化+命名空间namespace)

文章目录

  • Count.vue 分组修改
  • Person.vue 分组修改
  • 继续优化,分成文件引入
  • actions联系后端api练习
  • 总结

没有看过上一篇的同学可以查看: Vue Vuex学习(vuex配置项、多组件数据共享案例)

Count.vue 分组修改

index.js 分组先用起来
我们观察 index.js,mutations 中有 JIAJIANADD_PERSON,也就是既有计算模块 Count 的方法,也有人员模块 Person 的方法。如果以后模块多了都写在这里,不便于管理。其他的 actions、getters、state 都是相同的情况,所以我们进行分组,把计算模块放在一起,把人员管理模块相关配置放一起:
Vue Vuex学习(vuex模块化+命名空间namespace)_第1张图片

完整代码如下:
index.js

//该文件用于创建vuex中最为核心的store

//引入vuex
import Vuex from 'vuex'
//引入vue
import Vue from "vue";
//应用vuex插件
Vue.use(Vuex)

//求和相关配置
const countOptions = {
    actions: {
        jiaOdd(context, value) {
            console.log("actions中的jianOdd被调用了", context);
            if (context.state.sum % 2) {
                context.commit("JIA", value)
            }
            context.dispatch("demo", value)
        },
        jiaWait(context, value) {
            console.log("actions中的jianWait被调用了");
            setTimeout(() => {
                context.commit("JIA", value)
            }, 500)
        }
    },
    mutations: {
        JIA(state, value) {
            console.log("mutations中的JIA被调用了", state, value);
            state.sum += value;
        },
        JIAN(state, value) {
            console.log("mutations中的JIAN被调用了", state, value);
            state.sum -= value;
        }
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    },
    state: {
        sum: 0,//当前和
        school: "三里屯小学",
        subject: "Vue",
    }
}
//人员相关配置
const personOptions = {
    actions: {},
    mutations: {
        ADD_PERSON(state, value) {
            console.log("mutations中的ADD_PERSON被调用了", state, value);
            state.personList.unshift(value)
        }
    },
    getters: {},
    state: {
        personList: [
            {id: "001", name: "张三"},
            {id: "002", name: "李四"}
        ]
    }
}

//创建并暴露store
export default new Vuex.Store({
    modules:{
        a: countOptions,
        b: personOptions
    }
});

我们可以把 App.vue 中 Person 组件先删掉,只关注 Count.vue ,在 mounted 中打印下 this.$store,找到 state,可以发现有我们刚才写的 a、b
Vue Vuex学习(vuex模块化+命名空间namespace)_第2张图片
所以页面上取值就变成了

	<h1>当前求和为:{{ a.sum }}h1>

    <h3>我在:{{ a.school }}学习{{ a.subject }}h3>
    <h3 style="color: red">Person组件的总人数为{{b.personList.length}}h3>
computed: {
	...mapState(['a','b']),
}

优化一下下
这样写可能有些同学会觉得有点繁琐,每次都 a.sum,a.school,不能像之前那样直接写 sum,shool 吗,可以的,我们修改 index.js 中计算相关配置,增加 namespaced:true,同样的也给人员相关配置增加

//求和相关配置
const countOptions = {
    namespaced:true,
    ......
}

//人员相关配置
const personOptions = {
    namespaced:true,
    ......
}

Count.vue 中

<h1>当前求和为:{{ sum }}h1>

    <h3>我在:{{ school }}学习{{ subject }}h3>
    <h3 style="color: red">Person组件的总人数为{{personList.length}}h3>

computed: {
    ......
    ...mapState('a',['sum','school',"subject","personList"]),
    ...mapState('b',["personList"]),
	......
  },

同样的修改其他 actions、mutations 等,Count.vue 完整代码如下:

<template>
  <div class="category">
    <h1>当前求和为:{{ sum }}h1>
    <h3>当前求和10倍为:{{ bigSum }}h3>
    <h3>我在:{{ school }}学习{{ subject }}h3>
    <h3 style="color: red">Person组件的总人数为{{personList.length}}h3>
    <select v-model="n">
      
      <option :value="1">1option>
      <option :value="2">2option>
      <option :value="3">3option>
    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('a',['sum','school',"subject","personList"]),
    ...mapState('b',["personList"]),
    ...mapGetters('a',['bigSum'])
  },
  methods: {
    ...mapMutations('a',{"increment":"JIA","decrement":"JIAN"}),
   
    ...mapActions('a',{incrementOdd:"jiaOdd",incrementWait:"jiaWait"})
  }
}
script>

<style scoped>
select, button {
  margin-right: 5px;
}
style>

Person.vue 分组修改

为了练习 actions 和 getters 在 index.js 中人员相关配置中也增加方法。我们直接看代码,然后解释

Person.vue

<template>
  <div class="category">
    <h1>人员信息h1>
    <input type="text" placeholder="请输入名字" v-model="name"/>
    <button @click="add">添加button>
    <button @click="addWang">添加一个姓王的人button>
    <ul>
      <li v-for="person in personList" :key="person.id">{{person.name}}li>
    ul>

    <h3>列表中第一个人的名字:{{firstPersonName}}h3>
    <h3 style="color: red">Count组件求和为{{sum}}h3>
  div>
template>

<script>
import {nanoid} from "nanoid"
export default {
  name: "Person",
  data(){
    return{
      name:""
    }
  },
  methods:{
    add(){
      const personObj = {id:nanoid(),name:this.name}
      this.$store.commit("b/ADD_PERSON",personObj)
      this.name = ""
    },
    addWang(){
      const personObj = {id:nanoid(),name:this.name}
      this.$store.dispatch("b/addPersonWang",personObj)
      this.name = ""
    }
  },
  computed:{
    personList(){
      return this.$store.state.b.personList;
    },
    sum(){
      return this.$store.state.a.sum;
    },
    firstPersonName(){
      return this.$store.getters['b/firstPersonName'];
    }
  }
}
script>

<style scoped>
select, button {
  margin-right: 5px;
}
style>

index.js

//求和相关配置
const countOptions = {
  ......	
}
//人员相关配置
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("mutations中的ADD_PERSON被调用了", state, value);
            state.personList.unshift(value)
        }
    },
    getters: {
        firstPersonName(state) {
            return state.personList[0].name;
        }
    },
    state: {
        personList: [
            {id: "001", name: "张三"},
            {id: "002", name: "李四"}
        ]
    }
}

//创建并暴露store
export default new Vuex.Store({
    modules: {
        a: countOptions,
        b: personOptions
    }
});

我们在 index.js 中 actions 中增加了 addPersonWang 来筛选,只能添加姓王的人,getters 中增加了 firstPersonName 来返回人员列表第一个人名

Person.vue 中增加了一个 h3 标签来展示人员列表第一个人的名字,使用计算属性 firstPersonName return this.$store.getters['b/firstPersonName']来调用了 index.js 中写的返回第一个人名的方法,为什么这么取值呢?我们可以在 mounted 生命钩子中打印 this.$store 查看 getters:
Vue Vuex学习(vuex模块化+命名空间namespace)_第3张图片
又增加了一个按钮绑定方法addWang来只添加姓王的人,这个方法写在 action 中,action 联系 mutations 用 dispatch,方法要这样写 b/addPersonWang

继续优化,分成文件引入

store 下新建 count.js 和 person.js ,把 index.js 中计算相关配置和人员相关配置放别放进来
Vue Vuex学习(vuex模块化+命名空间namespace)_第4张图片
在 index.js 中引入即可
Vue Vuex学习(vuex模块化+命名空间namespace)_第5张图片

actions联系后端api练习

Vue Vuex学习(vuex模块化+命名空间namespace)_第6张图片
Person.vue 中增加一个按钮,添加一个人,名字随机,由后台返回。用到的接口是:https://api.uixsj.cn/hitokoto/get?type=social,它会随机返回一句话

先看效果:
Vue Vuex学习(vuex模块化+命名空间namespace)_第7张图片
person.js

import axios from "axios";
import {nanoid} from "nanoid";

export default {
    namespaced: true,
    actions: {
        ......
        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)
                }
            )
        }
    },
	......
}

Person.vue 中

<button @click="addPersonServer">添加一个人,名字随机button>
<script>
methods:{
    ......
    addPersonServer(){
      this.$store.dispatch("b/addPersonServer")
    },
  },
script>

总结

1、目的:让代码更好维护,让多种数据分类更加明确
2、修改 index.js

const countAbout = {
	namespaced:true,//开启命名空间
	state:{x:1}mutations:{ ... },
	actions:{ ... },
	getters: {
		bigSum( state){
			return state.sum *10
		}
	}
}

const personAbout = {
	namespaced:true,//开启命名空间
	state:{ ... },
	mutations: { ... },
	actions: { ... }
}
	
const store = new Vuex.Store({
	modules: {
		countAbout,
		personAbout
	}
})

3、开启命名空间后,组件中读取 state 数据:

//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取
...mapState('countAbout',['sum','school','subject']),

4、开启命名空间后,组件中读取 getters 数据:

//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])

5、开启命名空间后,组件中调用 dispatch

//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonwang',person)
//方式二:借助mapActions:
...mapActions ('countAbout' ,{incrementOdd:'jiaOdd',incrementWait:'jiawait'})

6、开启命名空间后,组件中调用 commit

//方式一:自己直接 commit
this.$store.commit('personAbout/ADD_PERSON",person)
//方式二:借助 mapMutations:
...mapMutations('countAbout' ,{increment:'JIA',decrement:'JIAN'})

你可能感兴趣的:(Vue学习笔记,vue,vuex)