vue3使用vuex的示例(模块化功能)

27 篇文章 1 订阅
4 篇文章 0 订阅

目录

1. store/index.ts

2. main.ts

3. App.vue调用

4. 如果删除moduleA的namespaced属性, 保留moduleB的namespaced:true

5. 则App.vue修改为:

6. 使用mapGetters和mapActions的情况:


1. store/index.ts

注意: 需要使用时带上模块名称的namespaced必须为true, 不写或者为false时调用时不需要写模块名称(获取state的值必须加模块名)

import { createStore } from "vuex";
// A模块
const moduleA = {
  namespaced: true,
  state: {
    name: "moduleA",
  },
  getters: {
    newName(state) {
      return state.name;
    },
  },
  mutations: {
    changeName(state, payload) {
      state.name = payload;
    },
    updateAge(state, playLoad) {
      state.age = playLoad;
    },
  },
  actions: {
    changeAge({ commit }, age) {
      setTimeout(() => {
        commit("updateAge", age);
      }, 0);
    },
  },
};
// B模块
const moduleB = {
  namespaced: true,
  state: {
    name: "moduleB",
    age: 33,
  },
  getters: {
    newName(state) {
      return state.name;
    },
  },
  mutations: {
    changeName(state, payload) {
      state.name = payload;
    },
    updateAge(state, playLoad) {
      console.log("playLoad", playLoad);
      state.age = playLoad;
    },
  },
  actions: {
    changeAge(ctx, count) {
      console.log("触发了-模块B的action");
      setTimeout(() => {
        ctx.commit("updateAge", count);
      }, 1000);
    },
  },
};
export default createStore({
  // 分模块
  modules: {
    moduleA,
    moduleB,
  },
});

2. main.ts

import { createApp } from "vue";
import App from "./App.vue";
import * as Vue from "vue";
import store from './store';

const app = createApp(App);
app.use(store);
app.mount("#app");

3. App.vue调用

<template>
  <div id="container">
    <!-- 1、使用A模块的state数据 -->
    <div>
      姓名: <input type="text" @change="changeAName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeAAge($event)">
    </div>
    <h1>模块a:</h1>
    <p>姓名(state): {{ store.state.moduleA.name }}</p>
    <!-- 2、使用A模块的getters数据 -->
    <p>姓名(getters): {{ store.getters["moduleA/newName"] }}</p>
    <p>年龄: {{ store.state.moduleA.age }}</p>

    <!-- 1、使用B模块的state数据 -->
    <h1>模块b:</h1>
    <div>
      姓名: <input type="text" @change="changeBName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeBAge($event)">
    </div>
    <p>姓名(state): {{ store.state.moduleB.name }}</p>
    <!-- 2、使用B模块的getters数据 $store.getters['模块名/计算属性']-->
    <p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
    <p>年龄: {{ store.state.moduleB.age }}</p>
  </div>
</template>
<script setup lang="ts">
import { useStore } from "vuex";

// userStore可以拿到vuex仓库实例
const store = useStore();

const changeAName = (e) => {
  store.commit('moduleA/changeName', e.target.value)
};
const changeAAge = (e) => {
  store.dispatch("moduleA/changeAge", e.target.value)
};


const changeBName = (e) => {
  // 提交B模块的更改
  store.commit('moduleB/changeName', e.target.value)
};
const changeBAge = (e) => {
  // 传参用法
  store.dispatch("moduleB/changeAge", e.target.value)
};
</script>
<style lang='scss' scoped></style>

4. 如果删除moduleA的namespaced属性, 保留moduleB的namespaced:true

import { createStore } from "vuex";
// A模块
const moduleA = {
  state: {
    name: "moduleA",
  },
  getters: {
    newName(state) {
      return state.name;
    },
  },
  mutations: {
    changeName(state, payload) {
      state.name = payload;
    },
    updateAge(state, playLoad) {
      state.age = playLoad;
    },
  },
  actions: {
    changeAge({ commit }, age) {
      setTimeout(() => {
        commit("updateAge", age);
      }, 0);
    },
  },
};
// B模块
const moduleB = {
  namespaced: true,
  state: {
    name: "moduleB",
    age: 33,
  },
  getters: {
    newName(state) {
      return state.name;
    },
  },
  mutations: {
    // 更改数据函数
    changeName(state, payload) {
      state.name = payload;
    },
    updateAge(state, playLoad) {
      console.log("playLoad", playLoad);
      state.age = playLoad;
    },
  },
  actions: {
    changeAge(ctx, count) {
      setTimeout(() => {
        ctx.commit("updateAge", count);
      }, 1000);
    },
  },
};
export default createStore({
  // 分模块
  modules: {
    moduleA,
    moduleB,
  },
});

5. 则App.vue修改为:

<template>
  <div id="container">
    <!-- 1、使用A模块的state数据 -->
    <div>
      姓名: <input type="text" @change="changeAName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeAAge($event)">
    </div>
    <h1>模块a:</h1>
    <p>姓名(state): {{ store.state.moduleA.name }}</p>
    <p>姓名(getters): {{ store.getters["newName"] }}</p>
    <p>年龄: {{ store.state.moduleA.age }}</p>

    <!-- 1、使用B模块的state数据 -->
    <h1>模块b:</h1>
    <div>
      姓名: <input type="text" @change="changeBName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeBAge($event)">
    </div>
    <p>姓名(state): {{ store.state.moduleB.name }}</p>
    <!-- 2、使用B模块的getters数据 $store.getters['模块名/计算属性']-->
    <p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
    <p>年龄: {{ store.state.moduleB.age }}</p>
  </div>
</template>
<script setup lang="ts">
import { useStore } from "vuex";

// userStore可以拿到vuex仓库实例
const store = useStore();

const changeAName = (e) => {
  store.commit('changeName', e.target.value)
};
const changeAAge = (e) => {
  store.dispatch("changeAge", e.target.value)
};



const changeBName = (e) => {
  store.commit('moduleB/changeName', e.target.value)
};
const changeBAge = (e) => {
  store.dispatch("moduleB/changeAge", e.target.value)
};
</script>
<style lang='scss' scoped></style>

6. 使用mapGetters和mapActions的情况:

store/vuexHelper.ts

原理: 使用bind改变this的指向, 且相当于() => fn, 所以可以使用computed钩子

import { computed } from "vue";

export const getStateOrGettersMap = (store, mappers) => {
  const obj = {};
  Object.keys(mappers).forEach((key) => {
    obj[key] = computed(mappers[key].bind({ $store: store })).value;
  });
  return obj;
};

export const formatterActionsMap = (store, actions) => {
  Object.keys(actions).forEach((fnKey) => {
    actions[fnKey] = actions[fnKey].bind({ $store: store });
  });
};

App.vue

<template>
  <div id="container">
    <!-- 1、使用A模块的state数据 -->
    <div>
      姓名: <input type="text" @change="changeAName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeAAge($event)">
    </div>
    <h1>模块a:</h1>
    <p>姓名(state): {{ store.state.moduleA.name }}</p>
    <p>姓名(getters): {{ store.getters["newName"] }}</p>
    <p>姓名(mapGetters): {{ mapAData.newName }}</p>
    <p>年龄: {{ store.state.moduleA.age }}</p>

    <!-- 1、使用B模块的state数据 -->
    <h1>模块b:</h1>
    <div>
      姓名: <input type="text" @change="changeBName($event)">
    </div>
    <div>
      年龄: <input type="number" @change="changeBAge($event)">
    </div>
    <p>姓名(state): {{ store.state.moduleB.name }}</p>
    <p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
    <p>姓名(mapGetters): {{ mapBData.newName }}</p>
    <p>年龄: {{ store.state.moduleB.age }}</p>
  </div>
</template>
<script setup lang="ts">
import { useStore, mapGetters, mapActions } from 'vuex';
import { computed } from 'vue'
import { getStateOrGettersMap, formatterActionsMap } from './store'

// userStore可以拿到vuex仓库实例
const store = useStore();

const changeAName = (e) => {
  store.commit('changeName', e.target.value)
};
const changeAAge = (e) => {
  store.dispatch("changeAge", e.target.value)
};
const aMappers = mapGetters(['newName'])
const mapAData = computed(() => getStateOrGettersMap(store, aMappers))

const changeBName = (e) => {
  // 提交B模块的更改
  store.commit('moduleB/changeName', e.target.value)
};
const changeBActions = mapActions('moduleB', ['changeAge'])
formatterActionsMap(store, changeBActions)
const changeBAge = (e) => {
  changeBActions.changeAge(e.target.value)
  // store.dispatch("moduleB/changeAge", e.target.value)
};

const bMappers = mapGetters('moduleB', ['newName'])
const mapBData = computed(() => getStateOrGettersMap(store, bMappers))
</script>
<style lang='scss' scoped></style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3中使用Vuex,你需要进行一些配置和使用方法上的改变。下面是使用Vuex的一般步骤: 1. 安装Vuex:在项目根目录下运行以下命令安装Vuex: ``` npm install vuex ``` 2. 创建store实例:在项目的src目录下创建一个新的文件夹,命名为store。在store文件夹中创建一个新的文件index.js,作为Vuex的入口文件。 3. 在index.js中导入VueVuex,并创建一个新的store实例: ```javascript import { createApp } from 'vue' import { createStore } from 'vuex' const store = createStore({ // 在这里定义你的状态、mutations、actions等 }) export default store ``` 4. 在main.js中引入store实例并将其挂载到Vue应用上: ```javascript import { createApp } from 'vue' import store from './store' const app = createApp(App) app.use(store) app.mount('#app') ``` 5. 在store文件夹中创建一个新的文件module.js,用于定义模块化的状态、mutations和actions。例如: ```javascript const state = { count: 0 } const mutations = { increment(state) { state.count++ } } const actions = { incrementAsync({ commit }) { setTimeout(() => { commit('increment') }, 1000) } } export default { state, mutations, actions } ``` 6. 在store/index.js中引入模块化的文件并注册到store实例中: ```javascript import { createStore } from 'vuex' import module from './module' const store = createStore({ modules: { module // 注册模块 } }) export default store ``` 现在你已经成功配置了Vuex,并可以在组件中使用它。你可以使用`$store`对象来访问状态、提交mutations和分发actions。例如,在组件中使用状态和提交mutation的示例: ```javascript export default { computed: { count() { return this.$store.state.module.count } }, methods: { increment() { this.$store.commit('increment') } } } ``` 这是一个简单的开始使用Vuex的例子,你可以根据你的具体需求来定义更多的状态、mutations和actions。请确保在使用之前阅读Vuex的文档以获取更多详细信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值