概念: Vuex可以理解为一种开发模式或者框架。比如:PHP有thinkphp ,java有spring 等!通过状态(数据源)集中管理驱动的组件的变化(好比spring的IOC 容器对bean 进行集中管理)
- 应用级的状态集中放在
store 里面 - 改变状态的方式是提交
mutation ,这是个同步的事物 - 异步逻辑应该封装到
action 中
vuex中的5个核心有哪些?
1.state state 为单一状态数,在state中 需要定义我们所需要管理的数组,对象、字符串等等,只有在这里定义了,在vue.js的组件中才能获取你定义的这个对象的状态
state: {
token: getStorage('token') || '',
refresh_token: getStorage('refresh_token') || '',
user: JSON.parse(localStorage.getItem('user')) || {}
},
- getter
getter 是与vue,js中计算属性有点类似的,当我们需要从stroe 的state 中派生出一些状态,那么我们就需要使用getter ,getter会接收state作为第一个参数,而且getter 的返回值会根据它的依赖项被缓存起来,只有getter 中的依赖值(state中某个需要派生状态的值)发生改变的·时候才会被重新计算。
getters: {
userPhoto(state) {
if (state.user.photo === undefined) {
store.dispatch('getUserInfo')
}
return state.user.userPhoto
}
}
- mutation
更改store中state状态的唯一方法就是体积mutation,就很类似像事件,每个mutation都有一个字符串类型的事件类型和一个回调函数,我们需要改变state的值就要在回调函数中改变,我们要执行这个回调函数,那么我们需要执行一个相应的调用方法store.commit
mutations: {
setToken(state, token) {
state.token = token
setStorage('token', token)
},
setRefreshToken(state, refreshToken) {
state.refresh_token = refreshToken
setStorage('refresh_token', refreshToken)
},
setUser(state, userObj) {
state.user = userObj
localStorage.setItem('user', JSON.stringify(userObj))
},
setPhoto(state, photo) {
state.user.photo = photo
localStorage.setItem('user', JSON.stringify(state.user))
},
setName(state, theName) {
state.user.name = theName
localStorage.setItem('user', JSON.stringify(state.user))
}
},
- action
action可以提交mutation,在action中可以执行store.commit,而且action中可以有任何的异步操作,在页面中如果要够用这个action,需要执行store.dispatch
actions: {
async asyncLoginAction(store, val) {
try {
const res = await loginAPI(val)
const {
token,
refresh_token
} = res.data.data
store.commit('setToken', token)
store.commit('setRefreshToken', refresh_token)
return Promise.resolve(res)
} catch (err) {
return Promise.reject(err)
}
},
async getUserInfo(store) {
const res = await getUserAPI()
store.commit('setUser', res.data.data)
}
},
- module
module其实只是解决了当state中很复杂臃肿的时候,module可以将store分割成模块,每个模块中拥有自己的state、mutation、action、getter
vue的出现的解决出的问题
主要解决了以下两个问题
- 多个组件依赖于同一状态时,对于多层嵌套的组件的传参将会非常繁琐,并且对于兄弟组件的状态状态传递无能为力
- 来自不同组件的行为需要变更同一状态,以往采用父子组件直接引用或者通过事件类变更和同步状态的多分拷贝,以上的这些面膜刷非常脆弱,通常会导致无法维护的代码
Vuex的数据传递流程
当组件进行数据修改的时候我们需要调用dispatch来触发actions里面的方法。actions里面的每个方法中都会,有一个
1.commit方法,当方法执行的时候会通过commiy来触发mutations里面的方法进行数据的修改 2. mutations里面的每一个函数都会有一个state参数,这样就可以在mutations里面进行state的数据修改,当数据修改完毕后,会传导给页面,页面的数据会发生改变
import Vue from 'vue'
import Vuex from 'vuex'
import {
setStorage,
getStorage
} from '@/utils/storage'
import {
loginAPI
} from '@/api/login.js'
import store from '@/store'
import {
getUserAPI
} from '../api/user'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
token: getStorage('token') || '',
refresh_token: getStorage('refresh_token') || '',
user: JSON.parse(localStorage.getItem('user')) || {}
},
mutations: {
setToken(state, token) {
state.token = token
setStorage('token', token)
},
setRefreshToken(state, refreshToken) {
state.refresh_token = refreshToken
setStorage('refresh_token', refreshToken)
},
setUser(state, userObj) {
state.user = userObj
localStorage.setItem('user', JSON.stringify(userObj))
},
setPhoto(state, photo) {
state.user.photo = photo
localStorage.setItem('user', JSON.stringify(state.user))
},
setName(state, theName) {
state.user.name = theName
localStorage.setItem('user', JSON.stringify(state.user))
}
},
actions: {
async asyncLoginAction(store, val) {
try {
const res = await loginAPI(val)
const {
token,
refresh_token
} = res.data.data
store.commit('setToken', token)
store.commit('setRefreshToken', refresh_token)
return Promise.resolve(res)
} catch (err) {
return Promise.reject(err)
}
},
async getUserInfo(store) {
const res = await getUserAPI()
store.commit('setUser', res.data.data)
}
},
getters: {
userPhoto(state) {
if (state.user.photo === undefined) {
store.dispatch('getUserInfo')
}
return state.user.userPhoto
}
}
})
|