在管理后台中使用vuex是比较常见的做法,我们这里使用的是vuex4
一、vuex的使用
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
官网传送阵next.vuex.vuejs.org/zh/index.ht…
安装:
vuex3
npm install vuex --save
vuex4
npm install vuex@next --save
v3的使用和v4的使用还是有些不同的 比如说v3创建实例
const store = new Vuex.Store({
...
})
v4的就改为了
const store = createStore({
...
})
二、常用方法
这是就是vuex的核心概念,主要就四个
- State: 存数据的地方,可以有一个或者多个,多数情况下是多个
- Getters:类似于computed,主要是用来拿参数的
- Mutations: 唯一改变State状态的方法
- Actions:类似于methods,写在状态里用到的方法
- Modules:通过这个方法,可以把单一的Store分割成模块使用
单个store的使用
单个store的使用
const store = new Vuex.Store({
state: {
token: ''
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
}
},
getters: {
},
actions: {
LoginByUsername ({ commit }, userInfo: { username: string, password: string}) {
commit('SET_TOKEN', 'token')
}
}
})
一般情况下很少会是单个的,基本都是多个store,比如用user的store, shop的store,还有其他的各种的store,以模块化分割。
多个store的使用
vuex4
这里先说vuex4的使用
创建文件夹如下:
index.ts文件夹是一个主文件 vuex里有一个createStore的api,我们用它来创建实例 如下
const store = createStore({
....
})
由于我们需要创建多个store,就需要使用到modules,分割我们的模块。 在分割之前我们先来写我们的user.ts
const user = {
state: {
token: '',
data: {}
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
}
},
getters: {
},
actions: {
LoginByUsername ({ commit }, userInfo: { username: string, password: string}) {
const username = userInfo.username.trim()
const data = {
username,
password: userInfo.password
}
commit('SET_TOKEN', 'token')
}
}
}
export default user
这里说下user,在我们现在的项目中使用到了ts,所以我们要定义好interface 在这里我定义了两个interface,一个是父级,一个子级
export interface UserDataProps {
username?: string,
password?: string,
id?: string,
}
export interface UserProps {
token?: string,
data: UserDataProps;
}
定义接口的好处是很多的,有提示和检验的作用,可以帮助我们更正规的去写代码。
这里有使用到username?: string这里是指该参数可选。
之后我们来写index.ts的文件
首先导入user.ts文件到
import { createStore } from 'vuex'
import user from './modules/user'
然后创建实例,并导出去
const store = createStore({
modules: {
user
}
})
export default store
这里我们定义下总的interface,如下
import user, { UserProps } from './modules/user'
export interface GlobalDataProps {
user: UserProps
}
完整的代码如下:
index.ts
import { createStore } from 'vuex'
import user, { UserProps } from './modules/user'
export interface GlobalDataProps {
user: UserProps
}
const store = createStore({
modules: {
user
}
})
export default store
user.ts
import { Module } from 'vuex'
import { GlobalDataProps } from '../index'
export interface UserDataProps {
username?: string,
password?: string,
id?: string,
}
export interface UserProps {
token?: string,
data: UserDataProps;
}
const user: Module<UserProps, GlobalDataProps> = {
state: {
token: '',
data: {}
},
mutations: {
},
getters: {
SET_TOKEN: (state, token) => {
state.token = token
}
},
actions: {
LoginByUsername ({ commit }, userInfo: { username: string, password: string}) {
const username = userInfo.username.trim()
const data = {
username,
password: userInfo.password
}
console.log(data)
commit('SET_TOKEN', 'token')
}
}
}
export default user
v3的使用
整体的使用和v4是差不多的,大家在用element-admin的时候在store中会看到这样的代码
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
这个其实是我想不到的,然后查了webpack的资料
require.context
可以给这个函数传入三个参数:一个要搜索的目录,一个标记表示是否还搜索其子目录, 以及一个匹配文件的正则表达式 这里说下正则表达,我们这里要匹配.js的文件,而且是需要匹配字符串的结尾
匹配.需要使用\.
\:将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符
$: 匹配输入字符串结尾的位置
因此使用的正则就是
/\.js$/
通过使用keys(),返回了我们匹配到的文件
通过 reduce(),我们拿到了如下数据
现在通过正则表达,拿到定义对象的key
^:匹配输入字符串开始的位置
\:将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符
( ):标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用
*:匹配前面的子表达式零次或多次
+:匹配前面的子表达式一次或多次
\w:匹配字母、数字、下划线
这是上边用到的正则匹配规则,先匹配开头位置为./的字符,尾部匹配.后加字符串的字符串。这样我们拿到的就是user这种干净的key值
const value = modulesFiles(modulePath)
拿到了每个mudules的模块。
这样达到了还v4一样的效果.