• vue重修之Vuex【上部】


    版权声明

    • 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
    • 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
    • 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
    • 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。

    Vuex 概述

    • uex 是一个用于 Vue.js 的状态管理库【状态就是数据】。简言之,Vuex 是一个插件,可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。
    • 使用场景
      在这里插入图片描述

    • 优势
      • 共同维护一份数据,数据集中化管理
      • 响应式变化
      • 操作简洁
        在这里插入图片描述

    Vuex 的主要概念和组件

    • 状态(State):Vuex 中的状态是存储应用程序数据的地方,通常表示为 JavaScript 对象。

    • 获取器(Getters):获取器用于根据当前状态计算派生状态类似于存储库中的计算属性。

    • 突变(Mutations):突变是修改状态的唯一方式。它们是同步的,通过明确定义状态如何改变,有助于维护可预测的状态。

    • 动作(Actions):动作用于执行异步操作和触发突变。适合进行诸如发出 API 请求然后根据结果提交突变等任务。

    • 模块(Modules):Vuex 允许将存储划分为模块。这对于较大的应用程序有助于将状态、突变、动作和获取器组织成更小、更可管理的部分。

    • Vuex 特别适用于较大的应用程序,其中状态管理可能变得复杂。

    • 它强制执行单向数据流,并使更容易跟踪应用程序状态变化的来源。这种可预测性有助于调试和维护不断增长的应用程序。

    vuex的使用

    • Vue.js 应用程序中设置 Vuex 的一般步骤
      在这里插入图片描述
    1. 安装(Installation):你需要将 Vuex 安装为依赖项,可以使用 npm 或 yarn 进行安装。

      npm i vuex@3 # vue2适用
      
      • 1
    2. 存储配置(Store Configuration):通过定义状态、突变、动作和获取器来创建一个存储。

      • 为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。
        在这里插入图片描述
         // store.js
         import Vue from 'vue'
         import Vuex from 'vuex'
      
         Vue.use(Vuex)
      
         const store = new Vuex.Store({
           state: {
             // 在这里定义应用程序的状态
           },
           mutations: {
             // 在这里定义突变函数
           },
           actions: {
             // 在这里定义动作函数
           },
           getters: {
             // 在这里定义获取器函数
           }
         })
         export default store
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    3. 在 main.js 中导入挂载到 Vue 实例上

      import Vue from 'vue'
      import App from './App.vue'
      import store from './store'
      
      Vue.config.productionTip = false
      
      new Vue({
        render: h => h(App),
        store
      }).$mount('#app')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    4. 测试打印Vuex

      created(){
        console.log(this.$store)
      }
      
      • 1
      • 2
      • 3

    状态 (state)

    • “state”(状态)是指应用程序中的数据的集合,通常表示为一个包含各种属性的 JavaScript 对象。这些属性可以包括应用程序的配置、用户信息、页面内容、各种设置等。
    • State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。
    • store 对象的 state 属性中定义应用程序的状态
    const store = new Vuex.Store({
      // state 状态, 即数据, 类似于vue组件中的data,
      // 区别:
      // 1.data 是组件自己的数据, 
      // 2.state 中的数据整个vue项目的组件都能访问到
      state: {
        user: null,
        settings: {
          theme: 'light',
          language: 'en',
        },
        // 其他应用程序状态
      },
      // 其他配置项
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Vuex特点

    • Vuex 中状态的一些重要特点
      • Centralized: Vuex 中的状态是集中管理的,这意味着所有组件都可以访问相同的状态数据,而不需要通过复杂的组件传递数据来实现共享。

      • Reactive: Vuex 的状态是响应式的。当状态发生变化时,依赖于该状态的组件会自动更新以反映这些变化。

      • Read-Only: Vuex 的状态是只读的。这意味着你不能直接在组件中修改状态,而是需要通过 mutations 来进行修改。这有助于维护状态的可预测性。

      • Single Source of Truth: Vuex 鼓励将应用程序的状态集中到一个单一的状态树中,使其成为整个应用程序的“唯一数据源”。这有助于简化状态的管理和维护。

      • Predictable: 由于状态的修改只能通过 mutations 来进行,因此状态的变化变得可预测,易于调试和维护。

    访问vuex中数据

    1. 通过$store直接访问 —> {{ $store.state.count }}
    2. 通过辅助函数mapState 映射计算属性 —> {{ count }}

    $store访问

    • 通过$store访问的语法
      获取 store:
       1.Vue模板中获取 this.$store
       2.js文件中获取 import 导入 store
      
      
      模板中:     {{ $store.state.xxx }}
      组件逻辑中:  this.$store.state.xxx
      JS模块中:   store.state.xxx
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 模板中使用
      • 在组件中访问 Vuex 中的状态,可以使用 this.$store.state 来获取状态的值
    <template>
      <div>
        <p>User: {{ $store.state.user }}</p>
        <p>Theme: {{ $store.state.settings.theme }}</p>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 组件逻辑中使用
      • 将state属性定义在计算属性中
      <h1>state的数据 - {{ count }}</h1>
      
      // 把state中数据,定义在组件内的计算属性中
        computed: {
          count () {
            return this.$store.state.count
          }
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • js文件中使用
    //main.js
    
    import store from "@/store"
    
    console.log(store.state.count)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    mapState辅助函数访问

    • mapState是辅助函数,把store中的数据映射到 组件的计算属性中, 它属于一种方便的用法
      在这里插入图片描述
    • 第一步:导入mapState (mapState是vuex中的一个函数)
      import { mapState } from 'vuex'
      
      • 1
    • 第二步:采用数组形式引入state属性
      mapState(['count']) 
      
      • 1
      • 上面的代码等价于
      count () {
          return this.$store.state.count
      }
      
      • 1
      • 2
      • 3
    • 第三步:利用展开运算符将导出的状态映射给计算属性
        computed: {
          ...mapState(['count'])
        }
      
       <div> state的数据:{{ count }}</div>
      
      • 1
      • 2
      • 3
      • 4
      • 5

    开启严格模式及Vuex的单项数据流

    • vuex 同样遵循单向数据流,组件中不能直接修改仓库的数据
    1. 直接在组件中修改Vuex中state的值
      在这里插入图片描述
    • Son1.vue
    button @click="handleAdd">+ 1</button>
    
    methods:{
    	 handleAdd (n) {
          // 错误代码(vue默认不会监测,监测需要成本)
           this.$store.state.count++
          // console.log(this.$store.state.count) 
        },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 开启严格模式
      • 通过 strict: true 可以开启严格模式,开启严格模式后,直接修改state中的值会报错
      • state数据的修改只能通过mutations,并且mutations必须是同步的
        在这里插入图片描述

    突变(mutations)

    mutations初识

    1. 定义mutations
    const store  = new Vuex.Store({
      state: {
        count: 0
      },
      // 定义mutations
      mutations: {
         
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 格式说明
    • mutations是一个对象,对象中存放修改state的方法
    mutations: {
        // 方法里参数 第一个参数是当前store的state属性
        // payload 载荷 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
        addCount (state) {
          state.count += 1
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 组件中提交 mutations
    this.$store.commit('addCount')
    
    • 1

    带参 mutations

    • 提交 mutation 是可以传递参数的 this.$store.commit('xxx', 参数)
    1. 提供mutation函数(带参数)
      mutations: {
        ...
        addCount (state, count) {
          state.count = count
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    2. 提交mutation
      handle ( ) {
        this.$store.commit('addCount', 10)
      }
      
      • 1
      • 2
      • 3
    3. 小tips: 提交的参数只能是一个, 如果有多个参数要传, 可以传递一个对象
      this.$store.commit('addCount', {
        count: 10
      })
      
      • 1
      • 2
      • 3

    辅助函数 mapMutations

    • mapMutations 和 mapState很像,它是把位于mutations中的方法提取了出来,映射到组件methods中。
      import  { mapMutations } from 'vuex'
      methods: {
          ...mapMutations(['addCount'])
      }
      //等价于
      methods: {
        // commit(方法名, 载荷参数)
        addCount () {
            this.$store.commit('addCount')
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 在组件中,可以直接通过this.addCount调用
      <button @click="addCount">+1</button>
      
      • 1
    • 请注意: Vuex中mutations中要求不能写异步代码,如果有异步的ajax请求,应该放置在actions中

    动作(Actions)

    • actions是用于处理异步操作的,例如从服务器获取数据或执行复杂的计算。Actions可以包含任何异步操作,但是它们最终需要调用mutations来更新state中的数据。

    • Actions是通过dispatch方法来调用的,dispatch方法接收一个action的名称和一个可选的payload参数。当调用dispatch方法时,它会触发一个action,并且可以在action中执行任何异步操作。

    1. 定义actions
    mutations: {
      changeCount (state, newCount) {
        state.count = newCount
      }
    }
    
    
    actions: {
      setAsyncCount (context, num) {
        // 一秒后, 给一个数, 去修改 num
        setTimeout(() => {
          context.commit('changeCount', num)
        }, 1000)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 组件中通过dispatch调用
    setAsyncCount () {
      this.$store.dispatch('setAsyncCount', 666)
    }
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    辅助函数 mapActions

    • mapActions 是把位于 actions中的方法提取了出来,映射到组件methods中
    • Son.vue
      import { mapActions } from 'vuex'
      methods: {
         ...mapActions(['changeCountAction'])
      }
      
      //mapActions映射的代码 本质上是以下代码的写法
      //methods: {
      //  changeCountAction (n) {
      //    this.$store.dispatch('changeCountAction', n)
      //  },
      //}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 直接通过 this.方法 就可以调用
      <button @click="changeCountAction(200)">+异步button>
      
      • 1

    vuex mutations VS actions

    MutationsActions
    目的修改state中的数据执行异步操作、调用多个mutations
    同步/异步同步操作可以是同步或异步操作
    使用场景更新state中的数据执行异步请求、处理复杂逻辑
    调用方式使用commit方法调用使用dispatch方法调用
    响应不能返回任何值,只能修改state可以返回Promise或异步操作的结果
    跟踪可以在devtools中跟踪mutations的调用可以在devtools中跟踪actions的调用
    • 总体来说
      • mutations适用于同步操作,用于修改state中的数据。它们是可追踪的,可以在devtools中查看它们的调用。
      • actions适用于执行异步操作、调用多个mutations或处理复杂逻辑。它们可以是同步或异步操作,并且可以返回Promise或异步操作的结果。
      • 在调用上,mutations使用commit方法,而actions使用dispatch方法。

    获取器(Getters)

    • getters用于从store中获取数据,类似于计算属性,可以基于store中的state计算出一个新的值。
    • getters可以看作是store的计算属性,它们的值会被缓存起来,只有当所依赖的state发生变化时才会重新计算。
    • 好处:可以将数据的处理逻辑从组件中抽离出来,将其放在store中,从而使得组件更加简洁和易于维护。另外,getters还可以在多个组件中共享和重复使用,避免了代码的冗余。

    • getter示例:
      • 定义doneTodos的getter,它基于store中的todos数组计算出一个新的数组,该数组包含所有已完成的todo对象
      const getters = {
       //getters: {
       // getters函数的第一个参数是 state
       // 必须要有返回值
        doneTodos: state => {
          return state.todos.filter(todo => todo.done)
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 访问getters
      • 使用store访问getters
      {{ $store.getters.doneTodos}}
      
      • 1
      • 在组件中使用这个getter,使用mapGetters辅助函数
    import { mapGetters } from 'vuex'
    
    export default {
      computed: {
        ...mapGetters([
          'doneTodos'
        ])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    总结

    • 关于Vuex中state、getters、mutations和actions的使用总结:
    StateGettersMutationsActions
    用途存储应用程序的数据从state中派生出计算属性修改state中的数据执行异步操作、调用多个mutations
    直接访问使用this.$store.state使用this.$store.getters不直接访问,通过commit方法调用不直接访问,通过dispatch方法调用
    用法示例this.$store.state.countthis.$store.getters.doneTodosthis.$store.commit(‘increment’)this.$store.dispatch(‘fetchData’)
    参数接收state作为参数接收state和payload作为参数接收context对象作为参数
    返回值返回基于state的计算属性或派生数据无返回值,只能修改state可以返回Promise或异步操作的结果
    异步操作不适用不适用不适用适用
    跟踪可以在devtools中跟踪getters的调用可以在devtools中跟踪mutations的调用可以在devtools中跟踪actions的调用
  • 相关阅读:
    声网深度学习时序编码器的资源预测实践丨Dev for Dev 专栏
    Qt中的Resource
    Android:关于定时任务重启之后的问题研究
    创建一个简单的贪吃蛇游戏:HTML、CSS和JavaScript教程
    阿里云在云原生领域喜获多项 OSCAR 开源尖峰案例奖
    【Hadoop】MapReduce 编程案例-WordCount
    Linux —— 线程
    jQuery--选择器/事件/增加/删除
    JavaScript小技能:对象
    使用中台 Admin.Core 实现了一个Razor模板的通用代码生成器
  • 原文地址:https://blog.csdn.net/yang2330648064/article/details/134024042