Vuex的使用

Vuex

  1. 父组件向子组件传值 props

  2. 子组件向父组件传值 $emit

  3. 非父子组件之间传值:爷孙、兄弟

基于Vue实现发布订阅者模式(代码比较乱,不建议使用)

// 中介
const event = new Vue();
// 订阅事件
event.$on('event-b', (param) => {
    console.log(param);  // 666
});
// 发布事件
event.$emit('event-b', 666)

所以,Vuex状态管理的存在是十分有必要性

Vuex是一个专为Vue.js应用的程序开发的状态管理模式。采用集中式存储应用(统一管理,存储/变更)的所有组件的状态,非常方便地进行复杂组件之间的数据传递(非父子关系)。

  • state 管理组件数据,管理的数据是响应式的,当数据改变时驱动试图更新
  • mutations 更新数据,state中的数据只能使用mutation去改变数据(只能处理同步的场景)
  • actions 处理异步场景,处理成功后把数据提交给mutations,进而更新state
  • getters 相当于在state和组件之间添加一个环节(对state中的数据进行加工处理后再 提供给组件),不直接修改state中的数据

初始化项目

基于脚手架初始化项目,(1)初始化store对象(2)把store对象挂载到Vue实例中

  1. npm i Vuex --save/-S
  2. 将Vuex挂载到main.js中
import store from './Vuex'
new Vue({
    // 把store对象挂载到Vue实例对象中,这样就可以在所有的组件中获取store中的数据了
    store,
    render: h => h(App),
}).$mount('#app')
  1. 在实际项目中,为方便管理,将Vuex文件拆分成这样

在这里插入图片描述

除index.js(为主)的文件,其他文件只需要export default导出相应的字段(变量);

而index.js内容:

"use strict";
import state from "./state"
import getters from "./getter"
import mutations from "./mutation"
import actions from "./action"
import Vue from 'vue'
import Vuex from "vuex"

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
});

状态state

  1. 管理数据
// 因为之前拆分,可直接使用let\const 来定义变量
// state中的数据是自定义的,但是state属性名是固定的
let userName = '乐知者',
const sex = '1',
export default {
    userName,
    sex
}
  1. 组件中获取 state 中的数据,使用原始用法 插值表达式
<div> 第一组件 state的数据: {{$store.state.userName}}</div>
<div> 第二组件 state的数据: {{userName}}</div>
  1. 使用计算属性中 使用方法
computed: {
    // 把state中的数据,定义在组件内的计算属性中
    userName () {
        return this.$store.state.userName
    }
}

mapState

简化获取store数据的代码

  1. 把vuex中的state数据映射到组件的计算属性中

import { mapState } from 'vuex'

  1. 使用mapState(对象)
// 使用mapState来生成计算属性,mapState函数返回值是对象
// 使用mapState使用 对象 传参
computed: mapState({
    // 1.基础写法(state)代表就是vuex申明的state
    userName: function(state) {
        return state.userName
    }
    // 2.使用箭头函数
    userName: state => state.userName
    // 3.vuex提供写法(userName是state中的字段名称)
    userName: 'userName'
    // 4.当你的计算属性 需要依赖vuex中的数据 同时 依赖组件中data的数据
    uerName(state) {
    	return state.userName + this.num
	}
})
  1. 使用:mapState(数组)
// mapState参数是一个数组
computed: mapState(['userName', 'total'])
  1. 如果组件自己有计算属性,state的字段映射成计算属性
computed: {
    // 组件其他计算属性
    sum() {
     return this.num + 1;   
    }
    // 把mapState返回值那个对象进行展开操作(把对象的属性添加到该位置)
    ...mapState(['userName'])
}

状态修改mutations

为了统一管理数据,便于监控数据变化,Vuex规定必须通过mutation修改数据,不可以直接通过store修改状态数据

// mutations是固定的,同于定义修改数据的动作(函数)
mutations: {
    // 定义一个mutation,age相加参数的方法
    increment (state, payload) {
        // state表示store中所有数据
        // payload表示组件中传递过来的数据
		state.age = state.age + payload
    }
}

组件中调用

methods: {
    handClick () {
        // 通过触发mutation修改state中的age的值
        this.$store.commit('increment', 2)
    }
}

需要先定义mutations,再 this.$store.commit(‘mutations的名称’, ‘参数’)

mapMutations

把vuex中的mutations的函数映射到组件methods中(通过mapMutations函数可以生成methods中函数)

methods: {
    // 1.对象参数写法
    ...mapMutations({
        // 冒号右侧的increment是mutations的名称
        // 冒号左侧的increment是事件函数的名称,可以自定义
        increment: 'increment'
    })
    // 2.数组参数的写法(事件函数名称和mutation名称一致)
    ...mapMutations(['increment'])
    // 3.与第二种等效
    increment (param) {
        // 点击触发该函数后要再次触发mutation的
        this.$store.commit('increment', param)
    }
}

异步操作action

异步任务,获取数据,一般axios请求数据是经典例子

  1. 安装axios的包
npm i axios
// 导入包
import axios from 'axios';
  1. 定义获取数据方法
// action是固定的,用于定义异步操作的动作(函数)
action: {
    // 定义一个action,用于查询接口
    async getData (context, payload) {
        const res = await axios.get('url')
        // 必须触发mutation修改res的值
        // context类似于this.$store
        context.commit('updateList', res.data.list)
    }
},
mutations: {
    updateList (state, payload) {
        state.list = payload
    }
}
  1. 组件使用
methods: {
    handleQuery () {
        // 触发action 必须嗲用dispatch方法
        this.$store,dispatch('queryData', 111)
    }
}

mapActions

mapActions辅助函数,把actions中的函数映射组件methods中(通过mapActions函数可以生成methods中函数)

...mapActions({
    fn: 'queryData'
})
// 相当于methods申明一个函数 getData(num) { this.$store.dispatch('getData', num) }
...mapActions(['queryData'])

getters用法

// 相当于state的计算属性(基于State处理成另外一份数据)
// getters的主要应用场景:模板中需要的数据和State中的数据不完全一样
getters: {
    getPartList (state) {
        return state.list.filter(item => {
            return item.id > 1;
        })
    }
}

用法

caleList () {
    // 获取getters的值,不需要加括号(当属性使用)
    return this.$store.getters.getPartList
}
// 简化用法
// mapGetters:把getters映射为计算属性
import { mapGetters } from 'vuex';
computed: {
    ...mapGetters(['getPartList'])
}
### Vuex 使用指南及实现状态管理示例 Vuex 是一个专为 Vue.js 应用设计的状态管理库,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化[^1]。以下是关于 Vuex 的核心概念和使用方法的详细说明。 #### 1. 核心概念 Vuex 的核心概念包括以下几个部分: - **State**:用于存储共享的状态数据。 - **Getter**:类似于 Vue 组件中的计算属性,用于从 state 中派生出一些状态。 - **Mutation**:用于同步地修改 state 的方法。 - **Action**:类似于 mutation,但可以包含异步操作,最终会提交 mutation 来改变 state。 - **Module**:将 store 分割成模块,使代码更易于维护。 #### 2. 创建 Vuex Store 在项目中创建一个 `store.js` 文件,定义 Vuex 的 store: ```javascript // store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { count: 0 // 示例状态 }, getters: { doubleCount(state) { return state.count * 2; // 计算属性示例 } }, mutations: { increment(state) { state.count++; // 同步修改状态 } }, actions: { incrementAsync({ commit }) { setTimeout(() => { commit('increment'); // 异步操作后提交 mutation }, 1000); } } }); ``` #### 3.Vue 实例中引入 Store 在 `main.js` 文件中引入并挂载 store: ```javascript // main.js import Vue from 'vue'; import App from './App.vue'; import store from './store'; new Vue({ store, // 挂载 store render: h => h(App) }).$mount('#app'); ``` #### 4. 在组件中使用 Vuex 通过 `mapState`、`mapGetters`、`mapMutations` 和 `mapActions` 辅助函数简化对 Vuex 的访问: ```javascript <template> <div> <p>Count: {{ count }}</p> <p>Double Count: {{ doubleCount }}</p> <button @click="increment">Increment</button> <button @click="incrementAsync">Increment Async</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'; export default { computed: { ...mapState(['count']), // 映射 state 到本地计算属性 ...mapGetters(['doubleCount']) // 映射 getter 到本地计算属性 }, methods: { ...mapMutations(['increment']), // 映射 mutation 到本地方法 ...mapActions(['incrementAsync']) // 映射 action 到本地方法 } }; </script> ``` #### 5. 状态持久化 未进行持久化配置可能导致状态丢失、数据不一致或重复操作等问题[^3]。可以通过插件如 `vuex-persistedstate` 实现状态持久化: ```javascript // store.js import createPersistedState from 'vuex-persistedstate'; export default new Vuex.Store({ state: { count: 0 }, plugins: [createPersistedState()] // 添加持久化插件 }); ``` 这样,即使页面刷新,状态也会被保存到 localStorage 或 sessionStorage 中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@乐知者@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值