vuex的学习历程

序言:在vue学习中,其实一直有一块功能不太明白,那就是vuex,我刚开始对它的理解是:可以储存数据,供全局使用。可是在之前没用vue的时候,如果想实现这种功能,我是使用localStorage。所以我得先弄明白,vuex和localStorage之间的区别。

一、vuex和localStorage的区别

好吧,虽然是讲解两者之间的区别,但我就还是先简单介绍下这两者到底是什么

1.vuex是什么

 vuex官方解释

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

我们组件传值会用到:父子传值,兄弟组件传值...但要是对于多层嵌套的就比较麻烦了。这时可以使用vuex,把组件共享的状态提取出来,把共享的数据函数放在vuex,全局使用,任何组件都能共同它

2.localStorage是什么

localStorage作为HTML5 Web Storage的API之一,主要作用是本地存储。本地存储是指将数据按照键值对的方式保存在客户端计算机中,直到用户或者脚本主动清除数据,否则该数据会一直存在。也就是说,使用了本地存储的数据将被持久化。

ok,了解的它们的定义后,我们来讨论下,它们的区别

3.区别

1.vuex的数据是存储在内存中的,页面刷新就会丢失;localStorage是储存在计算机本地的,刷新不会消失

2.重点:vuex是用于组件之间传值(响应性的),localStorage是主要用在不同页面传值(其他页面更新数据了,当前页面得刷新才能更新对应数据,非响应式的

这两点是最重要的区别,如果数据不变的话,localStorage是可以代替vuex,但是你想实现响应式的效果,一个组件中的数据改变,另一个组件也要响应改变,那么你就需要使用vuex。

状态管理设计的目的并不是用于做缓存,而是用来作为唯一数据源,同步状态,共享状态。

针对第一点,vuex刷新丢失的问题,常用的方式就是将vuex中的数据保存在localStorage里,两者结合

二、vuex的使用

注意点:

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

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

使用:

store文件夹下的index.js的文件中

import Vue from "vue";
import Vuex from "vuex";
 
Vue.use(Vuex);
 
export default new Vuex.Store({

  state: {
    oneComNumber: 10,
  },
 
  // Action支持异步调用Mutation来修改。  处理一些逻辑业务
  actions: {
    numberAddWait(context, v) {   // 上下文和传过来的值
      setTimeout(() => {
        context.commit("numberAdd", v)

      }, 1000);
    },
  },
 
  // 用于操作一些数据 (state)  也可进行判断
  mutations: {
    numberAdd(state, v) {
      // if (state.oneComNumber % 2) {
      //     console.log(4546546546);
      // }
      state.oneComNumber += v
    },
    numberMinus(state, v) {   // 上下文和传过来的值
      state.oneComNumber -= v
    },
 
 
  },
  // 计算属性 辅助函数
  getters: {
    bigOneComNumber(state) {
      return state.oneComNumber * 10
    }
  },
});

store实例中读取状态的最简单方法是在计算属性中返回:

  computed: {
    oneComNumber() {
      return this.$store.state.oneComNumber;
    },
  },

但是当一个组件需要获取多个状态的时候,要是都这样声明就会显得重复和冗余。所以可以使用mapState辅助函数来帮助我们生成计算属性

import { mapState } from "vuex";  // 需要引入
export default {
  name: "HelloWorld",
  props: {
    
  },
  data() {
    return {};
  },
  created() {
    console.log(this.$store);
  },
  computed: {
    // oneComNumber() {
    //   return this.$store.state.oneComNumber;
    // },
 
    // 这里是数组形式获取 用于方法名和属性名一样的时候
    ...mapState(["oneComNumber"]), // 展开运算符写入即可
 
    // 这里是对象形式获取 用于方法名和属性名一样的时候
    // ...mapState({'oneComNumber':'oneComNumber'}), // 展开运算符写入即可
  },
};

Action

Action 类似于 mutation,不同在于:

        1.Action 提交的是 mutation,而不是直接变更状态。

        2.Action 可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters 。

  // Action支持异步调用Mutation来修改。  处理一些逻辑业务
  actions: {
    // 这里 就是等一段时间去执行 
    numberAddWait(context, v) {   // 上下文和传过来的值
      setTimeout(() => {
          context.commit("numberAdd", v)
      }, 1000); 
    },
  },

在页面调用时可以直接调用:$store.dispatch('方法名称', 传递的参数)

<button @click="$store.dispatch('numberAddWait', n)">过一会再加</button>

使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用

import { mapActions } from "vuex";
 
export default {
 
  methods: {
    ...mapActions(["numberAddWait"]),
  },
 
};

调用

<button @click="numberAddWait(n)">过一会再加</button>

Mutation

        更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。

  // 用于操作一些数据 (state)  也可进行判断
  mutations: {
    numberAdd(state, v) {
      state.oneComNumber += v
    },
    numberMinus(state, v) {   // 上下文和传过来的值
      state.oneComNumber -= v
    },
  },

直接调用 通过$store.commit('方法名',参数)调用

 <button @click="$store.commit('numberAdd', n)">+</button>
 <button @click="$store.commit('numberMinus', n)">-</button>

使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用

 <button @click="numberAdd(n)">+</button>
 <button @click="numberMinus(n)">-</button>
 
 
methods: {
    // 与上面Actions mapActions用法一致 也有对象传值方法
    ...mapMutations(["numberAdd", "numberMinus"]),
},

可以看出这边和上面actions mapActions用法类似,但是直接调用的时候不一样,注意一下

actions直接调用是:$store.dispatch('方法名', 参数)

mutation直接调用是:$store.commit('方法名',参数)

Getter

        有时候我们需要从 store 中的 state 中派生出一些状态,例如数据进行加工处理 例如放大倍数:这个时候可以在computed里面写计算属性,但是为了方便管理 Vuex提供了‘getter’

  // 计算属性 辅助函数
  getters: {
    bigOneComNumber(state) {
      return state.oneComNumber * 10
    }
  },

直接调用 进行显示

<h2>{{ $store.getters.bigOneComNumber }}</h2>

使用mapGetters 辅助函数

 <h2>{{ bigOneComNumber }}</h2>
 
 computed: {
   ...mapGetters(["bigOneComNumber"]),
 },

Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 主要用于多个文件/多个store,单个文件添加命名空间进行区别

namespaced: true,

在项目中,如果需要用到Vuex,可以将 store 分割成多个模块(module),每个模块拥有自己的 state、mutation、action、getter,这样你的模块具有更高的封装度和复用性,此时就用到了命名空间这个概念。( 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的,这样使得多个模块能够对同一 mutation 或 action 作出响应。)

例如,新建文件oneCom.js

export default {
    namespaced: true, // 空间命名
    state: {
        oneComNumber: 10,
        peoppleList: [
            {
                id: 1,
                name: "张三"
            }
        ],
    },
 
    // Action支持异步调用Mutation来修改。  处理一些逻辑业务
    actions: {
        numberAddWait(context, v) {   // 上下文和传过来的值
            setTimeout(() => {
                context.commit("numberAdd", v)
                // context.state.oneComNumber += v
            }, 1000);
        },
    },
 
    // 用于操作一些数据 (state)  也可进行判断
    mutations: {
        numberAdd(state, v) {
            // if (state.oneComNumber % 2) {
            //     console.log(4546546546);
            // }
            state.oneComNumber += v
        },
        numberMinus(state, v) {   // 上下文和传过来的值
            state.oneComNumber -= v
        },
 
 
    },
    // 计算属性 辅助函数
    getters: {
        bigOneComNumber(state) {
            return state.oneComNumber * 10
        }
 
    },
}

index.js

import Vue from "vue";
import Vuex from "vuex";
import oneCom from './oneCom'
Vue.use(Vuex);
 
export default new Vuex.Store({
  strict: true,// 严格模式
  // 多个模块进行管理 管理多个文件
  modules: {
    oneCom
  }
});

页面.vue

<template>
  <div class="home">

    <button @click="numberAdd(n)">+</button>
 
    <button @click="numberMinus(n)">-</button>
    <button @click="numberAddWait(n)">过一会再加</button>
 
    <select v-model="n">
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <h2>{{ oneComNumber }}</h2>
  </div>
</template>
 
<script>
import { mapMutations, mapActions, mapState } from "vuex";

export default {
  name: "Home",

  data() {
    return {
      n: 1,
    };
  },
  created() {
    
  },
  methods: {
    ...mapMutations("oneCom", ["numberAdd", "numberMinus"]),
    ...mapActions("oneCom", ["numberAddWait"]),
  },
  computed: {
    ...mapState("oneCom", ["oneComNumber"]),
  },
};
</script>

参考文章:浅谈vuex 五大属性 传值 获取值的方法_猫和老许的博客-CSDN博客_vuex获取值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值