Vuex的定义和使用条件
定义
官方说明:Vuex 是 专为 Vue.js 应用程序开发的状态管理模式(state management pattern)。它采用集中式存储(centralized store)管理应用的所有组件的状态(state),并以相应的规则保证状态以一种可预测的方式发生变化。
个人白话理解:在全局设一个store,任何组件都可以访问store里的数据,大家一起共用。
为什么要用Vuex
官方说明:
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{
{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
})
其中:
- state,驱动应用的数据源; (data部分)
- view,以声明方式将 state 映射到视图;(template部分)
- actions,响应在 view 上的用户输入导致的状态变化。(methods部分)
以下是一个表示“单向数据流”理念的简单示意:
但是:多个组件共享状态(State)时:
1.多个视图(View)依赖于同一状态(State)。
2.来自不同视图(View)的行为需要变更同一状态(State)。
程序会变得很繁琐。
白话理解: 如果多个组件需要访问同一个数据,就得通过传参的方式共享这个数据,太麻烦了,而且兄弟组件之间也没法传参。如果多个组件都要已相同或者相似的方式改变同一个数据,每个组件中会有很多重复的方法(Methods)代码。所以在全局设store,存放共享的数据和方法。
创建Store
在根实例中
import Vue from 'vue'
import Vuex from 'vuex'
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
核心概念
五个核心概念:State Getter Mutation Action Module
State
通过在根实例注册 store 选项
Vue.use(Vuex)
const app = new Vue({
el: '#app',
store,
components: {
Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
子组件就可以通过this.$store来访问
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
官方文档每次访问state,都是会把state声明为computed,个人理解是:在一个组件中,如果反复写this.$store.state.变量,代码显得太冗长了。所以先赋给计算属性,在需要用到state的时候直接访问相应的计算属性,会比较简洁。
子组件中,将状态(State)声明为 computed 而非 data 的好处:
export default {
data () {
return {
dataCount: this.$store.state.count //state改变时,data监听不到
}
},
computed:{
computedCount(){
return this.$store.state.count //state改变时,computed可以监听到
}
}
}
所以,在改变state值时,computedCount可以响应更新,但dataCount不可以。
但是,如果要将多个state声明为computed时,代码会很冗长。为了解决这个问题,mapState 辅助函数闪亮登场:
mapState辅助函数
import {
mapState } from 'vuex'
export default {
computed: mapState({
count: state => state.count, //第一种方法
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count', //第二种方法
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount //第三种方法
}
})
}
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
为了与局部计算属性融合,需要用到对象展开运算符
computed:{
a(){
return ...},
b(){
return ...},
c(){
return ...},
...mapState({
//这里的...是对象扩展符
count1:'count1',
count2:'count2',
count3:'count3'
})
}
(对象展开运算符的简单介绍)
对象展开运算符:‘…’, 用于对象融合,举个例子大家就很容易明白
Eg:
let {
x, y, ...z