您的位置:  首页 > 技术 > 前端 > 正文

复杂交互的项目使用vuex如何更好的组织代码

2021-08-25 18:00 https://my.oschina.net/u/5079097/blog/5200603 PHP开发工程师 次阅读 条评论

前言

阅读之前希望你有vuex的基础知识以及拥有一定的项目经验。

最近一年左右做一个视频在线编辑的项目,该项目是基于vue2.x的。项目中最复杂的页面是编辑页面,页面大概长这样(找了个类似的界面):

image.png

可以看到界面比较复杂,大大小小组件差不多几十个,如果不使用状态管理库的话,使用父子组件交互比较麻烦,所以最终选用了vuex作为状态管理的库。

那么像这种比较复杂的项目,vuex的代码将如何组织呢?下面是我推荐的方法:

首先一个项目会有很多模块(或者叫页面),我的建议是将store按照业务逻辑的模块进行划分,一个业务模块对应一个module

这里需要注意的是:

  1. 不要把所有的业务模块放到一个store里面,这样项目状态变多之后就不太好维护。
  2. 一个业务模块不要对应多个vuex的module,即使很复杂。
 

犯下的错(可以跳过)

这两个坑我都踩过,刚开始做项目的时候,项目比较小,也很简单,编辑页面也没有现在那么复杂,我大概看了一下,需要存的状态只有用户信息和编辑页面的一些状态,没多少,我就放一起了。代码大概这样,所有的状态都在store中

export const store = new Vuex.Store({

    state: {

        userInfo:{

            id:'',

            token:'',

            phone:''

        },

        materials:[],

        audio:[],

        task:[]

    },

    mutations: {},

    modules: {},

})



复制代码
 

这样搞完之后,代码稳定运行了一段时间。 后来产品让加功能,支持多个视频场景,支持背景,支持滤镜,分辨率调整,素材动画等等乱七八糟的功能,需要存的状态也多了很多,都放到一起,store这个文件就太长了,达到了一千多行。在这种情况下,我感觉状态再加下去store那个文件会越来越不好维护,所以重构了下代码,这时我犯下了第二个错误:

我把编辑页面的状态分成了好几个module,大概长这样

const user={

  state: () => ({ ... }),

  mutations: { ... },

  actions: { ... },

  getters: { ... }

}

const material = {

  state: () => ({ ... }),

  mutations: { ... },

  actions: { ... },

  getters: { ... }

}



const audio = {

  state: () => ({ ... }),

  mutations: { ... },

  actions: { ... }

}

//...其他模块



const store = new Vuex.Store({

  modules: {

    user:user,

    material: material,

    audio: audio,

    //其他模块

  }

})



复制代码
 

这样带来的问题是,代码太分散了,我一个编辑页面就对应了好几个module,太分散了维护也不好维护,也不够模块化。

 

最终结局方案

最终解决方案就是:一个单独的业务模块对应一个store的模块

我项目中涉及的业务模块有:用户模块,编辑模块,管理模块,工具包模块,假如每个模块都有需要存储的状态,就可以搞4个module

const store = new Vuex.Store({

  modules: {

    user,

    edit,

    manage,

    toolkit

  }

})

复制代码
 

每个模块对应一个文件或者文件夹,有的模块状态比较简单,例如user,新建一个user.js文件存放状态即可,对于复杂的模块,例如edit,就需要建立一个文件夹了。

目录如下:

vuex-demo/store

├── index.js

└── module

    ├── edit

    │   ├── audio.js

    │   ├── component.js

    │   ├── edit-mutations.js

    │   ├── edit.js

    │   └── material.js

    └── user.js

复制代码
 

搞成一个文件夹(而不是一个文件)是为了不把所有的状态都写在edit.js中,防止一个文件过大。在edit.js中使用拓展运算法又做了进一步的代码模块化,代码如下:

edit.js代码如下:

import { audio } from './audio'

import {material} from './material'



export const edit = {

    state: () => ({

        ...audio.state,

        ...material.state

    }),

    getters: {

        ...audio.getters,

        ...material.getters

    },

    mutations: {

        ...audio.mutation,

        ...material.mutation

    },

    actions: {

        ...audio.actions,

        ...material.actions

    },

}



复制代码
 

就这样,很简单哈。

说了那么多,大部分都是废话,有用的代码不过十几行,代码放在这里了传送门

 

vuex持久化插件推荐

我们存在vuex中的数据,尤其是用户数据,一刷新页面就无了,这和我们的预期不一样,好多人(尤其是年轻人)以为的状态管理库是可以持久保存的,即我刷新页面也还在。

之所以这样以为其实是对vuex的本质认知不够,vuex的本质就是一个JS大对象,保存在内存里,类似于下面

let store={state:{},getter:{}}



new Vue({  store: store})

复制代码
 

你一刷新页面,内存中的数据肯定清空,所以store中的数据无了也是正常的。如果你要存起来,你可以选择vuex和localStorage或者sessionStorage或者cookie配合。 你需要

  1. 提交Mutation时,同时存到本地储存中(注意如果是对象的话需要JSON.stringify)
  2. 刷新页面时(可以在App.vue中的created方法中),从本地储存中取到用户信息,如果有的话提交一下Mutation
export const user = {

    state: () => ({

       info:{}

    }),

    getters: {},

    mutation: {

        setUser(state,info){//1. 提交Mutation时,同时存到本地储存中

            localStorage.setItem('user',JSON.stringify(info))

            state.info=info

        }

    },

    actions: {},

}





复制代码
 
    created() {

        const userInfo=localStorage.getItem('user')

        if(userInfo){

            // 提交Mutation,更新用户信息

        }

    }

复制代码
 

这样存,你有一个数据你就存一次,有两个数据就存两次,有n个就存n次,太累了,所以推荐个插件, 在提交mutation时自动存,页面刷新时自动更新,方便的很。就不写demo了,累了。

插件地址 vuex-persistedstate

 

结语

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:     http://github.crmeb.net/u/defu           不胜感激 !
 
来自 “开源独尊 ” ,链接:           https://ym.baisou.ltd/post/856.html    

 
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接