【vue】vuex实现组件间数据共享 & vuex模块化编码 & 网络请求

目录

一、vuex实现组件间数据共享

[二、 vuex模块化编码](#二、 vuex模块化编码)

三、网络请求

模块化+命名空间小结:

[总结不易~ 本章节对我有很大的收获, 希望对你也是!!!](#总结不易~ 本章节对我有很大的收获, 希望对你也是!!!)


本节素材已上传Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/28.src%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_%E5%A4%9A%E7%BB%84%E4%BB%B6%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE

有过前面vuex四个map的引入,极大的缩短了我们构建dispatch 和 commit过程的流程,现在我们来创建两个组件Count 和 Person来通过vuex进行组件间数据共享

多组件共享数据就变得很简单了,新建一个组件Person就跟Count访问sum一样的考以访问sum

一、vuex实现组件间数据共享

往vuex添加Person的添加用户方法:ADD_PERSON

javascript 复制代码
// 准备mutations------用于操作数据(state)
const mutations = {
  JIA(state, value) {
    console.log('mutations被调用了')
    state.sum += value
  },
  JIAN(state, value) {
    state.sum -= value
  },
  // person 添加一个人没有什么业务逻辑, 可以直接在mytations里面直接进行添加
  ADD_PERSON(state, value) {
    console.log('mutations中的ADD_PERSON被调用了')
    state.personList.unshift(value)
  }
}
// 准备state------用于存储数据
const state = {
  sum: 0,
  school: '武汉传媒学院',
  subject: '前端',
  personList: [
    { id: '001', name: '张三' }
  ]
}

Person来实现数据共享,拿取vuex里面的sum, 就直接...mapState就可以直接拿到

javascript 复制代码
import {nanoid} from 'nanoid'
import {mapState, mapGetter, mapMuatations, mapActions} from 'vuex'
export default {
  name:'MyPerson',
  data() {
    return {
      name: ''
    }
  },
  computed: {
    ...mapState(['personList', 'sum'])
  },
  methods: {
    add() {
      const personObj = {id:nanoid(), name:this.name}
      this.$store.commit('ADD_PERSON', personObj)
      this.name = ''
    }
  }
}

本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/29_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_vuex%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A0%81

二、 vuex模块化编码

现在就遇到一个问题我们现在是开发一个订单系统,那我们就会遇到一个订单的增删改查,一个商品的增删改查,总之很多很多不同的程序都往一个mutations里面挤,最后mutations就会变得十分的臃肿,最最容易造成的就是git的版本冲突!

那么将各个功能分离出来,也是我们必须具备的能力,也十分简单!

在vuex里面将各个功能的actions、mutations、state、getters都准备好,然后分别对每个组件的共都封装好一个对象来存储这个四个属性

javascript 复制代码
// 求和功能相关的配置 写成一个对象就好
const countOptions = {
  // 准备actions------用于响应组件中的动作
  actions: {
    jiaOdd(context, value) {
      console.log('jiaOdd被调用了')
      console.log(context)
      if (context.state.sum % 2) context.commit('JIA', value)
    },
    jiaWait(context, value) {
      console.log('jiaWait被调用了')
      setTimeout(() => { context.commit('JIA', value) }, 500)
    }
  },
  // 准备mutations------用于操作数据(state)
  mutations: {
    JIA(state, value) {
      console.log('mutations被调用了')
      state.sum += value
    },
    JIAN(state, value) {
      state.sum -= value
    },
  },
  // 准备state------用于存储数据
  state: {
    sum: 0,
    school: '武汉传媒学院',
    subject: '前端',
  },
  // 准备getters------用于将state里面的数据进行加工
  getters: {
    bigSum(state) {
      return state.sum * 10
    }
  }
}

// 人员管理功能相关的配置 写成一个对象就好
const personsOptions = {
  actions: {},
  mutations: {
    // person 添加一个人没有什么业务逻辑, 可以直接在mytations里面直接进行添加
    ADD_PERSON(state, value) {
      console.log('mutations中的ADD_PERSON被调用了')
      state.personList.unshift(value)
    }
  },
  state: {
    personList: [
      { id: '001', name: '张三' }
    ]
  },
  getters: {}
}

将各个功能分割好后,就放在Vuex.store里面进行暴露,注意!!!modules是对你的功能配置进行重命名一样,如果懒,也可以采用对象的简写形式!

javascript 复制代码
// 创建 并 暴露store
export default new Vuex.Store({
  modules: {
    countAbout: countOptions,
    personsAbout: personsOptions
  }
})

对外暴露后, 这里拿MyCount组件进行举例,你一看就懂怎么样引用vuex里面分割好的actions、mutations、state、getters属性

要想模板里面的属性名不变,就要提前在map里面解析好,这种引用方法还是挺简单的,一看就懂;同样MyPerson组件也是如此!!!

javascript 复制代码
<template>
  <div>
    <h1>当前求和为:{{ sum }}</h1>
    <h3>放大10倍的和:{{ bigSum }}</h3>
    <h3>我在{{ school }},学习{{ subject }}</h3>
    <select v-model="n" name="" id="">
      <!-- 加上v-bind 就是动态数据绑定 value里面的值会被当作js表达式进行解析 不再是字符串 -->
      <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="jiaOdd(n)">当前求和为奇数再加</button>
    <button @click="jiaWait(n)">等一等再加</button>
    <h3 style="color: red;">Person组件的总人数是:{{ personList.length }}</h3>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  name: 'MyCount',
  data() {
    return {
      n:1, // 用户当前选择的数字
    }
  },
  computed: {
    ...mapState('countAbout', ['sum', 'school', 'subject']),
    ...mapState('personsAbout', ['personList']),

    //数组写法
    ...mapGetters('countAbout', ['bigSum'])

  },
  methods: {
    ...mapMutations('countAbout', {increment:'JIA', decrement:'JIAN'}),

    ...mapActions('countAbout', ['jiaOdd', 'jiaWait'])
  
  
  },
  mounted() {
    const x = mapState({he:'sum', xuexiao:'school', xueke:'subject'})
    console.log(x)
  }
}
</script>

那么此时分别将两个组件的功能都进行完整的分割后,最后的功能分割就来了!!!

const.js求和功能:

javascript 复制代码
// 求和功能相关的配置 写成一个对象就好
export default {
  namespaced: true,
  // 准备actions------用于响应组件中的动作
  actions: {
    jiaOdd(context, value) {
      console.log('jiaOdd被调用了')
      console.log(context)
      if (context.state.sum % 2) context.commit('JIA', value)
    },
    jiaWait(context, value) {
      console.log('jiaWait被调用了')
      setTimeout(() => { context.commit('JIA', value) }, 500)
    }
  },
  // 准备mutations------用于操作数据(state)
  mutations: {
    JIA(state, value) {
      console.log('mutations被调用了')
      state.sum += value
    },
    JIAN(state, value) {
      state.sum -= value
    },
  },
  // 准备state------用于存储数据
  state: {
    sum: 0,
    school: '武汉传媒学院',
    subject: '前端',
  },
  // 准备getters------用于将state里面的数据进行加工
  getters: {
    bigSum(state) {
      return state.sum * 10
    }
  }
}

那么MyPersons组件问题就来了!计算属性里面我是map写的,可以很轻松的就解析vuex里面的内容,但是add方法里面呢?我却很麻烦才能拿到vuex里面功能分割后的内容!

person.js添加人员功能:

javascript 复制代码
  computed: {
    personList() {
      return this.$store.state.personsAbout.personList
    },
    sum() {
      return this.$store.state.countAbout.sum
    },
    firstPersonName() {
      return this.$store.getters['personsAbout/firstPersonName']
    }
  },
  methods: {
    add() {
      const personObj = {id:nanoid(), name:this.name}
      this.$store.commit('personsAbout/ADD_PERSON', personObj)
      this.name = ''
    },
    addWang() {
      const personObj = {id:nanoid(), name:this.name}
      this.$store.dispatch('personsAbout/addPersonWang', personObj)
      this.name = ''
    }
  }

所以还是比较推荐map写法的!毕竟那是配套的~

本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/29_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_vuex%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A0%81

三、网络请求

最后就是网络请求这一条路我们还没有讲过,现在来说说~

在vuex的Person.js里面添加一个actions addPersonServer方法来随机添加一个人的名字

这个网址是每日一句,可以不断的刷新那种经典句子,有兴趣可以自己看看:https://international.v1.hitokoto.cn/ 然后进行axios请求,如果请求成功就得到d的对象itokoto然后进行添加即可

javascript 复制代码
  actions: {
    addPersonServer(context) {
      axios.get('https://international.v1.hitokoto.cn/').then(
        response => {
          console.log(response.data.hitokoto)
          context.commit('ADD_PERSON', { id: nanoid(), name: response.data.hitokoto })
        },
        error => {
          alert(error.message)
        }
      )
    }
  },

最后就在MyPersons组件里面进行调用即可:

javascript 复制代码
    <button @click="addPersonServer">添加一个人,名字随机</button>

    addPersonServer() {
      this.$store.dispatch('personsAbout/addPersonServer')
    }

模块化+命名空间小结:

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 修改store.js

    javascript 复制代码
      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数据:

    javascript 复制代码
      //方式一:自己直接读取
      this.$store.state.personAbout.list
      //方式二:借助mapState读取:
      ...mapState('countAbout',['sum','school','subject']),
  4. 开启命名空间后,组件中读取getters数据:

    javascript 复制代码
      //方式一:自己直接读取
      this.$store.getters['personAbout/firstPersonName']
      //方式二:借助mapGetters读取:
      ...mapGetters('countAbout',['bigSum'])
  5. 开启命名空间后,组件中调用dispatch

    javascript 复制代码
      //方式一:自己直接dispatch
      this.$store.dispatch('personAbout/addPersonWang',person)
      //方式二:借助mapActions:
      ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  6. 开启命名空间后,组件中调用commit

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

总结不易~ 本章节对我有很大的收获, 希望对你也是!!!

相关推荐
TE-茶叶蛋5 分钟前
Nodejs核心机制
前端
pink大呲花10 分钟前
动态路由实现原理及前端控制与后端控制的核心差异
前端
Hopebearer_18 分钟前
什么是CacheStorage?
前端·javascript·web
程序员阿鹏28 分钟前
Spring Boot项目(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot前后端分离)
java·前端·vue.js·spring boot·后端·spring·maven
读心悦32 分钟前
5000字总结 HTML5 中的音频和视频,关羽标签、属性、API 和最佳实践
前端·音视频·html5
哈桑compile39 分钟前
用纯HTML和CSS仿写知乎登录页面
前端·css·html
巴巴_羊1 小时前
webpack和vite区别
前端·webpack·node.js
爱编程的王小美1 小时前
前端代理问题
前端
pink大呲花1 小时前
Vue 跨域解决方案及其原理剖析
前端·javascript·vue.js
亦世凡华、1 小时前
前端npm包发布流程:从准备到上线的完整指南
前端·经验分享·npm·node.js·npm发包