实现一个业务组件管理器

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
上一篇下一篇

猜你喜欢

热点阅读