实现一个业务组件管理器
2020-08-12 本文已影响0人
jluemmmm
/**
* @description 业务组件管理器
* @method registre
* @method getConText
* @method render
* @method run
* @class ComponentManager
*/
import EventEmit from 'xxx'
function noop() {}
const DEFAULTOPTION = {
deffer: '',
name: '',
component: '',
data: {},
onReady: noop,
onRendered: noop,
onUpdated: noop,
onDestoryed: noop
}
class ComponentManager {
constructor (context = {}) {
this.component = {}
this.parentContext = context
}
registe(options = {}) {
let el = document.querySelector(`*[component='${options.name}']`)
if(!el) return
//添加自定义事件通知回调
this._analyseEvent(el)
//实例化组件
let comInstance = new options.component(el, options.name, typeof options.data !== 'object' ? {} : options.data)
//注册生命周期的回调函数
this._bindLifeCycleEvent(options)
//初始化组件
comInstance.init && comInstance.init()
this.components[options.name] = {
instance: comInstance,
options,
el,
isDeffer: options.deffer
}
return comInstance
}
_bindLifeCycleEvent(options) {
EventEmit.instance.on(`${options.name}`, options.onReady || noop)
EventEmit.instance.on(`${options.name}`, options.onRendered || noop)
EventEmit.instance.on(`${options.name}`, options.onUpdated || noop)
EventEmit.instance.on(`${options.name}`, options.onUpdated || noop)
EventEmit.instance.on(`${options.name}`, options.onDestoryed || noop)
EventEmit.instance.on(`${options.name}`, options.onDataReady || noop)
}
/**
* 解析组件沙盒上需要定义的事件名, 仅支持一个.once的修饰符
*/
_analyseEvent(el) {
let attrs = [...el.attriburtes]
let props = {}
attrs.forEach( attr => {
// attr.name为标签上的属性名称, nodeValue为属性值
let matched = attr.name.match(/^bind:([-_a-z0-9$]+)(\.\w+)?/i)
if(matched && matched.length) {
let eventName = matched[1]
props[eventName] = {
callback: attr.nodeValue,
modifier: matched[2] ? matched[2].replace('.', '') : ''
}
}
})
Object.keys(props).forEach(key => {
let modifer = props[key].modifier
let callbackName = props[key].callback
if (modifer === 'once') {
EventEmit.instance.once(key, typeof this.parentContext[callbackName] === 'function' ? this.parentContext[callbackName] : noop)
} else {
EventEmit.instance.on(key, typeof this.parentContext[callbackName] === 'function' ? this.parentContext[callbackName] : noop)
}
})
}
/**
* 获取某个组件上下文
*/
getContext(name) {
const current = this.components[name]
if (!current) {
throw new Error(`没有找到${name}组件`)
}
return current.instance
}
/**
* 渲染指定组件
* @param {String} name 要渲染的组件名
* @param {Object} data 要传输给组件的数据
*/
render(name, data = {}) {
let context = this.getContext(name)
context.render(data)
}
run() {
for (const cname in this.components) {
// 如果不是动态组件,马上渲染
if (!this.components[cname].isDeffer) {
this.components[cname].instance.render()
}
}
}
}
export default ComponentManager