Vue 学习记录四
Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
安装 Vuex
1、npm install vuex --save
2、创建store
对象,src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {};
const getters = {};
const mutations = {};
const actions = {};
const store = new Vuex.Store({
state,
getters,
mutations,
actions,
});
export default store;
3、在入口文件src/main.js
引入并注入store
import Vue from 'vue'
import store from './store'
new Vue({
el:'#app',
store,
})
Vuex选项
1、state
- 定义
state
const state = {
user:null,
}
- 在组件中获取
state
,由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态
export default {
computed:{
user:this.$store.state.user,
}
}
mapState 辅助函数帮助我们生成计算属性
import {mapState} from 'vuex'
export default {
computed:{
localComputed(){
},
//此处是数组的形式,当然也可以使用对象的方式
...mapState([
'user'
]),
}
}
2、getters
- 定义**getters
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
getter 方法接受以下参数:state,getters(可选)
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
getTodoById: (state) => (id) => { //返回一个函数,实现给 getter 传参
return state.todos.find(todo => todo.id === id)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
- 在组件中获取getters
export default {
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
}
同样的,可以使用mapGetters
辅助函数
import mapGetters from 'vuex'
export default {
computed:{
localComputed(){
},
//此处是数组的形式,当然也可以使用对象的方式
...mapGetters([
'doneTodosCount'
]),
}
}
3、mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
一条重要的原则就是要记住 mutation 必须是同步函数
在 store 上注册 mutation,处理函数总是接受 state 作为第一个参数(如果定义在模块中,则为模块的局部状态),payload 作为第二个参数(可选),可以是一个变量,或者是一个对象
- 定义
mutations
const mutations = {
increment (state, n) {
state.count += n
},
}
- 在组件中提交 Mutation
你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
4、actions
Action 提交的是 mutation,而不是直接变更状态
Action 可以包含任意异步操作
在 store 上注册 action。处理函数总是接受 context 作为第一个参数,payload 作为第二个参数(可选)
context 对象包含以下属性:
{
state, // 等同于 `store.state`,若在模块中则为局部状态
rootState, // 等同于 `store.state`,只存在于模块中
commit, // 等同于 `store.commit`
dispatch, // 等同于 `store.dispatch`
getters, // 等同于 `store.getters`
rootGetters // 等同于 `store.getters`,只存在于模块中
}
- 定义
actions
const actions = {
increment({commit},amount){
commit('increment',amount)
},
}
- 在组件内分发
actions
import {mapActions} from 'vuex'
export default {
methods:{
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
另外:
1、应用层级的状态应该集中到单个 store 对象中
2、提交 mutation 是更改状态的唯一方法,并且这个过程是同步的
3、异步逻辑都应该封装到 action 里面
4、如果 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件
本作品采用《CC 协议》,转载必须注明作者和本文链接