美文网首页
实现一个业务组件管理器

实现一个业务组件管理器

作者: jluemmmm | 来源:发表于2020-08-12 08:11 被阅读0次
    /**
     * @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
    

    相关文章

      网友评论

          本文标题:实现一个业务组件管理器

          本文链接:https://www.haomeiwen.com/subject/vyxpdktx.html