一、组件常用通信方式
1、 props和$emit 2、通过$parent,$root,$children, $refs 3、$attrs 和 $listeners 4、provide和inject 5、事件总线eventbus 6、vuex:Vuex 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以可预测的方式发生变化。
二、五个属性
states:vuex的基本数据,用来存储变量,每当变量变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOMgetters:相当于store的计算属性mutations:更改 Vuex 的 store 中的状态,必须是同步函数actions:异步操作,Action 提交的是 mutation,而不是直接变更状态modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
三、需求分析
实现一个插件,声明store类,挂载$store创建响应式state,保存getters,mutations,actions实现commit根据用户传入type执行对应mutation实现dispatch根据用户传入type执行对应action,同时传递上下文实现getters,按照getters定义对state做派生
四、准备工作
创建一个vue项目,安装vuex;创建一个store/index.js文件,内容如下:
import Vue
from 'vue'
import Vuex
from 'vuex'
Vue
.use(Vuex
)
export default new Vuex.Store({
state
: {
counter
: 0
},
getters
: {
doubleCounter(state
) {
return state
.counter
* 2
}
},
mutations
: {
add(state
) {
state
.counter
++
}
},
actions
: {
add({ commit
}) {
setTimeout(() => {
commit('add')
}, 1000);
}
},
modules
: {}
})
根节点注入store,在main.js文件中添加如下代码;
import store
from './store'
new Vue({
el
: '#app',
router
,
store
,
components
: { App
},
template
: '<App/>'
})
最后在页面中添加测试代码
<p @click
="$store.commit('add')">counter
:{{$store
.state
.counter
}}</p
>
<p @click
="$store.dispatch('add')">async counter
:{{$store
.state
.counter
}}</p
>
<p
>double counter
:{{$store
.getters
.doubleCounter
}}</p
>
在store同一级下,创建xStore文件夹,添加文件index.js和xvuex.js,其中在xvuex.js中实现Store类。然后把项目中所有用到store的,都换成xstore,vuex换成xvuex。
五、实现自己的Store类
声明Store类实现install方法(采用mixin方法获得store实例)
function install(_Vue
) {
Vue
= _Vue
Vue
.mixin({
beforeCreate() {
if(this.$options
.store
) {
Vue
.property
.$store
= this.$optins
.store
}
}
})
}
state的数据是一个响应式数据,可以使用new Vue(),其中data给的值是传进来的state对象;
class Store {
constructor(options
) {
this.state
= new Vue({
data
: options
.state
})
}
}
至此,实现了创建一个响应式state。
实现commit(接收两个参数,一个是type,一个是payload,type是mutation的类型,payload是参数)
commit(type
, payload
) {
const entry
= this._mutations
[type
]
if(entry
) {
entry(this.state
,payload
)
}
}
实现dispatch,类似于commit
dispatch(type
, payload
) {
const entry
= this._actions
[type
]
if(entry
) {
entry(this,payload
)
}
}
实现getters,通过computed来实现,代码如下:
const computed
= {};
this.getters
= {};
const store
= this;
Object
.keys(this.getterWrapper
).forEach(k
=> {
let fn
= store
.getterWrapper
[k
];
computed
[k
] = function() {
return fn(store
.state
)
}
Object
.defineProperty(store
.getters
,k
,{
get: () => store
._vm
[k
]
})
})
到此基本实现vuex功能。