使用vuexStore.registerModule构建命令式组件
命令式组件
例如Notification, MessageBox, Alert, ConfirmBox 等等
这类组件都是通过命令式来调用.
例如elementUi
中this.$message
或者Message
来调用.
对于我们来说,this.$message
这种调用方法莫过于是最方便.因为不需要处处引入Message
或者在webpack
中配置插件使得Message
暴露于全局
那么我就从this.$message
这类讲起
组件编写
其实也只是编写一个Comp组件, 这里不多说.
接入方式
第一种接入方式
将Vue
组件挂载到一个dom
上,也就是将组件实例化.
然后将组件实例挂载命名空间中或者Vue.prototype
中,
这样相当于直接操作组件实例的methods
来改变组件的状态.
ElementUI
使用的是这种方式.
无入侵式
第二种接入方式
这方式前提必须要使用Vuex, 因为他是依赖vuex.registerStore实现
关于registerStore请移步到文档中
其实就是动态注册一个storeModule, 用来管理组件的状态.
所有操作都通过细改store的状态来引起组件的改变
// 引入组件
import Comp from 'Comp.vue'
function registerModule(store) {
store.registerModule('compNameSpaceState', {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {}
})
}
之后可以将通过对象将调用接口暴露出去
let $compApi = function() {
return {
// 此处需要使用建投函数,确保this指向
action: () => {
this.$store.dispatch('compNameSpaceState/compAction')
}
}
}
接下来很简单,就是将$compApi.prototype中.
那么如何保证$compApi
中this
指向Vue
实例呢
let bind = false
// Vue.use() 会自动调用install方法,此时可以注册组件
Comp.install = function(Vue) {
// 代理带vue原形上.可以通过this.$spin调用
Object.defineProperties(Vue.prototype, {
$compApi: {
// 挂载到Vue.prototype中的$compApi
get() {
if (!bind) {
// 注册store
registerModule(this.$store)
// 只需要绑定一次即可
// 绑定后可以将原来的$compApi覆盖掉
// 调用bind函数确保this指向
$compApi = $compApi.bind(this)()
bind = true
}
return $compApi
}
}
})
// 将组件注册为Vue全局组件
Vue.component('Comp', Comp)
}
export default Comp
最后一步则需要在App.vue将Comp挂载上去
// 这一步自动调用install, 会全局注册Comp
// 但是在第一次调用$compApi时候才会进行registerStore.
Vue.use(Comp)
<!-- App.vue-->
<template>
<Comp />
</template>
这种方法是入侵式的
但是可以很方便的追踪组件状态, 而且实现起来也很方便.
在自己开发组件的时候可以考虑