且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

前端模块化之基础组件

更新时间:2022-08-13 10:37:44

在前端开发过程中组件的抽离是非常有必要的,我们在使用 VueReact 等开发的时候,组件的开发是必须的,我们常常将一些通用的逻辑抽象为组件。
纯前端的开发的时候,我们添加节点有两种方式,一种是使用 appendChild,另一种则是常用的 innerHTML 所以我们的组件都应该做到能够被 appendChildinnerHTML 的形式添加到节点,所以这就需要我们抽离一个基础组件,该组件具有获取组件节点或者节点字符串的函数。基于此,我们的一个基础组件应该类似于下面的:

class Component<T extends HTMLElement> {
  protected el: T

  public constructor(el: string | HTMLElement) {
    this.el = queryElem(el)
  }

  public node() {
    return this.el
  }

  public toString() {
    return this.el.outerHTML
  }
}

其中的 queryElem 用于获取节点,如果传递的 elHTMLElement 节点则直接返回,如果是 string 类型,则表示为 css 选择器,根据选择器获取节点,同时该函数还具有一个回退的,如果没有获取到节点时,则传递一个没有添加到页面的节点,作为承载节点,所以整理后的函数如下:

function queryElem(el: string | HTMLElement, tagName = 'div') {
  let qel: HTMLElement
  // 传递的是 `css` 选择器
  if (typeof el === 'string') {
    if (el.trim() === '') {
      qel = document.createElement(tagName || 'div')
    } else {
      let els = document.querySelector(el)
      if (els != null) {
        qel = els as HTMLElement
      } else {
        qel = document.createElement(tagName || 'div')
      }
    }
  } else {
    // 传递的本来就是节点,则直接返回
    qel = el
  }
  return qel
}

所以整理后的基础组件如下:

class Component<T extends HTMLElement> {
  protected el: T

  public constructor(el: string | HTMLElement, tagName?: string) {
    this.el = queryElem(el, tagName) as T
  }

  public node() {
    return this.el
  }

  public toString() {
    return this.el.outerHTML
  }
}

后续我们的所有的组件都继承该继承节点例如:

class Button extends Component<HTMLButtonElement> {
  public constructor(el: string, config: object){
    super(el)
  }

  public xxx() {
    this.el
  }