• vue-vuex详解


    ​🌈个人主页:前端青山
    🔥系列专栏:Vue篇
    🔖人终将被年少不可得之物困其一生

    依旧青山,本期给大家带来vue篇专栏内容:vue-vuex详解

    目录

    Vuex

    1.vuex是什么?

    2.vuex核心概念

    3.vuex模块化

    4. Vuex中action和mutation的区别

    4.1Vuex 和 localStorage 的区别

    4.2Vuex有哪几种属性?

    4.3Vuex和单纯的全局对象有什么区别?

    4.4为什么 Vuex 的 mutation 中不能做异步操作?

    4.5 Vuex的严格模式是什么,有什么作用,如何开启?

    4.6如何在组件中批量使用Vuex的getter属性

    4.7 如何在组件中重复使用Vuex的mutation

    5.实战应用代码

    Vuex

    1.vuex是什么?

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

    其具有以下优势:

    • 能够在vuex中集中管理共享的数据,便于开发和后期进行维护

    • 能够高效的实现组件之间的数据共享,提高开发效率(代码量

    • 存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新

    什么样的数据适合存储在Vuex中?

    一般情况下,只有组件之间共享的数据才有必要存储到vuex中,对于组件中私有的数据依旧存储在组件自身的data中即可。

    注意事项:由于vue项目一刷新就会重新编译,因此每次刷新都会重新初始化vuex中的数据,会导致之前的数据丢失,因此vuex中一般不保存非常重要的数据。【放在vuex中的数据一般是刷新后也不影响业务的数据】

    2.vuex核心概念

    vuex的核心组成:

    • state:状态,用于初始化仓库中的数据,在这里声明项目中全局使用的数据

    • mutations:修改state数据的方法,存放用于修改state数据的方法

      • 只存放同于同步修改数据的方法

      • 每个方法接收俩个形参,依次是:

        • state:object,指的是仓库中的数据

        • payload:any类型,用于修改数据的数据源(可选)

      • 函数不需要return,所有操作都是基于state直接更改

    • actions:修改state数据的方法,存放用于修改state数据的方法

      • 只存放同于异步修改数据的方法

      • 每个方法接收俩个形参,依次是:

        • context:object,指的是仓库对象(上下文对象)

        • payload:any类型,用于修改数据的数据源(可选)

      • 函数不需要return,所有操作都是基于state直接更改

      • 这里的方法本身自己不直接该数据,而是通过context对象调用mutations中的方法去修改数据

    • getters:获取并修饰数据(对数据进行格式处理),存储用于修饰数据的方法

      • 里面的方法有一个形参

        • state:object,指的是仓库中的数据

      • 每个函数必须有返回值,返回修饰完的数据

    • modules:模块化,存放模块化后的仓库模块,这里存放导入进来的模块变量

    vuex语法,vuex支持对象属性形式、辅助函数形式去操作store中数据,所以每个操作都具备俩个语法:

    • 获取state数据

      • 对象属性:this.$store.state.属性名

      • 辅助函数:mapState

        • 作用:将指定的state中的数据映射为组件自身的计算属性

        • 语法:

          • 写在computed中

          • ...mapState([属性名1,属性名2,....])

    • 同步修改数据

      • 对象属性:this.$store.commit(方法名,载荷数据)

      • 辅助函数:mapMutations

        • 作用:将指定的mutations中的方法映射为组件自身的方法

        • 语法:

          • 写在methods中

          • ...mapMutations([方法名1,方法名2,...])

    • 异步修改数据

      • 对象属性:this.$store.dispatch(方法名,载荷数据)

      • 辅助函数:mapActions

        • 作用:将指定的Actions中的方法映射为组件自身的方法

        • 语法:

          • 写在methods中

          • ...mapActions([方法名1,方法名2,...])

    • 获取修饰数据

      • 对象属性:this.$store.getters.属性名

      • 辅助函数:mapGetters

        • 作用:将指定的getters中的数据映射为组件自身的计算属性

        • 语法:

          • 写在computed中

          • ...mapGetters([属性名1,属性名2,....])

    3.vuex模块化
    • 为什么需要模块化?

      • 团队协作开发需要

      • 方便后期维护管理

    • 怎么模块化?

      • 将除modules对象中的内容按照指定的拆分标准进行按文件分离

      • 在index.js中导入并在modules对象中注册

    • 有什么需要注意的?

      • 因为模块化,后续的语法需要有所调整,具体见下

      • 命名冲突时会执行自动合并策略

        • state,名字相同也不会冲突

        • mutations、actioms里同名方法会被合并成数组,都执行(index.js中的是最先执行的)

        • getters如果同名,无法合并,直接报错

      • 通过命名空间来避免冲突(给每个模块开启命名空间)

        • 设置模块的namespaced属性为true即可

    vuex模块化后的语法:

    • 获取state数据

      • 对象属性:this.$store.state.模块名.属性名

      • 辅助函数:mapState

        • 作用:将指定的state中的数据映射为组件自身的计算属性

        • 语法:

          • 写在computed中

          • ...mapState(模块名,[属性名1,属性名2,....])

    • 同步修改数据

      • 对象属性:this.$store.commit(模块名/方法名,载荷数据)

      • 辅助函数:mapMutations

        • 作用:将指定的mutations中的方法映射为组件自身的方法

        • 语法:

          • 写在methods中

          • ...mapMutations(模块名,[方法名1,方法名2,...])

    • 异步修改数据

      • 对象属性:this.$store.dispatch(模块名/方法名,载荷数据)

      • 辅助函数:mapActions

        • 作用:将指定的Actions中的方法映射为组件自身的方法

        • 语法:

          • 写在methods中

          • ...mapActions(模块名,[方法名1,方法名2,...])

    • 获取修饰数据

      • 对象属性:this.$store.getters["模块名/属性名"]

      • 辅助函数:mapGetters

        • 作用:将指定的getters中的数据映射为组件自身的计算属性

        • 语法:

          • 写在computed中

          • ...mapGetters(模块名,[属性名1,属性名2,....])

    4. Vuex中action和mutation的区别

    mutation中的操作是一系列的同步函数,用于修改state中的变量的的状态。当使用vuex时需要通过commit来提交需要操作的内容。mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

    1. const store = new Vuex.Store({
    2.  state: {
    3.    count: 1
    4. },
    5.  mutations: {
    6.    increment (state) {
    7.      state.count++      // 变更状态
    8.   }
    9. }
    10. })

    当触发一个类型为 increment 的 mutation 时,需要调用此函数:

    store.commit('increment')

    而Action类似于mutation,不同点在于:

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

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

    1. const store = new Vuex.Store({
    2.  state: {
    3.    count: 0
    4. },
    5.  mutations: {
    6.    increment (state) {
    7.      state.count++
    8.   }
    9. },
    10.  actions: {
    11.    increment (context) {
    12.      context.commit('increment')
    13.   }
    14. }
    15. })

    Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用

    context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。 所以,两者的不同点如下:

    • Mutation专注于修改State,理论上是修改State的唯一途径;Action业务代码、异步请求。

    • Mutation:必须同步执行;Action:可以异步,但不能直接操作State。

    • 在视图更新时,先触发actions,actions再触发mutation

    • mutation的参数是state,它包含store中的数据;store的参数是context,它是 state 的父级,包含 state、getters

    4.1Vuex 和 localStorage 的区别

    (1)最重要的区别

    • vuex存储在内存中

    • localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON的stringify和parse方法进行处理。 读取内存比读取硬盘速度要快

    (2)应用场景

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

    • localstorage是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用 。

    • Vuex能做到数据的响应式,localstorage不能

    (3)永久性

    刷新页面时vuex存储的值会丢失,localstorage不会。

    注意: 对于不变的数据确实可以用localstorage可以代替vuex,但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到,原因就是区别1。

    4.2Vuex有哪几种属性?

    有五种,分别是 State、 Getter、Mutation 、Action、 Module

    • state => 基本数据(数据源存放地)

    • getters => 从基本数据派生出来的数据

    • mutations => 提交更改数据的方法,同步

    • actions => 像一个装饰器,包裹mutations,使之可以异步。

    • modules => 模块化Vuex

    4.3Vuex和单纯的全局对象有什么区别?
    • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

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

    4.4为什么 Vuex 的 mutation 中不能做异步操作?
    • Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解我们的应用。

    • 每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

    4.5 Vuex的严格模式是什么,有什么作用,如何开启?

    在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

    在Vuex.Store 构造器选项中开启,如下

    1. const store = new Vuex.Store({
    2.   strict:true,
    3. })
    4.6如何在组件中批量使用Vuex的getter属性

    使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中

    1. import {mapGetters} from 'vuex'
    2. export default{
    3.    computed:{
    4.        ...mapGetters(['total','discountTotal'])
    5.   }
    6. }
    4.7 如何在组件中重复使用Vuex的mutation

    使用mapMutations辅助函数,在组件中这么使用

    1. import { mapMutations } from 'vuex'
    2. methods:{
    3.    ...mapMutations({
    4.        setNumber:'SET_NUMBER',
    5.   })
    6. }

    然后调用this.setNumber(10)相当调用this.$store.commit('SET_NUMBER',10)

    5.实战应用代码
    1. import { createStore } from 'vuex'
    2. import router from '@/router'
    3. import qs from 'qs'
    4. export default createStore({
    5.  state: {
    6.   // token: '',
    7.  // menuList:[],
    8.    hasRoutes: false,
    9.    editableTabsValue:'/index',
    10.    editableTabs:[
    11.     {
    12.        title: '首页',
    13.        name: '/index'
    14.     }
    15.   ]
    16. },
    17.  getters: {
    18.    GET_TOKEN: state => {
    19.      return sessionStorage.getItem("token")
    20.   },
    21.    GET_MENULIST:state => {
    22.      return JSON.parse(sessionStorage.getItem("menuList"))
    23.   },
    24.    GET_PERMS:state=>{
    25.      return JSON.parse(sessionStorage.getItem("perms"))
    26.   },
    27.    GET_USERINFO:state=>{
    28.      // console.log("GET_USERINFO="+sessionStorage.getItem("userInfo"))
    29.      return JSON.parse(sessionStorage.getItem("userInfo"))
    30.   }
    31. },
    32.  mutations: {
    33.    SET_TOKEN: (state, token) => {
    34.      // state.token = token
    35.      sessionStorage.setItem("token", token)
    36.   },
    37.    RESET_TOKEN:(state)=>{
    38.      //state.token=''
    39.      sessionStorage.setItem("token", "")
    40.   },
    41.    SET_MENULIST:(state,menuList)=>{
    42.      //state.menuList=menuList;
    43.      sessionStorage.setItem("menuList", JSON.stringify(menuList))
    44.   },
    45.    SET_PERMS:(state,perms)=>{
    46.      sessionStorage.setItem("perms", JSON.stringify(perms))
    47.   },
    48.    SET_USERINFO:(state,userInfo)=>{
    49.      sessionStorage.setItem("userInfo", JSON.stringify(userInfo))
    50.   },
    51.    //动态添加tab
    52.    ADD_TABS:(state,tab)=>{
    53.      // debugger
    54.      // console.log("进入条件"+state.editableTabs.findIndex(e=>e.name));
    55.      if(state.editableTabs.findIndex(e=>e.name===tab.path)===-1){
    56.        // if(tab.name===undefined){
    57.        //   tab.name="操作日志"
    58.        // }
    59.        state.editableTabs.push({
    60.          title: tab.name,
    61.          name:tab.path
    62.       });
    63.     }
    64.      state.editableTabsValue=tab.path
    65.      // console.log("路由列表:"+JSON.stringify(state.editableTabs))
    66.      // console.log("路由值:"+JSON.stringify(state.editableTabsValue))
    67.   },
    68.    RESET_TABS:(state)=>{
    69.      state.editableTabsValue='/index';
    70.      state.editableTabs=[
    71.       {
    72.          title: '首页',
    73.          name: '/index'
    74.       }
    75.     ]
    76.   },
    77.    SET_ROUTES_STATE:(state,hasRoutes)=>{
    78.      state.hasRoutes=hasRoutes
    79.   }
    80. },
    81.  actions: {
    82.    // 安全退出
    83.    logout(){
    84.      window.sessionStorage.clear();
    85.      this.state.hasRoutes=false
    86.      router.replace('/login')
    87.   }
    88. },
    89.  modules: {
    90. }
    91. })

  • 相关阅读:
    庐山谣寄卢侍御虚舟
    01线程概述
    深度学习笔记其七:计算机视觉和PYTORCH
    BHQ淬灭试剂BHQ-2 acid|cas:1214891-99-2|BHQ-2 酸|BHQ-2 羧基的信息你知道多少
    【MySql】mysql 常用查询优化策略详解
    svelte初探-上
    ElasticSearch 、Kibana安装
    给定一个整数数组 nums 和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
    【编程题】【Scratch二级】2022.03 魔法星空
    【Web】Ctfshow SSTI刷题记录1
  • 原文地址:https://blog.csdn.net/2302_76329106/article/details/134402231