• vue、vuex状态管理


    每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

    1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

    2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

    vuex初步使用

    1、安装vuex

    口诀:“233”、“344”

    数字分别对应,“vue版本,vue 路由版本、vuex 版本”。

    所以这里了使用vuex3版本:

    yarn add vuex@3

     

     2、创建仓库文件

     编写如下:

    1. // 这个文件用于存放vuex的核心代码
    2. import Vue from 'vue'
    3. import Vuex from 'vuex'
    4. // 插件安装
    5. Vue.use(Vuex)
    6. // 创建仓库
    7. const store = new Vuex.Store()
    8. // 导出仓库,把仓库丢到main.js
    9. export default store

     3、在main.js中导入

    1. import Vue from 'vue'
    2. import App from './App.vue'
    3. import router from './router'
    4. import store from '@/store/index'
    5. Vue.config.productionTip = false
    6. new Vue({
    7. router,
    8. render: h => h(App),store
    9. }).$mount('#app')

     4、验证仓库是否被创建成功

    1. created () {
    2. console.log('222222')
    3. console.log(this.$store)
    4. },

    控制台打印:

    这个对象就是我们的仓库了



    使用state仓库的数据

    state是vuex的核心。

    状态目标:明确如何给仓库提供数据。

    如何使用仓库的数据?方式有两种:

    1、通过store直接访问

    步骤1:提供数据State

    提供唯一的公共数据源,所有共享的数据都要统一放到 Store中的 State中存储。在 state对象中可以添加我们要共享的数据。

    步骤2:获取数据:

    示例:

    1、在我们的vuex仓库中添加共享的数据

    1. // 这个文件用于存放vuex的核心代码
    2. import Vue from 'vue'
    3. import Vuex from 'vuex'
    4. // 插件安装
    5. Vue.use(Vuex)
    6. // 创建仓库
    7. const store = new Vuex.Store({
    8. // 通过提供数据,这些数据被所有的组件共享
    9. state: {
    10. title: '公共的标题',
    11. count: 100
    12. }
    13. })
    14. // 导出仓库,把仓库丢到main.js
    15. export default store

    2、在我们的页面中获取数据

      <h1>{{ $store.state.title }}h1>

    2、通过辅助函数访问

    简化mapstate是辅助函数,帮助我们把 store中的数据自动映射到组件的计算属性中。

     

    步骤1:

    1. import { mapState } from 'vuex'
    2. // console.log(mapState(['count','title']))
    3. // 我们可以在计算属性中展开mapState

    步骤2:

    1. computed: {
    2. ...mapState(['count', 'title'])
    3. },

    步骤3:

    我们可以像使用vue的data中的数据一样,去使用计算属性中的变量。

       <h1>{{ title }}h1>

     

     3、严格模式

    明确νuex同样遵循单向数据流,组件中不能直接修改仓库的数据通过 strict:true可以开启严格模式

    1. // 创建仓库
    2. const store = new Vuex.Store({
    3. // 严格模式: 如果每个组件都可以修改数据,一旦项目打了,开发人员多了,就很难维护了
    4. // 可以使用严格模式来让vuex修改数据,修改后,vuex在通知我们的组件,更新数据。
    5. // 有利于初学者,检测不规范的代码=>上线时需要关闭
    6. strict: true,
    7. // 通过提供数据,这些数据被所有的组件共享
    8. state: {
    9. title: '公共的标题',
    10. count: 100
    11. }
    12. })

     4  mutations的操作流程

    state数据的修改只能通过 mutations。

    1、仓库index.js

    1. const store = new Vuex.Store({
    2. strict: true,
    3. state: {
    4. title: '公共的标题',
    5. count: 100
    6. },
    7. mutations: {
    8. // 所有 mutation函数,第一个参数,都是 state
    9. addCount (state) {
    10. state.count += 1
    11. }
    12. }
    13. })

     2、在页面中使用我们的mutations

    1. handleAddCount(){
    2. this.$store.commit('addCount')
    3. }
         <button @click="handleAddCount">值 + 1button>

     

    5  mutations传参语法

    需要注意的是,如果要传递多个参数,我们需要把多个参数丢到对象当中,像传递一个参数一样,把对象传递给我们定义的mutations函数 。

    6  辅助函数: mapmutations

    目标:掌握辅助函数 mapmutations,映射方法mapmutations和 mapstate很像,它是把位于 mutations中的方法提取了出来,映射到组件 methods中

    mapmutations相当于3.1的辅助写法,只是把方法捞到了methods当中了。

    7 actions (异步操作)

    目标:明确 actions的基本语法,处理异步操作,

    需求:一秒钟之后,修改 state的 count成666。

    说明: mutations必须是同步的(便于监测数据变化,记录调试。

     步骤1:修改仓库index.js

    1. mutations: {
    2. changeTitle (state, newTitle) {
    3. state.title = newTitle
    4. }
    5. },
    1. // 3.actions 处理异步
    2. // context上下文(此处未分模块,可以当成 store仓库)
    3. // context, commit(" mutation名字,额外参数)
    4. actions: {
    5. asynChangeTitle (context, newTitle) {
    6. // setTimeout方法是异步的,3秒钟之后换成我们的新标题
    7. setTimeout(()=>{
    8. context.commit('changeTitle',newTitle)
    9. },3000)
    10. }
    11. }

    这里,actions是mutations的同级对象。

    步骤2: 测试

        <button @click="handleChangeTitle">3秒之换标题button>
    1. methods: {
    2. handleChangeTitle () {
    3. // 调用action
    4. //this.$store.dispatch('我们vuex仓库中的action的名字','额外参数')
    5. this.$store.dispatch('asynChangeTitle','这是3秒钟之后的新标题')
    6. }
    7. },

     

    总结:和前面的“mutations传参语法”目录类似,只是多了actions这个中间人 ,this.$store.commi换成了this.$store.dispatch。

    8 getters

    getters类似于计算属性。说明:除了 state之外,有时我们还需要从 state中派生出一些状态,这些状态是依赖 state的,此时会用到 getters。

    例如: statel中定义了list,为1-6的数组,组件中,需要显示所有大于3的数据

    步骤1:

    getters和state同级

    1. getters: {
    2. filterList (state) {
    3. return state.list.filter(item => item > 3)
    4. }
    5. },

    步骤2:

    在组件内使用:

      import { mapState,mapGetters } from 'vuex'
    1. computed: {
    2. //mapState和mapGetters都是映射属性
    3. ...mapState(['count', 'title']),
    4. ...mapGetters(['filterList'])
    5. },

    9 模块 module(进阶语法)

    9.1 获取module的数据

    项目大,代码就多了,store的文件内存上千行代码,很难维护,不易管理。

    module的存在就是为了解决这个问题的。

    步骤1:

    在store目录下建一个新目录modules,在modules下建两个js文件,user.js,setting.js,如下:

    1. // setting.js
    2. const state = {
    3. theme: 'blue',
    4. desc: 'deom'
    5. }
    6. const mutations = {}
    7. const actions = {}
    8. const getters = {}
    9. export default {
    10. state,
    11. mutations,
    12. actions,
    13. getters
    14. }
    1. // user.js
    2. const state = {
    3. name: 'Mike',
    4. hobby: '唱、跳、Rap'
    5. }
    6. const mutations = {}
    7. const actions = {}
    8. const getters = {}
    9. export default {
    10. state,
    11. mutations,
    12. actions,
    13. getters
    14. }

    步骤2、把user.js,setting.js导入到store目录下的index.js文件中:

    1. import settings from './modules/settings'
    2. import user from './modules/user'

     mudules对象和state对象同级:

    1. modules:{
    2. settings,
    3. user
    4. }

    步骤3 使用modules下的数据:

    modules的子模块的状态,还是会挂到根级别的 state使用模块中的数据

    ①直接通过模块名访问$ store. state模块名.XXX

    ②通过 mapstate映射

    默认根级别的映射 mapstate(['XXX'])子模块的映射 mapstate('模块名',['XXX']) -

    需要开启命名空间

    1. export default {
    2. state,
    3. mutations,
    4. actions,
    5. getters,
    6. namespaced:true
    7. }
     ①直接通过模块名访问$store.state.模块名.XXX
         <span>爱好: {{ $store.state.user.hobby }}span>

    ②通过mapstate映射
      <span>(mapState)爱好: {{ user.hobby }}span>
    1. computed: {
    2. //mapState和mapGetters都是映射属性
    3. ...mapState(['count', 'title','settings','user']),
    4. ...mapGetters(['filterList'])
    5. },

     9.2 修改module模块下的数据

    步骤1、定义mutaion

    1. const mutations = {
    2. setUserInfo(state,newHobby){
    3. state.hobby = newHobby
    4. }
    5. }
    1. methods: {
    2. updateUserInfo () {
    3. // this.$store.commit('模块名/mutation名',参数)
    4. this.$store.commit('user/setUserInfo','唱、跳、Rap、Smile')
    5. }
    6. },
    1. <span>爱好: {{ user.hobby }}span>

     点击按钮前:

     点击按钮后的页面:

     

  • 相关阅读:
    AI视界周刊第 1 期:最具性价比 GPT-4o mini 发布、大模型集体失智、语言模型安全漏洞
    金仓数据库KingbaseES物理备份恢复最佳实践(概述)
    9.2.5.2 【MySQL】XDES 类型
    [LeetCode] 最后一个单词的长度【58】
    前端 JS 经典:ES6 和 CommonJs 用法
    数据结构和算法(14):串
    cmd界面中文显示?VS控制台中文显示?
    【LeetCode】No.55. Jump Game -- Java Version
    R语言data.table包进行数据分组聚合统计变换(Aggregating transforms)、计算dataframe数据的分组标准差(sd)
    electron+vue3全家桶+vite项目搭建【27】封装窗口工具类【1】雏形
  • 原文地址:https://blog.csdn.net/m0_59259076/article/details/133579168