1.Vuex概述
1.1组件之间共享书记的方式
父向子传值 v-bind 子向父传值 v-on 兄弟组件之间共享数据:EventBus
1.2 vuex是什么
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
1.3 vuex统一管理状态的好处
- 能够在vuex中管理共享数据,易于开发和后期维护
- 能够搞笑地实现组件之间的谁共享,提升开发效率
- 存储在vuex中的数据都是响应式的,能狗保持数据与页面的同步
1.4 什么样的数据适合存储在vuex中
一般情况喜爱,只有组件之间共享的数据,才有必要存储在vuex中,对于组件中的私有数据,依旧存储在自身的data中。
2 vuex基本使用
- 安装vuex依赖包
npm install vuex --save
- 导入vux包
import Vuex from 'vux'
Vue.use(Vuex);
- 创建一个store对象
const store = new Vux.Store({
// state中存放的就是全局共享的数据
state: {
count: 0
},
// 用于修改Store中的数据
mutation: {}
})
- 将store对象挂载到vue实例中
new Vue({
el: '#app',
render: h => h(app),
router,
store
})
3 vuex的核心概念
3.1 State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储
const state = new Vux.Store{{
state: {
cousnt: 0
},
// 不能在mutation中不能执行异步操作
mutation: {
add(state) {
state.count++;
},
addN(state, step) {
state.count += step;
}
},
// 处理异步操作
actions: {
addAsync(context) {
setTimeout(() => {
// 在Action中,不能直接修改state中的数据
// 必须通过context.commit()触发mutation
context.commit('add');
}, 1000)
},
addAsyncN(context, step) {
setTimeout(() => {
// 在Action中,不能直接修改state中的数据
// 必须通过context.commit()触发mutation
context.commit('addN', step);
}, 1000)
}
}
}}
组件中访问State中数据的第一种方式
this.$state.state.全局数据名称
组件中访问State中的第二个方式
import {mapState} from 'vuex';
通过导入的mapState函数,将当前组件需要的全局数据,映射到当前组件的computed计算属性
computed: {
...mapState(['count'])
}
3.2 Mutation
用于变更Store中的数据
- 只能通过mutation变更Store数据,不可以直接操作Store中的数据
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
触发mutation的第一种方式-this.$store.commit() 组件中
methods: {
add() {
this.$store.commit('add');
},
addN() {
this.$store.commit('add', 3)
}
}
触发mutation的第二种方式-mapMutation
组件中导入mapMutation
import {mapMutations} from 'vuex';
通过mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法:
methods: {
...mapMutations(['add', 'addN'])
}
3.3 Action
Action用于处理异步任务。
提过通过异步操作变更数据,必须通过Action,而不能同时用Mutation,但是Action中还是要通过触发Mutation的方式间接变更数据。
组件中触发action的第一种方式-this.$store.dispatch()
methods: {
addAsync() {
this.$store.dispatch('addAsync')
},
addAsyncN() {
this.$store.dispatch('addAsyncN', 3);
}
}
组件中触发action的第二种方式-mapActions
import {mapActions} fron 'vuex';
……
methods: {
...mapActions(['addAsync', 'addAsyncN'])
}
3.4 Getter
Getter用于对Store中的函数进行加工处理形成新的数据
- Getter可以对Store中已有的数据加工处理后形成新的数据,类似Vue的计算属性
- Store中的数据发狠恶搞变化,Getter的数据也会跟着变化
const store = new Vuex.Store({
state: {
count: 0
},
getters: {
showNum: state => {
return `当前最新的数据量是【${state.count}】`
}
}
})
使用getter的第一种方式-this.$store.getters.名称
使用getter的第二种方式-mapGetters
import {mapGetters} from 'vuex'
……
computed: {
...mapGetters(['showNum'])
}
4 手写vuex
let Vue;
const Store {
constructor(options = {}) {
this.state = options.state;
// Vuex的核心,实现数据响应式
this.s = new Vue({
data() {
return {state: options.state}
}
});
// state
get state() {
return this.s.state;
}
// getters 对象
let getters = options.getters;
this.getters = {};
Object.keys(getters).forEach((getterName) => {
Object.defineProperty(this.getters, getterName,
{
get: () => {
return getters[getterName](this.state)
}
}
)
});
let mutations = options.mutations;
this.mutations = {}
Object.keys(mutations).forEach(mutationName => {
this.mutations[mutationName] = (payload) => {
mutations[mutationName](this.state, payload)
}
});
commit(mutationName, payload) {
this.mutations[mutationName](payload);
}
let actions = options.action;
this.actions = {};
Object.keys(actions).forEach(actionName => {
this.actions[actionName] = (payload) => {
actions[actionName](this, payload);
}
});
dispatch(actionName, paylod) {
this.actions[actionName](paylod);
}
}
}
const install = function(_vue) {
Vue = _Vue;
// 混入生命周期
Vue.mixin({
// new Vue的时候,和app渲染的时候都会执行,工作还行两次
beforeCreate() {
if(this.$option && this.$option.$store) {
this.$store = this.$options.store;
}
else {
this.$store = this.$parent && this.$parent.$store;
}
// 为什么不挂在Vue.prototype
// 1. new Vue()每个实例都会带store
// 2. 不会污染原型
// 3. 单独创建的实例,没有父亲,没有store
}
})
console.log('install')
}
export default {
install,
Store
}