vuex的使用

Vuex 是 Vue.js 的状态管理工具,适用于多个组件共享数据的情况。可以理解为:“一个全局的数据仓库”,所有组件都可以从这里取数据或者改数据,而不用层层传值。

 

1. Vuex 的 5 个核心概念

名称作用例子
state存储数据state.count = 0
getters计算属性getters.doubleCount -> state.count * 2
mutations同步 修改数据mutation: state.count++
actions异步 修改数据action: setTimeout(() => commit('increment'), 1000)
modules拆分模块modules: { user, cart }

2. 代码示例

(1) 安装 Vuex

Vue 2

npm install vuex@3

 Vue 3

npm install vuex@4

(2) 创建 Vuex 仓库

创建 store/index.js

import Vue from 'vue';  // Vue 2
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    asyncIncrement({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

(3) 在 main.js 引入 Vuex

import Vue from 'vue';
import store from './store';

new Vue({
  store, // 挂载 Vuex
  render: h => h(App)
}).$mount('#app');

(4) 在组件中使用 Vuex

Counter.vue 组件:

<template>
  <div>
    <p>当前计数:{{ count }}</p>
    <p>两倍计数:{{ doubleCount }}</p>
    <button @click="increment">加 1</button>
    <button @click="asyncIncrement">1 秒后加 1</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';

export default {
  computed: {
    ...mapState(['count']), // 映射 state.count
    ...mapGetters(['doubleCount']) // 映射 getters
  },
  methods: {
    ...mapMutations(['increment']), // 直接调用 mutation
    ...mapActions(['asyncIncrement']) // 调用 action
  }
};
</script>

3. Vuex 的工作流程

  1. state 存数据(全局)
  2. 组件 mapState 取数据
  3. 组件 mapMutations 调用 mutation 同步修改数据
  4. 组件 mapActions 调用 action 异步修改数据
  5. getters 计算属性,自动计算

4. 进阶:Vuex 的 modules(模块化)

如果项目很大,可以把 Vuex 拆成多个模块。

创建 store/modules/user.js

export default {
  state: {
    name: '张三'
  },
  mutations: {
    setName(state, newName) {
      state.name = newName;
    }
  },
  actions: {
    asyncChangeName({ commit }) {
      setTimeout(() => {
        commit('setName', '李四');
      }, 1000);
    }
  },
  getters: {
    upperName: state => state.name.toUpperCase()
  }
};

然后,在 store/index.js 注册:

import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    user
  }
});

组件中使用:

<template>
  <div>
    <p>用户名:{{ name }}</p>
    <p>大写用户名:{{ upperName }}</p>
    <button @click="setName('王五')">改名</button>
    <button @click="asyncChangeName">1 秒后改名</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';

export default {
  computed: {
    ...mapState('user', ['name']),
    ...mapGetters('user', ['upperName'])
  },
  methods: {
    ...mapMutations('user', ['setName']),
    ...mapActions('user', ['asyncChangeName'])
  }
};
</script>

5. Vuex 与 Pinia

Vuex 在 Vue 3 之后,官方推荐使用 Pinia 替代 Vuex:

  • Vuex 代码复杂,需要 mutationsactions
  • Pinia 更简单,直接 state + actions
  • Pinia 支持 TypeScript

如果你的项目是 Vue 3,可以考虑使用 Pinia,使用方式类似 Vuex。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值