vuex之store知识点整理
什么是vuex
vuex是项目里面的状态管理器,统一管理和维护各个组件的可变化状态,vue的应用核心是store,vue有五个核心概念,state, getters, mutations, actions, modules。
基本概念
每一个 Vuex 应用的核心就是 store,里面又包括:
state
,数据,用来存放数据源,就是公共状态
调用:this.$store.state.key
getters
,数据加工,有的时候需要对数据源进行加工,返回需要的数据
调用:this.$store.getters.fun
mutations
,执行,操作结束之后,actions
通过commit
更新state
数据源
调用:this.$store.commit('mutation方法名')
actions
,事件,要执行的操作,可以进行同步或者异步事件。一般用来请求数据,并提交mutations
调用:this.$store.dispatch('action方法名')
modules
,使用单一状态树,致使应用的全部状态集中到一个很大的对象,所以把每个模块的局部状态分装使每一个模块拥有本身的 state、mutation、action、getters、甚至是嵌套子模块;
工作流程
所以,简单的来说,vuex
的工作流程就是:
(1)通过dispatch
去提交一个actions
,
(2)actions
接收到这个事件之后,在actions
中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations
,
(3)actions
通过commit
去触发mutations
,
(4)mutations
去更新state
数据,state
更新之后,就会通知vue
进行渲染
创建一个 Store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {}
})
必须在 Vue.use(Vuex) 之后创建 store
用法说明
state用法说明
存储应用状态数据的对象,state
的值可以是一个对象,也可以是一个返回对象的函数,类似vue
中组件的data
。
定义state
const store = new Vuex.Store({
state: {
userInfo: false
}
})
调用state
- 一般调用
this.$store.state.userInfo
问题:
state 的更新并不会更新视图
解决
使用computed
<template>
<div class="home">
<h2>{{title}}</h2>
<div>{{content}}</div>
</div>
</template>
<script>
import store from '@/stores'
export default {
name: 'home',
computed: {
title() {
return store.state.title
},
content() {
return store.state.content
}
}
}
</script>
- 使用辅助函数
mapState
调用
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用mapState
辅助函数帮助我们生成计算属性,让你少按几次键,通常我们把store
的state
通过mapState
函数映射到组件的computed
上
<template>
<div class="home">
<h2>{{title}}</h2>
<div>{{content}}</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState([
'title',
'content'
])
}
}
</script>
getters用法说明
定义一个函数的形式来返回派生数据,也就是state
只能返回值,如果对值要进行一些转义,那么就用getters
定义getters
const store = new Vuex.Store({
state: {
userInfo: false
},
getters: {
userInfo: (state)=>{
return state.userInfo
},
isLogin: (state)=>{
return state.userInfo!==false
},
username: (state)=>{
let _username = ''
if(typeof state.userInfo === 'object'){
_username = state.userInfo.hasOwenProperty('username') ? state.userInfo.username : ''
}
return _username
},
}
})
调用getters
- 一般调用
this.$store.getters.isLogin
- 使用辅助函数
mapGetters
调用
与mapState
函数类似,通常映射到组件的computed
上
mutations用法说明
更改Vuex
的store
中的状态的唯一方法是提交mutation
,Vuex
中的mutation
非常类似于事件:每个mutation
都有一个字符串的事件类型 (type)
和 一个回调函数 (handler)
定义mutations
const store = new Vuex.Store({
state: {
userInfo: false
},
getters: {
userInfo: (state)=>{
return state.userInfo
},
isLogin: (state)=>{
return state.userInfo!==false
},
username: (state)=>{
let _username = ''
if(typeof state.userInfo === 'object'){
_username = state.userInfo.hasOwenProperty('username') ? state.userInfo.username : ''
}
return _username
},
},
mutations: {
setUserinfo: (stata, data){
stata.userInfo = data
localStorage.setItem('userInfo', data)
}
}
})
调用mutations
mutation 中的函数不要直接调用
使用
commit
调用store.commit('type', payload) // or store.commit({ type1: payload1, type2: payload2, ...:... })
–
type
要提交的mutation
回调函数名称,type
为固定的key
–payload
载荷:提交的额外数据,任意格式使用辅助函数
mapMutations
调用import { mapMutations } from 'vuex' // 先从vuex里导入 mapMutations methods:{ ...mapMutations([ 'setUseInfo', //将mutation里的方法映射到该组件内 'setToken' //等同于this.$store.commit('setToken') ]), changeToken(token){ this.setToken(token) //由于上一步已经将mutation映射到组件内,所以组件可以直接调用setToken } changeUser(userInfo){ this.setUseInfo(userInfo) //同理 } }
store 注入调用
如果每个组件在使用store
的时候都import
会比较繁琐,这个时候,我们通过vuex
提供的store
选项把store
对象注入到vue
的原型上
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/stores'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
配置注入后,我们就可以在组件实例中使用this.$store
来访问store
对象了
<template>
<div class="home">
<h2>{{title}}</h2>
<div>{{content}}</div>
</div>
</template>
<script>
// import store from '@/stores' // 可以去掉了
export default {
name: 'home',
computed: {
title() {
return this.$store.state.title
},
content() {
return this.$store.state.content
}
}
}
</script>
actions用法说明
action 中的函数与 mutation 中的函数类似,但是它主要用来进行异步任务的处理,然后通过提交 mutation 来修改 state
为什么不能在mutations执行异步操作?
Vuex中所有的状态更新的唯一途径都是mutation
,异步操作通过action
来提交mutatio
n实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
每个mutation
执行完成后都会对应到一个新的状态变更,这样devtools
就可以打个快照存下来,然后就可以实现time-travel
了。如果mutation
支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。