• vue中的一个重要插件——vuex


    目录

    一、vuex简介

    二、vuex工作原理

    三、小案例

    四、四个map方法的使用

    1、mapState

    2、mapGetters

    3、mapMutations

    4、mapActions

    五、vuex实现数据共享案例

    1、项目目录

    2、源码

    六、vuex实现模块化+命名空间

    1、步骤:

    2、开启命名空间后,读取state数据

    ①、自己读取

    ②、借助mapState读取

     3、开启命名空间后,读取getters数据

    ①、自己读取

    ②、借助mapState读取

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

    ①、自己调用dispatch

    ②、借助mapActions

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

    ①、自己直接调用commit

    ②、借助mapMutations

    5、案例源码



    一、vuex简介:

    概念:专门在vue中实现集中式状态(数据)管理的一个vue插件,对vue应用中多个组件共享状态进行集中式的管理读/写),也是一种组件间的通讯方式,且适用于任意组件间通讯

    何时使用:

    ①、多个组件依赖同一状态

    ②、来自不同组件的行为需要变更同一状态

    二、vuex工作原理

    三、小案例

    main.js代码:

    1. // 项目的入口文件
    2. // 引入vue
    3. import Vue from 'vue'
    4. // 引入App,他是所有组件的父组件
    5. import App from './App'
    6. // 引入vuex
    7. import Vuex from 'vuex'
    8. // 引入store
    9. import store from './store'
    10. // 关闭vue的生产提示
    11. Vue.config.productionTip = false
    12. // 使用vuex
    13. Vue.use(Vuex)
    14. // 创建vue实例对象
    15. new Vue({
    16. el:'#app',
    17. render: h => h(App),
    18. store,
    19. })

    App.vue代码:

    1. <template>
    2. <div>
    3. <Count>Count>
    4. div>
    5. template>
    6. <script>
    7. import Count from './components/Count.vue'
    8. export default {
    9. name: "App",
    10. components:{Count},
    11. }
    12. script>

    Count.vue代码:

    1. <template>
    2. <div>
    3. <h1>当前求和为:{{$store.state.sum}}h1>
    4. <select v-model.number="n">
    5. <option :value="1">1option>
    6. <option :value="2">2option>
    7. <option :value="3">3option>
    8. select>
    9. <button @click="increment">+button>
    10. <button @click="decrement">-button>
    11. <button @click="incrementOdd">当前求和为奇数再+1button>
    12. <button @click="incrementWait">等一等再+1button>
    13. div>
    14. template>
    15. <script>
    16. export default {
    17. name:'Count',
    18. data(){
    19. return{
    20. n:1,
    21. }
    22. },
    23. methods:{
    24. increment(){
    25. // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
    26. this.$store.commit("JIA",this.n)
    27. },
    28. decrement(){
    29. // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
    30. this.$store.commit("JIAN",this.n)
    31. },
    32. incrementOdd(){
    33. this.$store.dispatch("jiaOdd",this.n)
    34. },
    35. incrementWait(){
    36. this.$store.dispatch("jiaWait",this.n)
    37. }
    38. }
    39. }
    40. script>
    41. <style>
    42. button{
    43. margin-left: 5px;
    44. }
    45. style>

    store/index.js代码:

    1. // 该文件用于创建vuex中最核心的store
    2. // 引入Vue
    3. import Vue from 'vue'
    4. // 引入Vuex
    5. import Vuex from 'vuex'
    6. // 应用Vuex插件
    7. Vue.use(Vuex)
    8. // 准备actions————用于响应组件中的动作
    9. const actions = {
    10. // 接收两个参数:第一个是mini版的store,第二个是传过来的value值
    11. // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
    12. // jia(context,value){
    13. // // 调用mutations中的JIA函数
    14. // console.log('actions中的jia被调用了')
    15. // context.commit("JIA",value)
    16. // },
    17. // jian(context,value){
    18. // // 调用mutations中的JIA函数
    19. // console.log('actions中的jian被调用了')
    20. // context.commit("JIAN",value)
    21. // },
    22. jiaOdd(context,value){
    23. console.log('actions中的jiaOdd被调用了')
    24. if(context.state.sum % 2){
    25. // 调用mutations中的JIA函数
    26. context.commit("JIA",value)
    27. }
    28. },
    29. jiaWait(context,value){
    30. console.log('actions中的jia被调用了')
    31. setTimeout(()=>{
    32. // 调用mutations中的JIA函数
    33. context.commit("JIA",value)
    34. },500)
    35. }
    36. }
    37. // 准备mutations————用于操作数据(state)
    38. const mutations = {
    39. JIA(state,value){
    40. console.log('mutations中的JIA被调用了')
    41. state.sum+=value
    42. },
    43. JIAN(state,value){
    44. console.log('mutations中的JIAN被调用了')
    45. state.sum-=value
    46. }
    47. }
    48. // 准备state————用于存储数据
    49. const state = {
    50. sum:0
    51. }
    52. // 创建并暴露store
    53. export default new Vuex.Store({
    54. actions,
    55. mutations,
    56. state
    57. })

    四、四个map方法的使用

    1、mapState

    借助mapState生成计算属性,从state读取数据对象写法

    1. computed:{
    2. // 借助mapState生成计算属性:sum、school、subject(对象写法)
    3. ...mapState({sum:'sum',school:'school',subject:'subject'})
    4. },

     借助mapState生成计算属性,从state读取数据数组写法

    1. computed:{
    2. // 借助mapState生成计算属性sum、school、subject(数组写法)
    3. ...mapState(['sum','school','subject'])
    4. },

    2、mapGetters

    借助mapGetters生成计算属性,从getters读取数据对象写法

    1. computed:{
    2. // 借助mapState生成计算属性sum、school、subject(数组写法)
    3. ...mapGetters({bigSum:'bigSum'}),
    4. },

    借助mapGetters生成计算属性,从getters读取数据数组写法

    1. computed:{
    2. // 借助mapState生成计算属性sum、school、subject(数组写法)
    3. ...mapGetters(['bigSum'])
    4. },

    3、mapMutations

    借助mapMutations生成对应的方法,方法中会调用commit去联系mutations;

    (1)、对象方法

    注意:

    这里调用increment和decrement方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n

    1. <button @click="increment(n)">+button>
    2. <button @click="decrement(n)">-button>
    1. methods:{
    2. // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象方法)
    3. // 注意:这里调用increment和decrement方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n
    4. ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    5. },

    (2)、数组方法

    注意:

    这里需要将html结构中调用的位置都改为JIAJIAN

    1. <button @click="JIA(n)">+button>
    2. <button @click="JIAN(n)">-button>
    1. methods:{
    2. // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组方法)
    3. // 注意:这里使用的是JIA和JIAN,需要在html结构中改为JIA和JIAN
    4. ...mapMutations(['JIA','JIAN']),
    5. },

    4、mapActions

     帮我们生成与Actions对话的方法,即:包含$store.dispatch(xxx)的函数;

    借助mapActions生成对应的方法,方法中会调用commit去联系mutations;

    (1)、对象方法

    注意:

    这里调用iincrementOdd和incrementWait方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n

    1. <button @click="incrementOdd(n)">当前求和为奇数再+1button>
    2. <button @click="incrementWait(n)">等一等再+1button>
    1. methods:{
    2. // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象方法)
    3. ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
    4. },

    (2)、数组方法

    注意:

    这里需要将html结构中调用的位置都改为jiaOddjiaWait

    1. <button @click="jiaOdd(n)">当前求和为奇数再+1button>
    2. <button @click="jiaWait(n)">等一等再+1button>
    1. methods:{
    2. // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组方法)
    3. ...mapActions(['jiaOdd','jiaWait'])
    4. },

    五、vuex实现数据共享案例

    1、项目目录

    2、源码:

    App.vue

    1. <template>
    2. <div>
    3. <Count>Count>
    4. <Person>Person>
    5. div>
    6. template>
    7. <script>
    8. import Count from './components/Count.vue'
    9. import Person from './components/Person.vue'
    10. export default {
    11. name: "App",
    12. components:{Count,Person},
    13. }
    14. script>

    store/index.js

    1. // 该文件用于创建vuex中最核心的store
    2. // 引入Vue
    3. import Vue from 'vue'
    4. // 引入Vuex
    5. import Vuex from 'vuex'
    6. // 应用Vuex插件
    7. Vue.use(Vuex)
    8. // 准备actions————用于响应组件中的动作
    9. const actions = {
    10. jiaOdd(context,value){
    11. console.log('actions中的jiaOdd被调用了')
    12. if(context.state.sum % 2){
    13. // 调用mutations中的JIA函数
    14. context.commit("JIA",value)
    15. }
    16. },
    17. jiaWait(context,value){
    18. console.log('actions中的jia被调用了')
    19. setTimeout(()=>{
    20. // 调用mutations中的JIA函数
    21. context.commit("JIA",value)
    22. },500)
    23. }
    24. }
    25. // 准备mutations————用于操作数据(state)
    26. const mutations = {
    27. JIA(state,value){
    28. console.log('mutations中的JIA被调用了')
    29. state.sum+=value
    30. },
    31. JIAN(state,value){
    32. console.log('mutations中的JIAN被调用了')
    33. state.sum-=value
    34. },
    35. ADD_PERSON(state,value){
    36. console.log('mutations中的ADD_PERSON被调用了')
    37. state.personList.unshift(value)
    38. }
    39. }
    40. // 准备state————用于存储数据
    41. const state = {
    42. sum:0,
    43. school:'尚硅谷',
    44. subject:'前端',
    45. personList:[
    46. {id:'001',name:'张三'}
    47. ]
    48. }
    49. // 准备getters————用于存储加工后的数据
    50. const getters = {
    51. bigSum(state){
    52. return state.sum*10
    53. }
    54. }
    55. // 创建并暴露store
    56. export default new Vuex.Store({
    57. actions,
    58. mutations,
    59. state,
    60. getters
    61. })

    Count.vue

    1. <template>
    2. <div>
    3. <h1>当前求和为:{{sum}}h1>
    4. <h1>当前求和扩大10倍为:{{bigSum}}h1>
    5. <h3>我在{{school}},学习{{subject}}h3>
    6. <h3 style="color:red;">Person组件的总人数为:{{personList.length}}h3>
    7. <select v-model.number="n">
    8. <option :value="1">1option>
    9. <option :value="2">2option>
    10. <option :value="3">3option>
    11. select>
    12. <button @click="increment(n)">+button>
    13. <button @click="decrement(n)">-button>
    14. <button @click="incrementOdd(n)">当前求和为奇数再+1button>
    15. <button @click="incrementWait(n)">等一等再+1button>
    16. div>
    17. template>
    18. <script>
    19. import {mapState,mapGetters, mapMutations, mapActions} from 'vuex'
    20. export default {
    21. name:'Count',
    22. data(){
    23. return{
    24. n:1,
    25. }
    26. },
    27. computed:{
    28. ...mapState(['sum','school','subject','personList']),
    29. ...mapGetters(['bigSum'])
    30. },
    31. methods:{
    32. ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    33. ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
    34. },
    35. mounted(){
    36. const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
    37. }
    38. }
    39. script>
    40. <style>
    41. button{
    42. margin-left: 5px;
    43. }
    44. style>

    Person.vue

    1. <template>
    2. <div>
    3. <h1>人员列表h1>
    4. <h3 style="color:red;">Count组件求和为:{{sum}}h3>
    5. <input type="text" placeholder="请输入名字" v-model="name">
    6. <button @click="add">添加button>
    7. <ul>
    8. <li v-for="p in personList" :key="p.id">{{p.name}}li>
    9. ul>
    10. div>
    11. template>
    12. <script>
    13. import {nanoid} from 'nanoid'
    14. export default {
    15. name:'Person',
    16. data(){
    17. return{
    18. name:''
    19. }
    20. },
    21. computed:{
    22. personList(){
    23. return this.$store.state.personList
    24. },
    25. sum(){
    26. return this.$store.state.sum
    27. }
    28. },
    29. methods:{
    30. add(){
    31. const personObj = {id:nanoid(),name:this.name}
    32. this.$store.commit('ADD_PERSON',personObj)
    33. this.name = ''
    34. }
    35. }
    36. }
    37. script>

    六、vuex实现模块化+命名空间

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

    1、步骤:

    ①、在store文件夹中,将不同内容分模块化进行分类一种内容存储在一个js文件中,通过index.js文件进行import和模块化定义

    1. import countOptions from './count'
    2. import personOptions from './person'
    3. // 创建并暴露store
    4. export default new Vuex.Store({
    5. modules:{
    6. countAbout:countOptions,
    7. personAbout:personOptions
    8. }
    9. })

    ②、将不同内容放在不同js文件中,并开启命名空间

    person.jscount.js文件结构如下:

    1. // 个人相关的配置
    2. export default {
    3. namespaced:true,
    4. actions:{
    5. // ...
    6. },
    7. mutations:{
    8. // ...
    9. },
    10. state:{
    11. // ...
    12. },
    13. getters:{
    14. // ...
    15. }

    2、开启命名空间后,读取state数据

    ①、自己读取

    this.$store.state.personAbout.list

    ②、借助mapState读取

    ...mapState('countAbout',['sum','school','subject'])

     3、开启命名空间后,读取getters数据

    ①、自己读取

    this.$store.getters['personAbout/firstPersonName']

    ②、借助mapState读取

    ...mapGetters('countAbout',['bigSum'])

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

    ①、自己调用dispatch

    this.$store.dispatch('personAbout/addPersonWang',person)

    ②、借助mapActions

    ...mapActions('countAbout',(incrementOdd:'jiaOdd',incrementWait:'jiaWait'))

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

    ①、自己直接调用commit

    this.$store.commit('personAbout/ADD_PERSON',person)

    ②、借助mapMutations

    ...mapActions('countAbout',(increment:'JIA',decrement:'JIAN'))

    5、案例源码

    目录结构:

    App.vue

    1. <template>
    2. <div>
    3. <Count>Count>
    4. <Person>Person>
    5. div>
    6. template>
    7. <script>
    8. import Count from './components/Count.vue'
    9. import Person from './components/Person.vue'
    10. export default {
    11. name: "App",
    12. components:{Count,Person},
    13. }
    14. script>

     

    main.js

    1. // 项目的入口文件
    2. // 引入vue
    3. import Vue from 'vue'
    4. // 引入App,他是所有组件的父组件
    5. import App from './App'
    6. // 引入vuex
    7. import Vuex from 'vuex'
    8. // 引入store
    9. import store from './store'
    10. // 关闭vue的生产提示
    11. Vue.config.productionTip = false
    12. // 使用vuex
    13. Vue.use(Vuex)
    14. // 创建vue实例对象
    15. new Vue({
    16. el:'#app',
    17. render: h => h(App),
    18. store,
    19. })

    components/Count.vue

    1. <template>
    2. <div>
    3. <h1>当前求和为:{{sum}}h1>
    4. <h1>当前求和扩大10倍为:{{bigSum}}h1>
    5. <h3>我在{{school}},学习{{subject}}h3>
    6. <h3 style="color:red;">Person组件的总人数为:{{personList.length}}h3>
    7. <select v-model.number="n">
    8. <option :value="1">1option>
    9. <option :value="2">2option>
    10. <option :value="3">3option>
    11. select>
    12. <button @click="increment(n)">+button>
    13. <button @click="decrement(n)">-button>
    14. <button @click="incrementOdd(n)">当前求和为奇数再+1button>
    15. <button @click="incrementWait(n)">等一等再+1button>
    16. div>
    17. template>
    18. <script>
    19. import {mapState,mapGetters, mapMutations, mapActions} from 'vuex'
    20. export default {
    21. name:'Count',
    22. data(){
    23. return{
    24. n:1,
    25. }
    26. },
    27. computed:{
    28. ...mapState('countAbout',['sum','school','subject']),
    29. ...mapState('personAbout',['personList']),
    30. ...mapGetters('countAbout',['bigSum'])
    31. },
    32. methods:{
    33. ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    34. ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
    35. },
    36. mounted(){
    37. const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
    38. }
    39. }
    40. script>
    41. <style>
    42. button{
    43. margin-left: 5px;
    44. }
    45. style>

    components/Person.vue

    1. <template>
    2. <div>
    3. <h1>人员列表h1>
    4. <h3 style="color:red;">Count组件求和为:{{sum}}h3>
    5. <h3>列表中第一个人的名字是:{{firstPersonName}}h3>
    6. <input type="text" placeholder="请输入名字" v-model="name">
    7. <button @click="add">添加button>
    8. <button @click="addWang">添加一个姓王的人button>
    9. <button @click="addPersonServer">添加一个人,名字随机button>
    10. <ul>
    11. <li v-for="p in personList" :key="p.id">{{p.name}}li>
    12. ul>
    13. div>
    14. template>
    15. <script>
    16. import {nanoid} from 'nanoid'
    17. export default {
    18. name:'Person',
    19. data(){
    20. return{
    21. name:''
    22. }
    23. },
    24. computed:{
    25. personList(){
    26. // 添加了personAbout
    27. return this.$store.state.personAbout.personList
    28. },
    29. sum(){
    30. // 添加了countAbout
    31. return this.$store.state.countAbout.sum
    32. },
    33. firstPersonName(){
    34. return this.$store.getters['personAbout/firstPersonName']
    35. }
    36. },
    37. methods:{
    38. add(){
    39. const personObj = {id:nanoid(),name:this.name}
    40. this.$store.commit('personAbout/ADD_PERSON',personObj)
    41. this.name = ''
    42. },
    43. addWang(){
    44. const personObj = {id:nanoid(),name:this.name}
    45. this.$store.dispatch('personAbout/addPersonWang',personObj)
    46. this.name = ''
    47. },
    48. addPersonServer(){
    49. this.$store.dispatch('personAbout/addPersonServer')
    50. }
    51. }
    52. }
    53. script>
    54. <style>
    55. style>

    store/count.js

    1. // 求和相关的配置
    2. export default {
    3. namespaced:true,
    4. actions:{
    5. jiaOdd(context,value){
    6. console.log('actions中的jiaOdd被调用了')
    7. if(context.state.sum % 2){
    8. // 调用mutations中的JIA函数
    9. context.commit("JIA",value)
    10. }
    11. },
    12. jiaWait(context,value){
    13. console.log('actions中的jia被调用了')
    14. setTimeout(()=>{
    15. // 调用mutations中的JIA函数
    16. context.commit("JIA",value)
    17. },500)
    18. }
    19. },
    20. mutations:{
    21. JIA(state,value){
    22. console.log('mutations中的JIA被调用了')
    23. state.sum+=value
    24. },
    25. JIAN(state,value){
    26. console.log('mutations中的JIAN被调用了')
    27. state.sum-=value
    28. },
    29. },
    30. state:{
    31. sum:0,
    32. school:'尚硅谷',
    33. subject:'前端',
    34. },
    35. getters:{
    36. bigSum(state){
    37. return state.sum*10
    38. }
    39. }
    40. }

    store/index.js

    1. // 该文件用于创建vuex中最核心的store
    2. // 引入Vue
    3. import Vue from 'vue'
    4. // 引入Vuex
    5. import Vuex from 'vuex'
    6. import countOptions from './count'
    7. import personOptions from './person'
    8. // 应用Vuex插件
    9. Vue.use(Vuex)
    10. // 创建并暴露store
    11. export default new Vuex.Store({
    12. modules:{
    13. countAbout:countOptions,
    14. personAbout:personOptions
    15. }
    16. })

    store/person.js

    1. import axios from 'axios'
    2. import { nanoid } from 'nanoid'
    3. // 个人相关的配置
    4. export default {
    5. namespaced:true,
    6. actions:{
    7. addPersonWang(context,value){
    8. if(value.name.indexOf('王') === 0){
    9. context.commit('ADD_PERSON',value)
    10. }else{
    11. alert('添加的人必须姓王!')
    12. }
    13. },
    14. addPersonServer(context){
    15. // 地址是一个随机自动显示文字的api
    16. axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
    17. response => {
    18. context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
    19. },
    20. error => {
    21. alert(error.message)
    22. }
    23. )
    24. }
    25. },
    26. mutations:{
    27. ADD_PERSON(state,value){
    28. console.log('mutations中的ADD_PERSON被调用了')
    29. state.personList.unshift(value)
    30. }
    31. },
    32. state:{
    33. personList:[
    34. {id:'001',name:'张三'}
    35. ]
    36. },
    37. getters:{
    38. firstPersonName(state){
    39. return state.personList[0].name
    40. }
    41. }
    42. }

  • 相关阅读:
    go-gin-vue3-elementPlus带参手动上传文件
    板材的Dk和Df测试方法概述
    HTML课程简介
    Python和Scrapy构建可扩展的框架
    linux ubuntu 开发环境搭建 opencv fftw openvino
    基于微信小程序的付费自习室系统平台设计与实现的源码+文档
    VSCode配置C和C++语言
    有人说SaToken吃相难看,你怎么看。
    迁移学习——ResNet152
    对数据安全建设的思路ing
  • 原文地址:https://blog.csdn.net/weixin_46376652/article/details/125858614