在前端开发过程中组件的抽离是非常有必要的,我们在使用 Vue
、React
等开发的时候,组件的开发是必须的,我们常常将一些通用的逻辑抽象为组件。
纯前端的开发的时候,我们添加节点有两种方式,一种是使用 appendChild
,另一种则是常用的 innerHTML
所以我们的组件都应该做到能够被 appendChild
和 innerHTML
的形式添加到节点,所以这就需要我们抽离一个基础组件,该组件具有获取组件节点或者节点字符串的函数。基于此,我们的一个基础组件应该类似于下面的:
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
用于获取节点,如果传递的 el
是 HTMLElement
节点则直接返回,如果是 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
}