如何解决如何在自定义组件中嵌入链接作为插槽?
我正在尝试创建一个包含一些动画的简单组件。我为链接的文本设置了名称属性。我为链接的目的地设置了一个插槽,但模板不允许将链接设置为插槽。我不确定接下来要尝试什么。
当我将鼠标悬停在链接上时,它只显示 <slot name=
而不是实际网址。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href="<slot name="destination" />"></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
constructor() {
super();
this.showInfo = true;
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector('a').innerText = this.getAttribute('name');
}
}
window.customElements.define('custom-anim-link',CustomAnimLink);
<custom-anim-link name="Learn more">
<div slot="destination">https://www.yahoo.com</div>
</custom-anim-link>
解决方法
你不能用插槽来做到这一点。插槽用于将 HTMLElement
放置在插槽的位置,除此之外不能用于任何其他用途。
而是将 URL 作为属性传递。这似乎适合数据类型。 Web Components 有一些很好的生命周期来帮助你解决这个问题。
我添加了 static get observedAttributes()
以指示应该观察某些属性。这样做将使您能够在其中一个属性中的值发生更改时执行某些操作,例如更新 Shadow DOM 中锚点上的 URL。
每当观察到的属性值发生变化时,就会调用 attributeChangedCallback
,您可以在其中确定每当值发生变化时会发生什么。
observedAttributes
和 attributeChangedCallback
都是 Web 组件生命周期挂钩的一部分。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href=""><slot></slot></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name','destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get anchor() {
return this.shadowRoot.querySelector('a');
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name',value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination',value);
}
}
attributeChangedCallback(attrName,oldValue,newValue) {
switch (attrName) {
case 'destination':
this.anchor.href = newValue;
break;
case 'name':
this.anchor.textContent = newValue;
break;
}
}
}
window.customElements.define('custom-anim-link',CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com"></custom-anim-link>
或者,您可以在插槽的位置传递 <a>
标记。然后获取分配给 destination
槽的所有元素,并根据 textContent
属性的值设置 name
属性。我们在上一个示例中添加的 destination
属性也是如此。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<slot name="destination"></slot>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name','destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get destinations() {
const slot = this.shadowRoot.querySelector('slot');
const assignedElements = slot.assignedElements();
return assignedElements;
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name',value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination',value);
}
}
attributeChangedCallback(attrName,newValue) {
switch(attrName) {
case 'name':
this.destinations.forEach(destination => {
destination.textContent = newValue;
});
break;
case 'destination':
this.destinations.forEach(destination => {
destination.href = newValue;
});
break;
}
}
}
window.customElements.define('custom-anim-link',CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com">
<a slot="destination"></a>
</custom-anim-link>
或者作为最后的简单手段,只需将 <a>
作为子元素完整地传递给您的自定义元素。
<custom-anim-link>
<a href="https://www.yahoo.com">Learn more</a>
</custom-anim-link>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。