Vue
Vue中最重要的就是数据驱动和组件化,每个组件都有自己的data,template,methods。
Vuex
进行状态管理,负责组件中的通信。
多个视图依赖同一状态;
来自不同视图的行为需要变更同一状态;
Vue的插件;
插件一般用来给Vue添加全局功能。
- 使用插件
Vue.use(myPlugins),把插件注册到Vue上。该方法执行时,会触发插件的install方法初始化,并将Vue作为参数传入。 - 开发插件:
vue.js的插件,有公开方法install,该方法的第一个参数是Vue的构造器,第二个是可选的选项对象。
myPlugins.install=function(Vue,options){
//...
}
Vuex的使用:
1. 创建store.js文件
点击查看代码
- import Vue from 'vue';
- import Vuex from 'vuex';
- Vue.use(Vuex);
//结构
- const store= new Vuex.Store({
state:{},
getters:{},
mutations:{},
actions:{},
})
- export default store;
2. main.js文件中引入
import store from './store';
挂载到Vue实例中;
new Vue({
store,
render: (h) => h(App),
}).$mount('#app')
- this.$store.xxx
Vuex插件的开发;
依赖于vue的双向数据绑定和插件系统;
首先必须有插件的install方法,
其次根据Vuex的结构可知Store是类。
-
class Store{
constructor(options){},
//...
}
function install(Vue){
//...
}
export default {
Store,
install
};
方法install的实现
Vue中加入参数store,但只有根组件有store,其他组件没有,需要让其他组件也有这个参数。
利用Vue.mixin()混入,将内容混入到Vue的初始参数。
点击查看代码
- function install(Vue) {
Vue.mixin({
beforeCreate() {//created时 options已经初始化完
if (this.$options && this.$options.store) {//根组件
this.$store = this.$options.store;
} else { //子组件 C=A && B : A true->get B
// 判定是子组件,就能直接拿到父组件的store? -- 父子组件执行顺序
this.$store = this.$parent && this.$parent.store;
}
}
})
}
父子组件执行顺序:
父、子组件执行顺序:
父beforeCreate-> 父created -> 父beforeMounte
-> 子beforeCreate ->子create ->子beforeMount ->子 mounted
-> 父mounted
类store的实现
基于以下
-
new Vuex.Store({
state: {
num:0,
},
getters:{
getNum(state){
//...
}
},
mutations:{
setNum(state,val){
//...
}},
actions:{}
}) -
state
this.$store.state
借助vue的数据是响应式的构造。new Vue()传入state的值。
class Store{
constructor(options){
this.state=options.state||{};
}
} -
getters
this.$store.getters.
Object.defineProperty();
对类store中传入的options的getters的每个函数劫持。
getters(state){
}
- mutations 同步
和getters实现方法一致。
setNum(state,args){
}
调用时:
- this.$store.commit(mutationName,args);
构造commit方法。
- actions 异步
addNum(context,args){
context.commit(xx);
}
或者解构
addNum({commit},args){
commit(args);
}
- this.$store.dispatch(actionName,args);
mapGetters,mapMutations,mapActions。
扩展
Object.create();
双向数据绑定:
数据劫持和添加观察者。
代码实现
点击查看代码
let Vue
//myVuex.js
class Store {
constructor(options) {
this.vm = new Vue({
data: {
state: options.state
}
})
let getters = options.getter || {}
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] = (arg) => {
mutations[mutationName](this.state, arg)
}
})
let actions = options.actions
this.actions = {}
Object.keys(actions).forEach(actionName => {
this.actions[actionName] = (arg) => {
actions[actionName](this, arg)
}
})
}
//dispatch,commit是方法;其余getter,state是属性!!!
dispatch(method, arg) {
this.actions[method](arg)
}
commit = (method, arg) => {
console.log(method);
console.log(this.mutations);
this.mutations[method](arg)
}
get state() {
return this.vm.state
}
}
let install = function (vue) {
Vue = vue
Vue.mixin({
beforeCreate() {
//因为vue实例会加入store,$options的意思就是vue实例的参数
//该步骤的目的是让this.$store能直接访问到
if (this.$options && this.$options.store) {
this.$store = this.$options.store
} else {
//let c= a && b; a为true则 c=b; ||时 相反
this.$store = this.$parent && this.$parent.$store
}
}
})
}
let Vuex = {
Store,
install
}
export default Vuex