vue3组件之间通信(七)——Vuex在实际项目中的使用


vuex官网地址

1:基本使用

(1)安装

(1):npm

npm install vuex@next --save

2: yarn

yarn add vuex@next --save

安装成功后版本号应该是vuex: 4.0.2

(2):新建store文件夹

说明:module就是实际项目中为了更好的区分模块做到一个分割,里面新建了一个test的文件,里面会有state、mutation、action、getter四个核心模块,加上原本的module也就是vuex的五大核心模块。具体了解为什么使用module,请点击vuex官网module查看详细说明
在这里插入图片描述

src/store/index.ts

import { createStore } from "vuex";
import test from "./modules/test.ts";
export default createStore({
  modules: {
    test,
  },
});

src/store/modules/test.ts

//示例
// state 仓库
const state = {
  count: 0,
};

// getters  计算属性
const getters = {};

// actions 异步
const actions = {};

// mutations 同步
const mutations = {};

export default {
  state,
  getters,
  actions,
  mutations,
};

(3):注册(main.ts)
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index.ts' // 这个的路径要根据你自己写的位置
const app = createApp(App)
app.use(store).mount('#app');
(4):基本使用(获取state里面的值)

src/views/myHeader.vue

<template>
  <div class="myHeader">>
    <h1>值:{{ store.state.test.count }}</h1>
  </div>
</template>

<script setup>
import { useStore } from "vuex";
const store = useStore();
</script>
<style scoped>
.myHeader {
  width: 600px;
  height: 200px;
  border: 2px solid red;
  margin: 0 auto;
}
</style>
(5):效果

在这里插入图片描述

2:核心使用

说明:用一个例子来讲解vuex的核心使用, 一个myHeader.vue用来做计算,有+1,-1,等一下加1,值大10倍,四个方法。

(1):获取值(实际项目中获取值)

思考一:在前面我有说到使用store.state.test.count来获取一个值,但是如果有多个值呢?每一个都要加上store.state.test这一串吗?一般人可能想到了使用结构赋值,例如\src\store\modules\test.ts中state中有以下数据

// state 仓库
const state = {
  count: 0,
  schoolName: "张三学校",
  schoolSubject: "前端",
};

注意点1:在你使用结构赋值后,想到结构赋值会失去响应式,这样即使你改变了值也没有效果。所以需要将值使用toRefs包裹起来就可以了

// myHeader.vue
const { count, schoolName, schoolSubject} = toRefs(
  store.state.test
);

(2):Mutation的使用-——同步(使用加1,减1两个方法说明)

1:代码

// myHeader.vue页面
<template>
  <div class="myHeader">
    <p>myHeader页面</p>
    <p>值:{{ count }}</p>
    <p style="color: red">学校名称:{{ schoolName }}</p>
    <p style="color: red">学校科目:{{ schoolSubject }}</p>
    <a-button @click="clickAdd()">+</a-button>
    <a-button @click="clickReduce()">-</a-button>
  </div>
</template>

<script setup>
import { toRefs } from "@vue/reactivity";
import { useStore, mapState, mapGetters, mapMutations, mapActions } from "vuex";

const store = useStore();
const { count, schoolName, schoolSubject} = toRefs(
  store.state.test
);
// 加1方法
function clickAdd() {
  store.commit("JIA");
}
// 减1方法
function clickReduce() {
  store.commit("JIAN");
}
</script>

<style scoped>
.myHeader {
  width: 600px;
  height: 300px;
  border: 2px solid red;
  margin: 0 auto;
}
</style>
// /str/store/modules/test.ts
// mutations 同步
const mutations = {
  /**
   *
   * @param state 必填 存储的仓库数据
   * @param value 非必填  vue页面调用方法的参数
   */
  JIA(state) {
    state.count = state.count + 1;
  },
  JIAN(state) {
    state.count = state.count - 1;
  },
};

2:说明
在这里插入图片描述
注意点2:第二步的方法中store.commit(‘方法名’,参数),第三步的方法名,第二个就是第二步传过来的参数

(3):Action的使用——异步(使用等一会加方法模拟请求后获取数据的情况)

1:代码

// myHeader.vue页面
<template>
  <div class="myHeader">
    <p>myHeader页面</p>
    <p>值:{{ count }}</p>
    <a-button @click="clickSetTimeoutAdd()">等一会加</a-button>
  </div>
</template>

<script setup>
import { toRefs } from "@vue/reactivity";
import { useStore, mapState, mapGetters, mapMutations, mapActions } from "vuex";

const store = useStore();
const { count, schoolName, schoolSubject} = toRefs(
  store.state.test
);
// 等一会加方法
function clickSetTimeoutAdd() {
  store.dispatch("jia2");
}
</script>
// /str/store/modules/test.ts
// actions 异步
const actions = {
  jia2(content, value) {
    setTimeout(() => {
      content.commit("JIA", value);
    }, 1000);
  },
};

2:说明
在这里插入图片描述
注意点3:
(1)首先让外面看看vuex官网的vuex状态更改的流程图(主要讲解以下红框部分)
在这里插入图片描述

(2)简单说明:vc通过dispatch进入action,调用方法commit进入mutations,那么我在说明mutations的时候为什么直接跳过了dispatch进入action呢?举个简单例子,客人去饭店吃饭,先找服务员点餐(action),服务员找厨师说做这个(mutations),但是,客人如果经常来饭店,是不是可以直接和厨师说我要吃xxx,这就是看实际开发中需不需要尽力这一步,而这异步就是看你是否需要异步操作决定的。

(4):Getter的使用——计算属性(通过页面显示的值放大十倍的方法来讲解)

1:代码

// myHeader.vue页面
<template>
  <div class="myHeader">
    <p>myHeader页面</p>
    <p>值:{{ count }}</p>
    <p>值大10倍:{{ bigSum() }}</p>
  </div>
</template>

<script setup>
import { toRefs } from "@vue/reactivity";
import { useStore, mapState, mapGetters, mapMutations, mapActions } from "vuex";

const store = useStore();
const { count, schoolName, schoolSubject} = toRefs(
  store.state.test
);
// 值大10倍方法
function bigSum() {
  return store.getters.bigSum;
}
</script>
// /str/store/modules/test.ts
// getters  计算属性
const getters = {
  bigSum(state) {
    console.log("getters", state);
    return state.count * 10;
  },
};

2:说明
在这里插入图片描述

(5):最后附上完整代码

(1) src\store\index.ts

import { createStore } from "vuex";
import test from "./modules/test.ts";
export default createStore({
  modules: {
    test,
  },
});

(2)src\store\modules\test.ts

//示例
// state 仓库
const state = {
  count: 0,
  schoolName: "张三学校",
  schoolSubject: "前端",
  personlist: [
    {
      id: "001",
      name: "张三",
      age: 18,
    },
    {
      id: "002",
      name: "李四",
      age: 19,
    },
    {
      id: "003",
      name: "王五",
      age: 20,
    },
  ],
};

// getters  计算属性
const getters = {
  bigSum(state) {
    console.log("getters", state);
    return state.count * 10;
  },
};

// actions 异步
const actions = {
  jia2(content, value) {
    setTimeout(() => {
      content.commit("JIA", value);
    }, 1000);
  },
};

// mutations 同步
const mutations = {
  /**
   *
   * @param state 必填 存储的仓库数据
   * @param value 非必填  vue页面调用方法的参数
   */
  JIA(state) {
    state.count = state.count + 1;
  },
  JIAN(state) {
    state.count = state.count - 1;
  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};

(3)myHeader.vue

<template>
  <div>
    <h1>求和:{{ sum }}</h1>
    <h1>求和的值大10倍:{{ bigSum }}</h1>
    <h1>学校名称:{{ schoolName }}</h1>
    <h1>学校科目:{{ schoolSubject }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="add1(n)">+</button>
    <button @click="deSum(n)">-</button>
    <button @click="addSum2(n)">奇数相加</button>
    <button @click="addSum3(n)">等一会加</button>
    <hr />
    <son
      :clickFatherone="clickFatherone()"
      @clickFathertwo="clickFathertwo()"
    />
  </div>
</template>

<script>
// import nanoid from  'nanoid'
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
import son from "./son.vue";
export default {
  props: ["addTodo"],
  components: {
    son,
  },
  data() {
    return {
      // sum: 0,
      n: 1,
    };
  },
  computed: {
    // 方法1:页面渲染vuex数据
    // sum(){
    //     return this.$store.state.sum
    // },
    // schoolName(){
    //     return this.$store.state.schoolName
    // },
    // schoolSubject(){
    //     return this.$store.state.schoolSubject
    // },
    // bigSum(){
    //     return this.$store.getters.bigSum
    // },
    /**
     * 第二种方法,vuex提供的四个map方法  第一个是数据名,第二个是仓库(store)里面的数据名
     */
    // ...mapState({sum:'sum',schoolName:'schoolName',schoolSubject:'schoolSubject'}),
    // ...mapGetters({bigSum:'bigSum'}),

    /**
     * 第三种方法,在第二种的上面(数据名和仓库名一样)使用简写
     * 注意:是字符串的
     */
    ...mapState(["sum", "schoolName", "schoolSubject", "personlist"]),
    ...mapGetters(["bigSum"]),
  },
  methods: {
    // 第一种方法:同数据
    // add1() {
    //     // this.sum += this.n;
    //     this.$store.commit('JIA',this.n)
    // },
    // deSum() {
    //     // this.sum -= this.n;
    //     this.$store.commit('JIAN',this.n)
    // },
    // addSum2() {
    //     this.$store.dispatch('addSum2',this.n)

    // },
    // addSum3() {
    //     this.$store.dispatch('addSum3',this.n)
    // },
    // 第二种方法,
    ...mapMutations({ add1: "JIA", deSum: "JIAN" }),
    ...mapActions({ addSum2: "addSum2", addSum3: "addSum3" }),
    // 第三种方法,使用数据简写,同上
    clickFatherone(params) {
      console.log("父组件的方法被触发了one", params);
    },
    clickFathertwo(params) {
      console.log("父组件的方法被触发了two", params);
    },
  },
  mounted() {
    console.log("header", this);
  },
};
</script>

<style scoped></style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值