Vuex知识点

写在前面

1、Vuex官方说法:一个专为 Vue.js 应用程序开发的状态管理模式。采用集中式存储管理应用的所有组件的状态。说白点就是在一个地方管理所有组件的数据。
2、Vue的思路:当改变数据时,页面会跟着变化,但是用户操作页面时,不会自动改变数据。所以Vuex是Vue用来单向绑定数据的。
3、为什么又要单向绑定数据:为了「控制欲」,双向绑定意味着你不知道 data 什么时候就变了(when),也不知道是谁变的(who),变成了什么也不通知你(what)。当然你可以加一个 watch 来监听 data 的变化。但这就显得很复杂了。单向绑定牺牲一部分的便捷性,换来更大的「控制力」。

1、安装

安装Vuex

1
npm install vuex --save

2、创建index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//src/store/index.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex) //通过全局方法 Vue.use() 使用插件,插件会为Vue添加全局功能

export default new Vuex.Store({
state: { //这里是用来放数据的,将组件中data里的数据全放到这里
count: 0
},
mutations: { //这里用来定义方法,当监听到要触发该事件时,就可以调用方法
increment (state,value) {
state.count+=value
}
}
})

3、将index引入到App.vue中

1
2
3
4
5
6
7
8
9
10
//App.vue
<script>
import store from './store/index'
export default {
name: 'app',
store,
//+这里添加store,相当于store:store,这可以把 store 的实例注入所有的子组件,子组件能通过 this.$store.state.count 访问到index.js里所有的数据

}
</script>

4、子组件拿到数据

虽然子组件可以用this.$store.state.count拿到数据,但是太麻烦了,所以可以放到子组件的计算属性里去

1
2
3
4
5
6
computed: {
count () {
return this.$store.state.count
}
},
//引用的时候就可以直接{{count}}

5、子组件如何修改this.$store.state的数据

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,通过计算属性的set来提交mutation

1
2
3
4
5
6
7
8
9
10
11
computed: {
count () {
get(){
return this.$store.state.count
},
set(value){
return this.$store.commit('increment', value)
//第一个参数为mutation里的属性,value为传入额外的参数,即载荷
}
}
},

6、Vuex为单向绑定,所以要解决用户操作修改数据

通过给元素添加事件监听,触发计算属性中的set来提交mutation

1
<input type="text" :value="value"  @input="count = $event.target.value">

7、Vuex其他核心概念(上面说了2个:State,Mutation)

1、Getter

有时候需要从 store 中的 state 中派生出一些状态,比如对state里的数据再进行一次筛选,就会用到Getter,它可以认为是 store 的计算属性,写在index.js里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//src/store/index.js
export default new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: (state,value)=> { //可接受2个参数
return state.todos.filter(todo => todo.done)
},
}
})
//子组件调用store.getters.doneTodos -> [{ id: 1, text: '...', done: true }]

2、Action

Action 类似于 mutation,Action 提交的是 mutation,而不是直接变更状态。而且可以包含任意异步操作。乍一眼看上去感觉多此一举,我们直接分发 mutation 岂不更方便。其实mutation必须同步执行,所以需要Action的存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//src/store/index.js
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
//Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

3、Module

将store的所有东西放在一个花括号,为了防止太累赘了,Vuex 允许我们将 store 分割成模块(没用过,改天试试)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}

const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
export default new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
//store.state.a // -> moduleA 的状态
//store.state.b // -> moduleB 的状态