当 属性 更改时如何重新渲染我的组件 (webcomponents)
How can I re-render my component when a property to it changes (webcomponents)
这是我的提交按钮组件:
class SubmitButton extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.isLoading = this.getAttribute('loading') === 'true';
console.log('isLoading: ', this.isLoading);
this.button = `<button>Go</button>`;
this.spinner = `
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>`
this.innerHTML = `
<style>
button {
margin-left: 1rem;
}
.spinner {
// animations and stuff
}
</style>
${this.isLoading ? this.spinner : this.button}
`;
}
}
customElements.define("submit-button", SubmitButton);
我用 <submit-botton loading="true"></submit-button>
调用它,但是当我用 js 动态更改 属性 时(即:获取完成),按钮不会重新呈现。
有没有办法让它重新渲染?
我正在使用以下代码更改 属性 的值:
const button = document.querySelector('submit-button');
button.loading = true;
// do some fetching
button.loading = false;
编辑:这是一个使用 changedAttributes 处理程序的更新,但它仍然不起作用:
class SubmitButton extends HTMLElement {
constructor() {
super();
this.isLoading = this.getAttribute('loading') === 'true';
}
static get observedAttributes() {
return ['loading'];
}
get loading() {
return this.isLoading;
}
set loading(val) {
this.isLoading = val === 'true';
}
render() {
this.button = `<button>Go</button>`;
this.spinner = `
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>`
this.innerHTML = `
<style>
button {
margin-left: 1rem;
}
.spinner {
animation: rotate 2s linear infinite;
z-index: 2;
width: 4rem;
height: 4rem;
margin-left: 1rem;
}
.path {
stroke: #633;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
</style>
${this.isLoading ? this.spinner : this.button}
`;
}
connectedCallback() {
console.log('isLoading: ', this.isLoading);
this.render();
}
attributeChangedCallback(name, oldValue, newValue) {
console.log('attr changed: ',name, oldValue, newValue);
this.render();
}
}
customElements.define("submit-button", SubmitButton);
这很有趣,感谢您提出问题。我从 https://developers.google.com/web/fundamentals/web-components/customelements and created this JSFiddle.
那里借用了一些代码
基本上,我不担心loading
是"true"
还是"false"
,只是检查属性是否存在:
get loading() {
return this.hasAttribute('loading');
}
set loading(val) {
if (val) {
this.setAttribute('loading', '');
} else {
this.removeAttribute('loading');
}
}
之后就是检查this.loading
的事情了。请务必检查 JSFiddle。
这是我的提交按钮组件:
class SubmitButton extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.isLoading = this.getAttribute('loading') === 'true';
console.log('isLoading: ', this.isLoading);
this.button = `<button>Go</button>`;
this.spinner = `
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>`
this.innerHTML = `
<style>
button {
margin-left: 1rem;
}
.spinner {
// animations and stuff
}
</style>
${this.isLoading ? this.spinner : this.button}
`;
}
}
customElements.define("submit-button", SubmitButton);
我用 <submit-botton loading="true"></submit-button>
调用它,但是当我用 js 动态更改 属性 时(即:获取完成),按钮不会重新呈现。
有没有办法让它重新渲染?
我正在使用以下代码更改 属性 的值:
const button = document.querySelector('submit-button');
button.loading = true;
// do some fetching
button.loading = false;
编辑:这是一个使用 changedAttributes 处理程序的更新,但它仍然不起作用:
class SubmitButton extends HTMLElement {
constructor() {
super();
this.isLoading = this.getAttribute('loading') === 'true';
}
static get observedAttributes() {
return ['loading'];
}
get loading() {
return this.isLoading;
}
set loading(val) {
this.isLoading = val === 'true';
}
render() {
this.button = `<button>Go</button>`;
this.spinner = `
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>`
this.innerHTML = `
<style>
button {
margin-left: 1rem;
}
.spinner {
animation: rotate 2s linear infinite;
z-index: 2;
width: 4rem;
height: 4rem;
margin-left: 1rem;
}
.path {
stroke: #633;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
</style>
${this.isLoading ? this.spinner : this.button}
`;
}
connectedCallback() {
console.log('isLoading: ', this.isLoading);
this.render();
}
attributeChangedCallback(name, oldValue, newValue) {
console.log('attr changed: ',name, oldValue, newValue);
this.render();
}
}
customElements.define("submit-button", SubmitButton);
这很有趣,感谢您提出问题。我从 https://developers.google.com/web/fundamentals/web-components/customelements and created this JSFiddle.
那里借用了一些代码基本上,我不担心loading
是"true"
还是"false"
,只是检查属性是否存在:
get loading() {
return this.hasAttribute('loading');
}
set loading(val) {
if (val) {
this.setAttribute('loading', '');
} else {
this.removeAttribute('loading');
}
}
之后就是检查this.loading
的事情了。请务必检查 JSFiddle。