具体代码开源到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等)
2.1、在/src/store目录下,新建以下文件
【以下是页面展示图,其中搜索数据需要全局存储,即存储于Vuex中】
2.2、【封装搜索组件SearchForm】
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,并挂载即可在组件中使用
3.1、@Getter 和 @Action 对应的值都需要非空;
@Watch对应的参数说明:
参数一表示监听的字段名、
参数二中的属性值'immediate'表示组件一加载就监听(默认加载之后第一次修改才执行监听)、
参数三中的属性值'deep'表示深度监听,即修改对象的属性值也会执行监听(默认修改对象的值,不会执行监听,但是设置deep,消耗性能,建议通过"对象.对象属性"进行监听)。参考这个大佬
具体代码如下:
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"
文件目录如下
7.1、 模块文件 /src/store/model/setting/setting.js ,需要定义 state、getters、mutations、actions,并导出
7.2、 导出模块文件 /src/store/model/setting/index.js ,导出模块文件 setting.js即可
7.3、导出 store 文件 /src/store/index.js,导出Vuex.Store对象,其中定义了模块,以及使用中间件 `vuex-persistedstate` 保证Vuex数据刷新不丢失
7.4、入口文件 main.js 导出Vuex.store对象
总结:
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、写给自己的随笔,有问题欢迎指出ψ(*`ー´)ψ