「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
写在前面
- 前面一篇文章,我们提到了 web compontens 是一套原生 JavaScript 就已经支持组件封装的技术
- 它由三个主要技术组成:自定义元素,HTML 模板,影子 DOM
- 然后我们也介绍了 template 的用法,其实它就是定义通用模板的一个容器,我们可以将模板应用在任何我们需要的地方,并且 template 元素在浏览器渲染页面时不会显示在页面上,只会显示 template 包含的内容
- 上一篇文章最后也提到了经常与 template 搭配使用的 slot 元素
- slot 就是插槽,与 vue 中的插槽类似,也可以使用 具名插槽
匿名插槽
- 话不多说,先写个例子,感受一下原生 JavaScript 实现的插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<my-com myTitle="myCom-title">
<span>这是 s1 具名插槽</span>
<span>这是 s2 具名插槽</span>
<span>这是 s3 具名插槽</span>
</my-com>
</body>
<script>
class MyCom extends HTMLElement {
constructor() {
super();
console.log(this);
// props
const title = this.getAttribute("myTitle");
// template、slot 搭配 shadow dom
const templateDom = document.createElement("template");
templateDom.innerHTML = `
<div>
<h2 class="title">template demo title:${title}</h2>
2222-【<slot></slot>】-2222
<br />
3333-【<slot></slot>】-3333
<br />
1111-【<slot></slot>】-1111
</div>
`;
const divTemplate = templateDom.content;
// open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM
let shadowDom = this.attachShadow({ mode: "open" });
shadowDom.append(divTemplate);
}
}
customElements.define("my-com", MyCom);
</script>
</html>
- 这里使用自定义元素注册了一个 my-com 元素,my-com 关联的 MyCom 为自定义元素的构造函数
- 创建一个 template 标签,并且构建我们的组件的结构标签,然后取出 template 的 content
- 然后通过 shadom dom 技术将 content 添加到自定义元素内部即可
- 这里有写到 shadom dom,是下一篇文章会介绍的知识点,本文先不做过多介绍
- 我们看下现象
- 可以看到,使用匿名插槽时,自定义元素包裹的内容会被放到第一个 slot 中
- 接下来我们看下具名插槽的用法
具名插槽
- 用过 vue 的小伙伴都知道具名插槽的用法,其实这里的用法也是一样的
- 我们先看个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<my-com myTitle="myCom-title">
<div>my-com template</div>
<span slot="s1">这是 s1 具名插槽</span>
<span slot="s2">这是 s2 具名插槽</span>
<span slot="s3">这是 s3 具名插槽</span>
</my-com>
<hr />
<div>other</div>
</body>
<script>
class MyCom extends HTMLElement {
constructor() {
super();
console.log(this);
// props
const title = this.getAttribute("myTitle");
// template、slot 搭配 shadow dom
const templateDom = document.createElement("template");
templateDom.innerHTML = `
<style>
div{
background: teal;
}
</style>
<div>
<h2 class="title">template demo title:${title}</h2>
2222-【<slot name="s2"></slot>】-2222
<br />
3333-【<slot name="s3"></slot>】-3333
<br />
1111-【<slot name="s1"></slot>】-1111
</div>
`;
const divTemplate = templateDom.content;
// open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM
// let shadowDom = this.attachShadow({ mode: "closed" });
// open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM
let shadowDom = this.attachShadow({ mode: "open" });
shadowDom.append(divTemplate);
}
}
customElements.define("my-com", MyCom);
</script>
</html>
- 具名插槽,顾名思义,就是给匿名插槽取个名字
- 我们在使用时,给外部自定义元素子代标签加上 slot 属性
- 其值与 template 内部的插槽 slot 的 name 属性值相同时
- 就会在渲染时将外部的内容渲染到对应的插槽上,以到达具名插槽的作用
小结
- template && slot 通常会一起组合使用
- 并且在与 自定义元素 和 影子 dom 配合时,就可以做出一些有意思的组件
- 在下篇文章中,我们会介绍 影子 dom 也就是 shadom dom 技术的一些知识
最后
- 今天的分享就到这里,欢迎大家在评论区留言讨论
- 如果觉得文章写的还不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰