foreword
In the previous section, the basic layout of MyCard was implemented using Templates, and I also said at the end of the article that because it is not reusable, its practicality is basically zero.
Today we improve the flexibility of custom elements by using named Slots to occupy places in Templates, and then pass values to Slots in custom elements.
pass-by-value analysis
Because each person's information is different, and corresponding to Templates, that is, the contents of all divs whose className is .info-content
are variable. All variable values are summarized as follows:
- userName
- gender
- nation
- birthYear
- birthMonth
- birthDay
- address
- cardNO
That is to say, for each Card, the above property values need to be passed in the custom component.
Custom attributes using HTML tags
To give custom components, in addition to Slots, you can also use custom attributes of HTML tags.
Step 1: We add an id tag to the variable item parent tag inside Templates, for example:
<div class="info-content" id="user_name">编程三昧</div>
Step 2: Get its own user-defined properties inside the custom component:
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let tempEle = document.getElementById("card_layout");
this.shadow.appendChild(tempEle.content);
// 获取并填充姓名
let userName = this.getAttribute("userName") || "编程三昧";
this.shadow.querySelector("#user_name").textContent = userName;
// 剩余可变项的获取和设置是一样的流程
}
}
Step 3: Add the corresponding custom attribute to the label of the custom element:
<my-card userName="隐逸王"></my-card>
Through the above steps, it is also possible to achieve the effect of custom components passing values, so as to achieve the purpose of component reuse.
Passing Values Using Named Slots
Although the custom attribute of the HTML tag is used above to achieve the purpose of passing the value, the code in the JS part does not look very beautiful. Let's use the method of passing the value of Slots to implement a version.
Step 1: Add named slots to Templates for placeholders.
<template id="card_layout">
<style>
* {
box-sizing: border-box;
}
:host {
display: inline-block;
width: 400px;
height: 240px;
border: 1px solid black;
border-radius: 10px;
box-shadow: -2px -2px 5px 0px #7a8489;
}
.container {
display: flex;
flex-direction: column;
padding: 10px;
height: 100%;
}
.card-body {
flex: 1;
display: flex;
}
.card-footer {
padding: 10px 0;
}
.main-info {
flex: 2;
}
.photo {
flex: 1;
display: flex;
align-items: center;
}
.photo img {
width: 100%;
}
.info-row {
display: flex;
padding-top: 15px;
}
.info-column {
display: flex;
align-items: center;
}
.info-title {
padding: 0 10px;
color: #0e5bd3;
font-size: 12px;
word-break: keep-all;
}
.info-content {
letter-spacing: 2px;
}
</style>
<div class="container">
<div class="card-body">
<div class="main-info">
<div class="info-row">
<div class="info-column">
<div class="info-title">姓名</div>
</div>
<div class="info-content">
<slot name="userName">隐逸王</slot>
</div>
</div>
<div class="info-row">
<div class="info-column">
<div class="info-title">性别</div>
<div class="info-content">
<slot name="gender">男</slot>
</div>
</div>
<div class="info-column">
<div class="info-title">民族</div>
<div class="info-content">
<slot name="nation">汉</slot>
</div>
</div>
</div>
<div class="info-row">
<div class="info-column">
<div class="info-title">出生</div>
<div class="info-content">
<slot name="birthYear">2022</slot>
</div>
</div>
<div class="info-column">
<div class="info-title">年</div>
<div class="info-content">
<slot name="birthMonth">12</slot>
</div>
</div>
<div class="info-column">
<div class="info-title">月</div>
<div class="info-content">
<slot name="birthDay"></slot>
</div>
</div>
<div class="info-column">
<div class="info-title">日</div>
</div>
</div>
<div class="info-row">
<div class="info-column">
<div class="info-title">住址</div>
</div>
<div class="info-content">
<slot name="address">xx省xx市xx区xx街道xx小区xx楼xx单元xx楼xx室</slot>
</div>
</div>
</div>
<div class="photo">
<img src="./static/photo.jpg">
</div>
</div>
<div class="card-footer">
<div class="info-row">
<div class="info-column">
<div class="info-title">公民身份号码</div>
</div>
<div class="info-content">
<slot name="cardNO">12345678901234567X</slot>
</div>
</div>
</div>
</div>
</template>
Step 2: Insert the label and content with the slot=‘’
attribute in the custom element label.
<my-card>
<span slot="userName">编程三昧</span>
<span slot="gender">男</span>
<span slot="nation">汉</span>
<span slot="birthYear">2002</span>
<span slot="birthMonth">2</span>
<span slot="birthDay">2</span>
<span slot="address">银河系太阳系地球村亚洲中国美丽小区</span>
<span slot="cardNO">134098567432129485-ZH</span>
</my-card>
The final effect is as follows:
Implement a web page to display multiple MyCards
If you want to display multiple cards on the same page at the same time, if you use the above code, you will find that only the first one has content, and the rest are empty. This is because the first MyCard instance appends the contents of Templates to itself, and the tempEle.content
obtained by the other instances are all empty nodes.
To solve this problem, you need to clone the Templates content inside the MyCard constructor instead of using it directly:
class MyCard extends HTMLElement {
constructor () {
super();
this.shadow = this.attachShadow({mode: "open"});
let tempEle = document.getElementById("card_layout");
this.shadow.appendChild(document.importNode(tempEle.content,true));
}
}
customElements.define("my-card", MyCard);
Summarize
This article uses two ways to pass values to custom components:
- HTML tag custom attribute pass value
- Named Slots by value
Both can be used, depending on the situation and personal preference.
In addition, there is one more detail to pay attention to: appendChild()
method will move the entire position of the incoming node, and the position of the incoming Node in the DOM will change. Generally, when we call appendChild()
, all incoming nodes are cloned nodes. .
~
~ This article is over, thanks for reading!
~
Learn interesting knowledge, meet interesting friends, and shape interesting souls!
Hello everyone, I'm Hermit King , the author of " Programming Samadhi ", my official account is " Programming Samadhi ", welcome to pay attention, I hope you will give more advice!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。