Web Components编写自定义组件

组成

Web Components 由三部分组成

  • Custom element(自定义元素)
  • Shadow DOM(影子 DOM: 使组件保持独立,解决冲突的
  • HTML template(HTML 模板):作为组件的基础,能够被复用
  • HTMLImports 弃用

示例

编写一个user-info组件

 第五步 使用自定义标签
 <user-info></user-info>
 第一步 编写template组件模板
<template id="userInfo">
	<style>
		.container {
			width: 100px;
			height: 100px;
			background-color: antiquewhite;
		}
	</style>
	<div class="container">
		<p>username</p>
		<p>email</p>
		<p>password</p>
	</div>
</template>
<script>
第二步 编写自定义组件
class UserInfo extends HTMLElement {
	static get Tag_Name() {
		return "user-info"
	}
	constructor() {
		super()
		第三步 使用影子dom,将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离
		const template = document.querySelector("#userInfo")
		const shadow = this.attachShadow({ mode: "closed" })
		const content = template.content.cloneNode(true)
		shadow.appendChild(content)
	}
}
第四步 注册组件
customElements.define(UserInfo.Tag_Name, UserInfo)
</script>

思考:为什么不直接使用template.content而要使用cloneNode呢?
因为这个模板可能会被更多的customElement使用,自定义组件只能修改副本,不能更改本体。

template与slot

slot就是一个占位标签,你可以选择替换它,如果不替换他将显示默认内容

<M-div>
	<ul slot="default">
		随便一个带slot属性的标签去替换slot标签
		<li>Let's have some different text!</li>
		<li>In a list!</li>
	</ul>
</M-div>
<template id='Mdiv'>
	<slot name='default'>slot标签里面的是默认内容</slot>
</template>

模板分离

前面我将组件放在了同一个文件中,但实际情况组件应该是一个独立的文件。
在以前我们可以使用<link rel="import" href="component.html"> ,但是现在HTML import已经被弃用了,
我们可以使用es module,但是es module属于js模块方案,它并不支持template 这种html的模板语法,我们只能使用纯js了。

  1. 编写js Web Components 组件
let template = `
        <template id='userInfo'>
          <style>
            .user-info{
              width:100px;
              height:100px;
              background-color:blue;
            }
          </style>
          <div class='user-info'>
            <p>username</p>
            <p>password</p>
          </div>
        </template>
      `
const parser = new DOMParser()
const doc = parser.parseFromString(template, "text/html")
const temp = doc.getElementById("userInfo")
class userInfo extends HTMLElement {
	constructor() {
		super()
		const shadow = this.attachShadow({ mode: "closed" })
		const content = temp.content.cloneNode(true)
		shadow.append(content)
	}
}
customElements.define("user-info", userInfo)
export default userInfo

注意:我这里解析字符串用的是DOMPaser,这个api返回的是一个document对象并不是一个dom,这个需要注意
2. 现在就可以使用这个组件了

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		 这里使用的是es module
		<script type="module" src="./component.js"></script>
	</head>
	<body>
		直接使用这个组件
		<user-info></user-info>
		<script></script>
	</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值