最近开发一个前端工具,需要使用原生 JS 来开发组件,在开发一个下拉选择组件的过程中,一开始更新组件的功能——比如点击下拉列表选项更新选中状态,实现方式就是监听下拉列表选项的点击事件,然后修改当前选中的内容以及下拉列表中选中的内容。
这样的实现方式是常规实现,通过不断的操作 dom 来实现功能。但是这样的实现有个问题就是 dom 操作过多,可能就会出现一些没考虑到的细节操作的 BUG。并且逻辑会很复杂。然后就记得很久以前用的一个前端模板渲染库的实现,通过清空 dom 再重绘 dom 实现更新,这就能极大的简化逻辑,也和现在的各种前端框架的思想一致——通过状态来渲染 dom,状态更新重绘 dom。
在构造函数中创建一个容器来存放实际的组件,把创建容器和组件的功能分开,因为实现更新功能只需要创建组件。
// [{ icon, value: 'xxx', label: 'yyy', selected: true }] constructor(options) { // 创建一个容器,将组件内容放于容器中,更新组建就清空容器内容再通过新的状态创建组件,而不是通过操作 dom 细节来更新组件 this.createContainer(); this.init(options); }
init 方法就是创建组件,options 就是接收到的组件状态,通过 options 创建这个下拉选择功能组件
init(options) { this.options = options; this.options.forEach((option, i) => { if (option.selected) { this.selectIndex = i; } }); this.optionsBtn = []; this.createElement(); this.addEvent(); }
更新组件的时候就清空容器再创建组件实现组件的更新
update(options) { this.elem.innerHTML = ''; this.init(options || this.options); }