【前端面试题】状态管理工具——Vuex——任何组件之间的传值

一、Vuex的理解

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

二、使用场景

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

三、如何使用

1、state

state中数据的定义:

state.js

//state的存放方式
const state = {
    
    
    items: []
}
export default state;

state中数据的读取:

Shop.vue

1)$store.state.xx
<h2>{ { $store.state.items }}</h2>

2)使用mapState转化为computed属性
<h2>{ { items }}</h2>
import { mapState } from "vuex";computed: mapState(["items"])

2、getters(计算属性)

getters计算属性的定义

getters.js

扫描二维码关注公众号,回复: 13738799 查看本文章
//返回state中items的内容
export const items = function (state) {
    
    
    return state.items
}
//state.items的长度
export const sum = function (state) {
    
    
    return state.items.length
}

getters计算属性的使用

Shop.vue

1)$store.getters.xx
<h2>state中items:{ { $store.getters.items }}</h2>

2)mapGetters
<h2>state中items的长度:{ { sum }}</h2>
computed: { ...mapGetters(["sum"]), },

3、mutations

mutations方法的定义

小技巧:可以创建mutation-types.js来定义mutations中的方法名

/*mutation-types.js*/
export const FUN1 = 'FUN1'
export const FUN2 = 'FUN2'
/*mutations.js*/
import * as types from './mutation-types'

const mutations = {
    
    
    //新增
    [types.FUN1](state, arg) {
    
    
        state.items.push({
    
    
            id: arg.id,
            title: arg.title,
            price: arg.price,
            num: 1,
        })
    },

    //如果重复,只增加数量
    [types.FUN2](state, arg) {
    
    
        const cartItem = state.items.find(item => item.id === arg.id);
        cartItem.num++;
    }
}

export default mutations;

mutations方法的使用(在method中使用)

  1. this.$store.commit("xxx");
  2. ...mapMutations({ fun1: "FUN1", }),

Shop.vue

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.id">
        <h3>{
   
   { item.title }}</h3>
        <button @click="fun1(item)">添加到购物车</button>
      </li>
    </ul>
    <h2>state中items:{
   
   { $store.getters.items }}</h2>
    <h2>state中items的长度:{
   
   { sum }}</h2>
  </div>
</template>

<script>
import {
      
       mapGetters, mapMutations } from "vuex";
export default {
      
      
  data() {
      
      
    return {
      
      
      list: [
        {
      
      
          id: 1,
          title: "物品1",
        },
      ],
    };
  },
  computed: {
      
      
    ...mapGetters(["sum", "items"]),
  },
  methods: {
      
      
    add(item) {
      
      
      this.$store.commit("FUN1", item);
    },
    ...mapMutations({
      
      
      fun1: "FUN1",
    }),
  },
};
</script>

<style>
li {
      
      
  list-style: none;
}
</style>

在这里插入图片描述
这里无法实现重复对象数量加1的效果,需要使用actions
一条重要的原则就是要记住 mutation 必须是同步函数!!!

4、actions

actions定义

/*actions.js*/
import * as types from './mutation-types'

export const addToCart = function ({
     
      commit, state }, arg) {
    
    
    const cartItem = state.items.find(item => item.id === arg.id);
    if (!cartItem) {
    
    
        commit(types.FUN1, {
    
     id: arg.id, title: arg.title })
    } else {
    
    
        commit(types.FUN2, cartItem)
    }
}

actions的使用(在method中使用)

  1. this.$store.dispatch("xx", );
  2. ...mapActions({ fun1: "addToCart", }),
<!--Shop.vue-->
<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.id">
        <h3>{
   
   { item.title }}</h3>
        <button @click="fun1(item)">添加到购物车</button>
      </li>
    </ul>
    <h2>state中items:{
   
   { $store.getters.items }}</h2>
    <h2>state中items的长度:{
   
   { sum }}</h2>
  </div>
</template>

<script>
import {
      
       mapGetters, mapActions } from "vuex";
export default {
      
      
  data() {
      
      
    return {
      
      
      list: [
        {
      
      
          id: 1,
          title: "物品1",
        },
        {
      
      
          id: 2,
          title: "物品2",
        },
      ],
    };
  },
  computed: {
      
      
    ...mapGetters(["sum", "items"]),
  },
  methods: {
      
      
    add(item) {
      
      
      this.$store.commit("FUN1", item);
    },
    // ...mapMutations({
      
      
    //   fun1: "FUN1",
    // }),
    ...mapActions({
      
      
      fun1: "addToCart",
    }),
  },
};
</script>

<style>
li {
      
      
  list-style: none;
}
</style>

在这里插入图片描述

以上就是状态管理工具——Vuex——任何组件之间的传值,关注《前端面试题》专栏。
我会将自己平时项目中常见的问题以及笔试面试的知识在CSDN与大家分享,一起进步,加油。

猜你喜欢

转载自blog.csdn.net/weixin_46318413/article/details/122848321
今日推荐