Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)

一、【VueCli3+】版本说明及需要安装的中间件,以下中间件没有的,就需要安装一哈子

具体代码开源到github,欢迎star

1.1、以下是 VueCli3+ 中的store (Vue + VueCli3 + TavaScript + iviewUI + Vuex)

    "vue": "^2.6.10",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.3.0",
    "vue-router": "^3.1.3",
    "vuex": "^3.0.1",
    "vuex-class": "^0.3.2",
    "vuex-persistedstate": "^2.7.0",
    "typescript": "~3.5.3",
    "view-design": "^4.0.2"

注意:`vuex-class` 和  `vuex-module-decorators` 两个装饰器中间件,二选一即可,此处用的 `vuex-class`

         以下是两个装饰器的区别

`vuex-class`(组件使用装饰器,即使用@State、@Action、@Getter等;store中使用Action和ActionTree等类);
`vuex-module-decorators`(store中使用装饰器,即store文件中使用@Module、@Mutation、@Action等,通过getModule导出模块;  组件中通过导入模块调用对应的属性和方法,即模块.属性\模块.方法调用); 


安装:
npm install vuex-class --save   # vuex装饰器(vue组件中使用@State、@Action、@Getter等)
npm install vuex-persistedstate --save # 保证vuex数据刷新不消失(默认刷新会消失)
npm install vuex-module-decorators --save # vuex装饰器中间件(store文件中使用@Module、@Mutation、@Action等)

 

 

二、【VueCli3+】封装store模块文件、actions文件、getters文件、mutation的types函数名文件等


2.1、在/src/store目录下,新建以下文件

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第1张图片

【以下是页面展示图,其中搜索数据需要全局存储,即存储于Vuex中】

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第2张图片

 

2.2、【封装搜索组件SearchForm】

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第3张图片

 

2.3、首先看看【mutation-types.ts】文件的数据:定义了两个函数名,'SET_STATE_DATA'设置数据、'INIT_STATE'初始化数据

/**
 * @description [store.mutation] 对应的函数名
 * @author Hilary
 * @date 2019/11/09
 */
export const SET_STATE_DATA = 'SET_STATE_DATA'
export const INIT_STATE = 'INIT_STATE'

 

2.4、接着模块【search.ts】文件的数据:定义了两个接口、两个mutations方法、导出state、mutations;   此处其实就两个需要全局存储的数据,分别是date和name值

/**
 * @description [搜索模块] 数据表头部搜索需要的相关数据(日期、用户名等)
 * @author Hilary
 * @date 2019/11/09
 */

// import { Commit } from 'vuex'
import * as types from '../mutation-types'

// 定义接口 -- state对应的数据
export interface State {
    date: Date[],
    name: string
}

// 定义接口 -- 修改state的数据格式
export interface SetNewSearchState {
    key: string,
    value: any
}

// 原state数据,初始化state数据
const initState: State = {
    date: [ new Date(Date.now() - 1000 * 3600 * 24 * 6), new Date()],
    name: '凯'
}

// // 原getters
// const getters = {
//     date: (state: State) => state.date,
//     name: (state: State) => state.name
// }

// 原mutations
const mutations = {
    [types.SET_STATE_DATA] (state: State, newObj: SetNewSearchState) {
        // 修改存在的state的属性值
        if(state.hasOwnProperty(newObj.key)) {
            state[newObj.key] = newObj.value
        }
    },
    [types.INIT_STATE] (state: State) {
        state.date = [ new Date(Date.now() - 1000 * 3600 * 24 * 6), new Date()]
        state.name =  '易凯源'
    }
}

// // 原actions
// const actions = {
//     setStateData(context: {commit: Commit; state: State}, newObj: SetNewSearchState) {
//         console.log('===============setStateData=====================');
//         console.log(context.state);
//         console.log('====================================');
//         context.commit(types.SET_STATE_DATA, newObj)
//     }
// }

export default {
    state: initState,
    // getters,
    mutations
    // actions
}

 

2.5、【index.ts】文件的数据:导出了Store数据,并且引入中间件`vuex-persistedstate`,保证数据刷新不丢失,其实其原理是将数据存储于localStorage中; 定义了对应不同模块的State接口

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import actions from './actions'
import getters from './getters'
import search, {State as SearchState} from './modules/search';

Vue.use(Vuex)

export default new Vuex.Store({
  getters,
  actions,
  modules: {
    search
  },
  // 将数据存储于localStorage中,保证刷新数据不消失
  plugins: [createPersistedState()]
})

// 统一模块的state数据
export interface State {
  search: SearchState
}

 

2.6、【getters.ts】文件的数据:定义了Getter类型的state的属性值; 返回GetterTree类型的getters对象

/**
 * @description [store.getters] 数据
 * @author Hilary
 * @date 2019/11/09
 */

import { GetterTree, Getter } from 'vuex'
import { State } from './index'

const date: Getter = (state: State) => {
    return state.search.date
}

const name: Getter = (state, State) => {
    return state.search.name
}

const getters: GetterTree = {
    date,
    name
}

export default getters

 

2.7、【actions.ts】文件的数据,定义了两个actions方法,运用了Vuex的'Action'和'ActionTree'类,最后导出ActionTree类型的actions对象

/**
 * @description [store.actions] 数据
 * @author Hilary
 * @date 2019/11/09
 */

import { Commit, Action, ActionTree } from 'vuex';
import * as types from './mutation-types'
import { SetNewSearchState } from './modules/search';
import { State } from './index'

/**
 * 设置state的数据
 * @param context 
 * @param newObj 
 */
const setStateData: Action = (context: {commit: Commit; state: State}, newObj: SetNewSearchState) => {
    console.log('===============setStateData=====================');
    console.log(context.state);
    console.log('====================================');
    context.commit(types.SET_STATE_DATA, newObj)
}

/**
 * 初始化state的数据
 * @param context 
 */
const initStateData: Action = (context: { commit: Commit; state: State }) => {
    context.commit(types.INIT_STATE)
}

const actions: ActionTree = {
    setStateData,
    initStateData
}

export default actions

 

2.8、【src/main.ts】文件引入store,并挂载即可在组件中使用

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第4张图片

 

三、【VueCli3+】组件中运用,需要`vuex-class`中间件,运用其装饰器 @Action、@Getter等   


 3.1、@Getter 和 @Action 对应的值都需要非空;     

        @Watch对应的参数说明:

             参数一表示监听的字段名、

             参数二中的属性值'immediate'表示组件一加载就监听(默认加载之后第一次修改才执行监听)、

             参数三中的属性值'deep'表示深度监听,即修改对象的属性值也会执行监听(默认修改对象的值,不会执行监听,但是设置deep,消耗性能,建议通过"对象.对象属性"进行监听)。参考这个大佬

             

具体代码如下:



 

 

四、【VueCli3+】 在Home的beforeDestroy生命周期中,调用了初始化state数据函数initStateData,具体代码如下



Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第5张图片

 

五、【VueCli3+】效果图,修改搜索框的数据后,切换不同页面,其值没有变化



Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第6张图片

 

六、【VueCli2】版本说明


6.1、以下是VueCli2中的store (Vue + VueCli2 + JavaScript+ ElementUI + Vuex) 

    "vue": "^2.5.2",
    "vue-router": "^3.0.1",
    "element-ui": "^2.11.1",
    "vuex": "^3.1.1",
    "vuex-persistedstate": "^2.5.4",
    "webpack": "^3.6.0"

 

七、【VueCli2】Vuex需要的文件( store 目录下)定义,并在 main.js文件中导出


文件目录如下

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第7张图片

 

7.1、 模块文件  /src/store/model/setting/setting.js ,需要定义 state、getters、mutations、actions,并导出

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第8张图片

 

7.2、 导出模块文件  /src/store/model/setting/index.js ,导出模块文件 setting.js即可

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第9张图片

 

7.3、导出 store 文件  /src/store/index.js,导出Vuex.Store对象,其中定义了模块,以及使用中间件 `vuex-persistedstate` 保证Vuex数据刷新不丢失

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第10张图片

 

7.4、入口文件 main.js 导出Vuex.store对象

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第11张图片

 

八、【VueCli2】组件中使用 store 的数据

Vue 之 Vuex,存储本地数据 并 保证刷新不丢失( VueCli2+JavaScript 与 VueCli4+TypeScript中store写法的区别)_第12张图片

 

 

总结:

1、使用Vuex时,VueCli3+ 需要安装中间件'vuex-class'装饰器; 'vuex-persistedstate'保证刷新不丢失数据

2、VueCli3+ 封装store文件,主要与 VueCli2 的区别就是,需要单独定义文件getters.ts和actions.ts文件等,主要是需要导出GetterTree类型对象、ActionTree类型对象等; 对应的模块文件只需要导出state和mutations属性和一些自定义接口等;  VueCli2 直接定义在对应的模块中,导出即可

3、VueCli3+ 在组件中引用,主要是通过装饰器@Getter和@Action,获取对应state属性值、actions的函数等;  而 VueCli2 一般通过mapGetters、mapActions回调获取

4、具体代码开源到github,欢迎star

5、写给自己的随笔,有问题欢迎指出ψ(*`ー´)ψ

 

 

 

 

 

你可能感兴趣的:(前端)