前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vuex 深入浅出超详细

Vuex 深入浅出超详细

作者头像
Java_慈祥
发布2024-08-10 10:21:00
830
发布2024-08-10 10:21:00
举报
文章被收录于专栏:Web前后端、全栈出发

Vuex 深入浅出超详细

什么是Vuex🤔❓

Vuex 官网🔗: Vuex 是一个专为 Vue.js 应用程序设计的状态管理库,它提供了一种集中式管理 应用中的状态;

状态管理模式: 它让组件的状态(数据),管理变得集中、有序,便于在整个应用中,共享和维护数据;

集中式存储: 它将应用的所有组件状态(数据),集中到一个单一的存储对象中,使得统一管理;


这是什么意思呢🤔❓

在复杂的Vue应用中: 多个组件常常需要共享状态(数据),直接传递props、使用事件机制会使程序变得 复杂且难以维护;

Vuex 是一个插件,可以帮我们管理 vue 通用的数据实现:多组件数据共享,多组件共同修改数据信息;

Vuex 应用场景: 跨组件共享状态 比如用户信息、购物车内容等,Vuex 提供了一个中心化的存储,

使得这些数据可以在任何组件中访问和更新,而无需通过复杂的父子组件传递或事件监听;

(官方)注意: 不是所有的场景都适用于Vuex,只有在必要的时候才使用Vuex

使用了Vuex之后,会附加更多的框架中的概念进来,增加了项目的复杂度,(数据的操作更便捷,数据的流动更清晰)

创建\使用:Vuex

自定义创建项目:

vue create vuex-demo 勾选:css预处理器、正常情况还需要勾选 vuexrouter 此处演示个人搭建环境;

安装Vuex 创建仓库:

vuex是一个独立存在的插件,如果脚手架初始化没有选 vuex,就需要额外安装,注意版本兼容:vue2\3\3原则;

代码语言:javascript
复制
yarn add vuex@3		#或 	npm i vuex@3
创建仓库 store/index.js

为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js📄

Vuex的store是一个集中存储应用所有组件共享状态的地方,所有,共享的数据都要统一放到 Store 中的 State 中存储;

它类似于一个全局数据仓库,在组件中访问状态: 通过this.$store访问store中的数据、触发mutations、调用actions

代码语言:javascript
复制
// 导入 vue、vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 启用 Vuex 插件
Vue.use(Vuex)

// 创建仓库 store 状态,即数据:  
// 类似于vue组件中的data、data 是组件自己的数据;
// state 中的数据整个vue项目的组件都能访问到;
const store = new Vuex.Store({
    state: {
        count: 100
    }
})
// 导出仓库 store
export default store
导入main 挂载Vue实例

在Vue应用中引入Storemain.js中导入store,并将其添加到Vue实例中作为选项;

代码语言:javascript
复制
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false

new Vue({
  //挂载至Vue实例
  render: h => h(App),
  store
}).$mount('#app')
在组件中访问状态数据

App.js: 通过this.$store访问store中的数据,此数据可以在任何组件中进行访问;

代码语言:javascript
复制
<template>
  <div id="app">
    <p>store公共仓库获取数据: {{  $store.state.count  }}</p>
  </div>
</template>
<script>
  export default { name: 'App', }
</script>
<style></style>

state状态:

在Vuex中,State是状态管理的核心组成部分之一,它扮演着应用单一数据源的角色:

单一数据源: StateVuex store中存储的所有组件共享的数据状态,官方定义: 将数据称为 State状态;

它提供了一个全局的、集中式的存储空间,使得任何组件都能访问到这些状态,从而实现状态的统一管理;

响应式:Vue的响应式系统使得当state中的数据发生变化时,所有依赖于这些数据的Vue组件能够自动更新;

这意味着你可以在组件中直接使用store中的状态,并且当状态改变时,视图会自动响应这些变化;

多组件使用Vuex:

案例:App.JS 主组件中引入,多个组件同时获取:Vuex 的数据进行展示; Son1.vue\Son2.vue

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son1 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
    </div>
</template>
<script></script>
<style></style>

获取Vuex数据: 通过$store访问的语法,可以直接在组件组件脚本.JSsrc/main.JS 快速访问;

代码语言:javascript
复制
//Vue模板中直接使用
{{ $store.state.xxx }}
//Vue模板.js文件中获取
this.$store.state.xxx
//src/main.JS 主文件中获取
import store from './store'
store.state.xxx;

辅助函数 mapState

mapState辅助函数:为了简化组件中对state的访问,

Vuex提供了mapState辅助函数,可以将store中的状态映射为组件的计算属性;

正常情况下,我们在组件中访问数据通过: {{ store.state.xxx }} 、this.store.state.xxx、...

实际使用过程有点麻烦,mapState函数,可以直接将 state-store状态数据 映射为一个计算属性直接访问: {{ xxx }}

  • mapState函数: mapState(['xxx','xxx']); 可以获取对应 store状态数据,赋值给 计算属性,方便快速访问;
代码语言:javascript
复制
<template>
  <div id="app">
    <h1>
      根组件
      - {{ title }}
      <!-- - {{ $store.state.title }} -->
    </h1>
    <p>store公共仓库获取数据: {{ count }}</p> <!-- {{  $store.state.count  }} -->
    <hr>
    <Son1></Son1>
    <Son2></Son2>
  </div>
</template>
<script>
  import Son1 from './components/Son1.vue';
  import Son2 from './components/Son2.vue';
  import { mapState } from 'vuex';          //通过ES6 语法对象解构直接获取mapState;
  export default { 
    name: 'App',
    components: { Son1, Son2, },
    created(){
      //created初始化钩子函数\查看$store\mapState对象属性;
      console.log("组件脚本中访问Vuex: "+this.$store.state.title);
      console.log("mapState['title']: "+mapState(['title']));
      console.log("mapState 对象属性: "+mapState);
    },
    //计算属性
    computed:{
      ...mapState(['title','count']),       //通过ES6 语法对象展开运算符,导出的状态映射给计算属性;
      //如果没有 ...mapState(['title','count']), 为了方便页面获取 $store.state 状态数据,通常需要自定义函数;
      diytitle(){ return this.$store.state.title; } //方便组件使用,$store.state 状态数据,当然计算函数支持更多自定义操作;
    }
   }
</script>
<style></style>

使用State的注意事项

禁止直接修改:

直接修改store中的state状态数据是被严格禁止的,

任何状态的改变都必须通过提交mutation来完成,以确保状态变更的可追踪性和一致性;

模块化状态: 在大型应用中,状态可能会非常复杂,因此可以将state分割到不同的模块中,

每个模块拥有自己的state,这有助于管理复杂的状态结构,后面介绍:Vuex模块化

状态修改mutations

在Vuex中,mutations是用于改变状态唯一合法方式,它遵循严格同步规则,确保状态变更的可预测性和调试的便利性

Vuex 遵循单向数据流,组件中不能直接修改仓库的数据: 但, 默认情况下并不会报错; 👇👇

代码语言:javascript
复制
<!-- Vuex store、state状态数据可以直接修改 -->
<template>
    <div class="box">
        <h2>Son1 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <button @click="$store.state.count++">值 + 1</button>  <!-- 错误写法但不会报错; -->
        <button @click="addcount2()">值 + 2</button>  <!-- 错误写法但不会报错; -->
    </div>
</template>
<script>
    export default { 
        //直接修改Vuex store、state状态数据
        methods:{ addcount2(){ this.$store.state.count+=2; } }
    }
</script>

Vuex 严格模式:

Vuex 的严格模式是一种开发时的辅助工具,它强制所有的状态变更必须通过 mutation 来进行:

这有助于维护状态的一致性,避免了状态的隐式修改,使得应用的行为更加可预测;

启用方式:在创建 Vuex store 实例时,通过设置 strict: true 启用严格模式:

代码语言:javascript
复制
const store = new Vuex.Store({
	strict: true
 	// ...store配置
});

mutatios 修改状态:

为什么可以直接修改,还要使用mutations:

Mutations是Vuex中实现状态变更的核心机制,它确保了状态的改变是有序的、可追踪的,并且遵循一定的规范:

  • 单一职责:将状态变更逻辑封装在mutations中,使得这部分代码更加模块化和易于测试;
  • 可追踪性:通过集中管理状态变更,使得开发者可以更容易地跟踪应用状态的变化历史; 特别是在使用Vue DevTools时,可以清晰地看到每次mutation对状态的影响;

使用:mutatios 修改state状态:

  • 在Vuex实例mutatios中定义=>处理函数: 这些函数必须是同步的,以确保状态变更的清晰和可追踪; 每一个处理函数对应一个状态数据,它接收两个参数:state(必须、状态数据)payload(可选、传递参数)
  • 在需要操作state状态数据,调用对应mutation处理并提交: this.$store.commit('处理函数名', 传递参数);
定义 mutations 事件函数

在Vuex的store配置中,定义mutations对象,其中: 键 =是=>事件类型(通常是大写命名)值=是=>处理函数

代码语言:javascript
复制
// 创建仓库 store 状态,即数据: 
// 类似于vue组件中的data、data 是组件自己的数据;
// state 中的数据整个vue项目的组件都能访问到;
const store = new Vuex.Store({
    //开启严格模式
    strict: true,
    state: {
        count: 10,
        title: "大标题1",
    },
    //mutations对象其中键是事件类型通常是大写命名)、值是处理函数;
    mutations:{
        //state: 表示当前Vuex中的state状态数据库,用来获取其操作数据;
        ADD_COUNT(state){ state.count++; },
        //带参传递数据: 参数只能一个,如果有多个参数,包装成一个{对象}\[数组] 传递;        
        ADD_COUNTX(state,payload){ state.count+=payload }
    }
})
使用 mutations 事件函数

在组件中通过,调用、提交:mutation处理函数,形式完成,状态修改: Son2.vue

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son2 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <button @click="addCount()">值 + 1</button>  <!-- mutatios修改state -->
        <button @click="addCountx(3)">值 + 3</button>  <!-- mutatios带 参? 修改state -->
        <button @click="addCountx(5)">值 + 5</button>  <!-- mutatios带 参? 修改state -->
    </div>
</template>
<script>
    export default {
        methods:{
            //无参自动+1
            addCount(){ this.$store.commit('ADD_COUNT'); },
            addCountx(x){ this.$store.commit('ADD_COUNTX',x); }     //自定义传参添加数值;
        }
    }
</script>

mapMutations-辅助函数

mapMutationsVuex提供的一个辅助函数,它简化了在Vue组件中提交mutation的过程:

这个辅助函数允许:store中的mutations映射到组件的methods中,

使得你可以直接在组件的方法中调用这些mutation

而不需要手动使用this.$store.commit

mapMutations 使用:

Son3.vue:mapState 用法类型,mapState 针对状态数据\使用计算属性进行优化,

mapMutations 针对状态数据修改操作\使用method 函数进行优化,自动将事件函数名,匹配生成一个method函数

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son3 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <button @click="addCount()">值 + 1</button>  <!-- mutatios修改state -->
        <button @click="addCountx(10)">值 + 10</button>  <!-- mutatios带 参? 修改state -->
        <button @click="ADD_COUNTX(-10)">值 - 10</button>  <!-- mutatios带 参? 修改state -->
    </div>
</template>
<script>
    import { mapMutations } from 'vuex';          //通过ES6 语法对象解构直接获取mapMutations;
    export default {
        methods:{
            //方式一: 直接映射名为increment的mutation
            ...mapMutations(['ADD_COUNT','ADD_COUNTX']),
            //方式二: 使用对象形式来映射并重命名
            ...mapMutations({
                'addCount' : "ADD_COUNT",      //组件方法名: store中的mutation名
                'addCountx' : "ADD_COUNTX",
            }),
        }
    }
</script>

注意: Vuex中mutations中不能写异步代码,如果有异步的ajax请求,应该放置在actions中;

异步操作action

在Vuex中,actions和mutations类似,是用于处理异步操作的关键部分:

它们允许你执行异步逻辑,比如API调用,并且最终通过触发一个或多个mutations来改变状态;

定义 actions 异步操作:

在Vuex的store配置中,定义actions对象: 虽然actions可以执行异步逻辑,但它们不能直接修改state

相反,它们通过调用context.commit来触发mutation,从而间接改变状态,也就是说:actions依赖mutation操作state;

代码语言:javascript
复制
// 创建仓库 store 状态,即数据: 
// 类似于vue组件中的data、data 是组件自己的数据;
// state 中的数据整个vue项目的组件都能访问到;
const store = new Vuex.Store({
    //开启严格模式
    strict: true,
    state: {
        count: 10,
        title: "大标题1",
    },
    //mutations对象其中键是事件类型通常是大写命名)、值是处理函数;
    mutations:{
        //state: 表示当前Vuex中的state状态数据库,用来获取其操作数据;
        ADD_COUNT(state){ state.count++; },
        //带参传递数据: 参数只能一个,如果有多个参数,包装成一个{对象}\[数组] 传递;        
        ADD_COUNTX(state,payload){ state.count+=payload }
    },
    //actions 处理异步: 注意,不能直接操作state 操作state 还是需要context.commit('mutation名','传参');
    actions:{
        //actions 接收参数: context对象提供了对store的访问、payload作为参数对象
        changeCountAction(context,num){ 
            // 这里是setTimeout模拟异步,以后大部分场景是发请求
            setTimeout(() => { context.commit('ADD_COUNTX', num) }, 1000) 
        }
    }
})

使用 actions 异步操作:

在Vue组件中,你可以通过this.$store.dispatch('actions名','参数对象')来触发action

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son3 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <button @click="addCount()">值 + 1</button>  <!-- mutatios修改state -->
        <button @click="addCountx(10)">值 + 10</button>  <!-- mutatios带 参? 修改state -->
        <button @click="ADD_COUNTX(-10)">值 - 10</button>  <!-- mutatios带 参? 修改state -->
        <button @click="changeCountAction(888)">1秒后改成888</button>   <!-- actions 异步操作state -->
    </div>
</template>
<script>
    import { mapMutations } from 'vuex';          //通过ES6 语法对象解构直接获取mapMutations;
    export default {
        methods:{
            //方式一: 直接映射名为increment的mutation
            //方式二: 使用对象形式来映射并重命名 	....省略....
            //在Vue组件中,你可以通过this.$store.dispatch来触发action:
            async changeCountAction(x){
                await this.$store.dispatch('changeCountAction',x);
            },
        }
    }
</script>

mapaction-辅助函数

mapActions是Vuex提供的一个辅助函数,和mapMutations 类似,

它允许你将store中的actions便捷地映射到Vue组件的methods中,从而简化组件内调用这些异步操作的流程;

代码语言:javascript
复制
//通过ES6 语法对象解构直接获取mapMutations...
import { mapMutations,mapActions } from 'vuex';   
export default {
    methods:{
        //mapActions 使用: 和mapMutations类似
        ...mapActions(['changeCountAction']),
        ...mapActions({
            "divChangeCountAction": "changeCountAction"
        }),
    }
}

getters 类计算属性:

Vuex 中的 getters 是用来从 store 的状态state中派生出一些状态的计算属性: 类似于组件中的 computed 计算属性;

  • 计算和过滤: getters 用于对 state 进行计算和过滤,生成新的数据视图; 有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters
  • 缓存机制: getters 的值会被缓存,只有当其依赖的 state 或其他 getters 发生变化时,才会重新计算;
  • 访问便捷: getters 可以通过 store.getters 访问,或者在 Vue 组件中通过 this.$store.getters 访问; 这使得多个组件可以共享这些计算后的数据,避免代码重复

getters 案例Demo

例如: state中定义了list的数组,组件中,需要显示所有大于>5的数;

代码语言:javascript
复制
// 创建仓库 store 状态,即数据: 
// 类似于vue组件中的data、data 是组件自己的数据;
// state 中的数据整个vue项目的组件都能访问到;
const store = new Vuex.Store({
    //开启严格模式
    strict: true,
    state: {
        count: 10,
        title: "大标题1",
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    },
    //getters 类似于计算属性,用来从 store.state 状态数据中派生出一些状态的计算属性;
    getters:{
        // state中定义了list的数组,需要显示所有大于>5的数;
        // 必须有返回值,返回值就是getters的值
        // 形参第一个参数,就是state
        filterList (state) { return state.list.filter(item => item > 5) }
    }
})

Son3组件中获取:getters数据: 通过 this.$store.getters 访问定义的 getters

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son3 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <div>getters过滤数据 {{ $store.getters.filterList }}</div>
    </div>
</template>

mapgetters-辅助函数

mapGetters 提供了一种高效、简洁的方式来访问 Vuex 中的 getters

减少了代码冗余,增强了组件的可读性和可维护性,是 Vue 应用中状态管理的重要工具之一

代码语言:javascript
复制
<template>
    <div class="box">
        <h2>Son3 子组件</h2>
        从vuex中获取的值: <label>{{  $store.state.count  }}</label>
        <div>getters过滤数据 {{ $store.getters.filterList }}</div>
        <div>mapGetters便携获取数据 {{ filterList }}</div>
    </div>
</template>
<script>
    //通过ES6 语法对象解构直接获取mapMutations...
    import { mapMutations,mapActions,mapGetters } from 'vuex';  
    export default {
        computed:{ ...mapGetters(['filterList']), },		//组件计算函数		
    }
</script>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Vuex 深入浅出超详细
    • 什么是Vuex🤔❓
      • 这是什么意思呢🤔❓
        • 创建\使用:Vuex
          • 自定义创建项目:
          • 安装Vuex 创建仓库:
          • 创建仓库 store/index.js
          • 导入main 挂载Vue实例
          • 在组件中访问状态数据
      • state状态:
        • 多组件使用Vuex:
          • 辅助函数 mapState
            • 使用State的注意事项
            • 状态修改mutations
              • Vuex 严格模式:
                • mutatios 修改状态:
                  • 定义 mutations 事件函数
                  • 使用 mutations 事件函数
                • mapMutations-辅助函数
                  • mapMutations 使用:
              • 异步操作action
                • 定义 actions 异步操作:
                  • 使用 actions 异步操作:
                    • mapaction-辅助函数
                    • getters 类计算属性:
                      • getters 案例Demo
                        • mapgetters-辅助函数
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档