Vuex采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
安装
直接下载CDN引用
//可以通过@来指定版本号
<script src='https://unpkg.com/vuex@2.0.0'></script>
通过npm下载
npm i vuex --save
核心属性
State
- 用来存储共享的数据属性或状态
- 可以使用mapState 辅助函数简化写法
Getters
- 相当于计算属性,它的返回值会根据它的依赖被缓存起来,只有依赖值发生了变化才会重新计算。
- Getter接受state作为第一个参数
- 可以使用mapGetters辅助函数简化写法
Mutaions
- 必须为同步函数
- 在组件中使用this.$store.commit('xx')来触发
- 可以使用mapMutations辅助函数简化写法
Actions
- Action提交的是mutation,由mutation中的函数来修改state中的属性或状态
- 可以包含任意异步操作
- 在组件中使用this.$dispath('xx')来触发
- 可以使用mapActions辅助函数简化写法
Modules
- 允许将store分割成模块,每个模块拥有自己的state,getters,mutation,action
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const moduleA = {
state: () => {...},
mutaions:: {...},
actions: {...},
getters: {...}
}
const store = new Vuex.Store({
state: {
count: 0,
list: [{
id: 1, text: 'xiaoyao'
}, {
id: 2, text: 'xianshi'
}],
},
getters: {
filterList: state => state.list.filter(item => item.id === 1),
//通过函数的方式获取值
getList: (state) => (id) => state.list.find(item => item.id === id),
},
mutations: {
//payload 可以是对象
increment (state, payload) {
state.count += n;
}
},
actions: {
setIncrement(context, payload) {
setTimeout(()=>{
context.commit('increment', n)
})
}
},
modules: {
a: moduleA
}
})
需要先在根实例中注册stroe
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
//在组件中使用
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
},
mapState({
count: state => state.count
}),
obj() {
return this.$store.getters.filterList
},
...mapGetters(['filterList', 'getList']),
//给getters取别名
...mapGetters({doneFilter: 'filterList'}),
},
methods: {
...mapMutations(['increment']),
...mapMutations({add: 'increment'}),
sum() {
this.$store.commit('increment', 2);//this.add(2)
},
...mapActions(['setIncrement']),
...mapActions({
add: 'increment'
}),
setCount() {
this.$store.dispach('setIncrement', 2)
}
}
}
双向数据绑定原理2.x
Vue 主要通过以下 4 个步骤来实现数据双向绑定的:
- 实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
- 实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
- 实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
- 实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。