JavaScript(Ts) 初试使用 Web Components 开发一个 dialog 组件

关于Web Components
Vite为工程依赖
Ts语言开发

<!-- index.html -->
<body>
<button class="open">open</button>
<my-dialog>
    <h1>wo cao nb</h1>
</my-dialog>

<script type="module" src="./src/index.ts"></script>
</body>
/* ./src/index.ts */
class MyDialog extends HTMLElement {
    static componentName: string = 'my-dialog'
    private closeButton: HTMLButtonElement;
    constructor() {
        super();
        const style = `
        :host(:not([open])) {
            display: none;
        }
        :host {
            position: fixed;
            left: 0; top: 0;
            height: 100%; width: 100%;
            background-color: rgba(25, 28, 34, 0.88);
            z-index: 19;
            display: grid;
            place-items: center;
        }
        dialog {
            position: static;
            display: inherit;
        }
        `

        const html = `
        <style>${style}</style>
        <dialog>
            <!-- slot 插槽 作用与 Vue 的 slot 相同-->
            <slot>暂无提示信息</slot>
            <p>
                <button name="close">确定</button>
            </p>
        </dialog>
        `
		// 解析html 字符串 
        const template = document.createRange().createContextualFragment(html)
        const shadowRoot = this.attachShadow({mode: "open"})
        shadowRoot.append(template)

        this.closeButton = this.shadowRoot.querySelector('button[name="close"]')

        this.closeButton.addEventListener('click', this.hide.bind(this))
    }

    hide() {
        this.toggleAttribute('open', false)
    }

    // 连接到 DOM
    connectedCallback() {
        /**
         * 一种常见错误是将 connectedCallback 用做一次性的初始化事件,
         * 然而实际上你每次将节点连接到 DOM 时都会被调用。
         * 取而代之的,
         * 在 constructor 这个 API 接口调用时做一次性初始化工作会更加合适。
         */
    }

    // 从 DOM 上脱离
    disconnectedCallback() {
        this.closeButton.removeEventListener('click', this.hide.bind(this))
    }
}
window.customElements.define(MyDialog.componentName, MyDialog)

const onLoaded = () => {
    const $ = {
        open: document.querySelector('.open'),
        dialog: document.querySelector('my-dialog')
    }

    $.open.addEventListener('click', () => {
        $.dialog.toggleAttribute('open', true)
    })
}

window.addEventListener('load', onLoaded)

image

posted @ 2022-06-29 18:28  demo_you  阅读(220)  评论(0编辑  收藏  举报