【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'}),

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

相关推荐
Larcher1 小时前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐2 小时前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭2 小时前
如何理解HTML语义化
前端·html
jump6802 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信2 小时前
我们需要了解的Web Workers
前端
brzhang2 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu3 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花3 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js
十二春秋3 小时前
场景模拟:基础路由配置
前端
六月的可乐3 小时前
实战干货-Vue实现AI聊天助手全流程解析
前端·vue.js·ai编程