Vuex 原理
2019-12-13 本文已影响0人
Do_Du
1、Vue.use(Vuex)
:将Vuex 应用到Vue中
use是一个自定义插件,这个插件里有一个固定方法install(),这句话的意思是调用这个自定义插件install方法
2、export default new Vuex.Store({
Store:就是用来存储数据的,以及提供数据访问接口
3、模拟Vuex原理
在store - vuex.js 中
改变引入路径 如下:
image.png
// 自定义 vuex
var Vue // 设置全局对象Vue 存储下来vue对象
// 数据存储类
class Store {
constructor(options) { // 构造函数;new 类Store会初始化构造函数; options即为new Vuex时传的state、mutations、actions等参数
// state
this.vm = new Vue({ // 实例化一个Vue对象,将 外面 Vuex的参数传进来
data: {
state: options.state // 将 Vuex的参数 state 传进来,为的是实现数据的监听
}
})
// getters
const getters = options.getters
this.getters = {}
Object.keys(getters).forEach(getterName => { // getterName是myNum
Object.defineProperty(this.getters, getterName, { // es5 添加对象属性: 给this.getters添加 getterName的属性
get: () => { // getterName 属性 添加查询方法get
return getters[getterName](this.state) // getters[getterName]:拿到方法 myNum,传入参数(this.state)
}
})
})
// mutations 同步
const mutations = options.mutations
this.mutations = {}
Object.keys(mutations).forEach(mutationName => {
this.mutations[mutationName] = (params) => {
mutations[mutationName](this.state, params)
}
})
// actions 异步
const actions = options.actions
this.actions = {}
Object.keys(actions).forEach(actionName => {
this.actions[actionName] = (params) => { // this.actions[actionName]: 给当前对象this.actions 添加函数,函数名是actionName
actions[actionName](this, params) // 真正执行的函数 是外面传进来的
}
})
}
dispatch(type, params) { // 异步增加
this.actions[type](params)
}
commit = (type, params) => { // 同步增加 箭头函数 this不会变
this.mutations[type](params)
}
get state() {
return this.vm.state
}
}
// 插件需要
const install = (v) => {
// console.log(v) // 打印出来这个v就是Vue对象
Vue = v // 使用全局对象Vue存储下来
// 这个插件的作用:需要在所有的组件中添加$store对象
// 才能让所有的组件中使用this.$store.commit()调用方法
// 所有的根组件和子组件中,跟组件是在main.js中引入store,子组件呢,子组件通过mixin方法找到
Vue.mixin({ // Vue 提供的方法 混合,通过这个可以给每个子组件加上store属性
beforeCreate() { // 组件初始化之前 添加生命周期
// this: 当前实例对象,每个组件都有一个options - name : 组建的名字
// 打印出 undefined 和 APP
// undefined 是根组件,即 main.js
console.log(this.$options.name)
// 只有根节点有store 存在参数配置项且store存在 把根节点的store赋值给新命名的对象$store
if (this.$options && this.$options.store) { // 判断当前是父节点 root
this.$store = this.$options.store
} else { // 判断当前是子节点 child 父节点存在 并且 父节点的$store对象存在 就赋值
this.$store = this.$parent && this.$parent.$store
}
}
})
}
export default { install, Store }
image.png
注意:
根组件是:main.js
默认情况下子组件是:App.vue
若给根组件main.js 加上name,则 this.$options.name
打印出 Root 和App