1、原生也有组件?
现在Vue、React的大规模流行。前端组件化已经成为潮流,但是原生的组件又有多少人了解了。下面通过几个代码示例,让你快速了解原生怎么写组件。
2、通过继承 HTML 实现组件
// 通过继承 HTMLImageElement 实现组件化class MyImg extends HTMLImageElement {constructor() {super()const src = 'https://resource.ttplus.cn/publish/app/pics/2019/04/18/233772/76d96560-7211-483d-988c-dc00d8391f41.jpg'setTimeout(() => {// this 指向继承后的新组件this.src = src}, 1000)}}// 组件名字 继承后的类 需要继承的标签customElements.define('my-img', MyImg, {extends: 'img',})
使用的时候只需要在你继承的标签中,is="你的组件名" 即可
<img is="my-img" />
3、独立的组件
demo2.html
<style>/* 样式隔离,无法操作 MyCom 内部的样式 */.my_com_main {background: pink;}</style><my-com class="my_com" cusAttr="我是自定义属性"><span slot="middle">我是主要内容</span><h2 slot="bottom">我是底部</h2><div slot="head">我是头部插槽</div></my-com><script type="module" src="./demo2.js"></script>
MyCom.js
const template = document.createElement('template')template.innerHTML = `<style>.my_com_wrapper {border: 1px solid red;}.my_com_main {height: 100px;background: skyblue;}</style><div class="my_com_wrapper"><header><slot name="head"></slot></header><main class="my_com_main"><slot name="middle"></slot></main><footer><slot name="bottom"></slot></footer></div>`class MyCom extends HTMLElement {constructor() {super()// 获取自定义组件的属性console.log(this.getAttribute('class'))console.log(this.getAttribute('cusAttr'))// 使用 attachShadow 与外面样式进行隔离const sd = this.attachShadow({ mode: 'open' })sd.appendChild(template.content)}}customElements.define('my-com', MyCom)
demo2.js
import './MyCom.js'const myComEl = document.querySelector('.my_com')// 当 attachShadow 的 mode 为 open 时,可以获取 shadowRoot 的内容并且操作。// 如果 mode 为 closed 则无法获取该节点信息console.log(myComEl.shadowRoot)const myColElChildren = myComEl.shadowRoot.children![...myColElChildren].forEach(el => (el.style = 'font-size: 40px;'))
4、如何实现自定义事件
通过 EventTarget 添加自定义事件。在通过 dispatchEvent 触发 CustomEvent 事件。
<button id="btn_a">自定义事件a</button><button id="btn_b">自定义事件b</button><script type="module">// 创建事件const obj = new EventTarget()// 添加事件obj.addEventListener('a', () => alert('触发了事件a'))obj.addEventListener('b', () => alert('触发了事件b'))document.querySelector('#btn_a').onclick = () => {obj.dispatchEvent(new CustomEvent('a'))}document.querySelector('#btn_b').onclick = () => {obj.dispatchEvent(new CustomEvent('b'))}</script>
5、实现简易版Dialog组件
由于代码太多,直接放链接了
