我正在制作vanilla-js web-component,需要将object作为其值传递给属性,但每次它都将其作为字符串。
我可以将字符串传递给组件的属性,但我知道我需要传递一个对象。
var obj = { name: "John", age: 30, city: "New York" };
const template = document.createElement('template');
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
console.log(this.content);
}
get content() {
return this.getAttribute("content")
}
}
window.customElements.define('table-component', TabelComponent);<table-component content=obj></table-component>
我的"content“属性应该将obj作为object,而不是string。我应该在控制台中获取{ name: "John", age: 30, city: "New York" };
发布于 2019-08-26 22:34:39
你所要求的通常是一个框架的工作。
最好通过属性而不是属性将对象传递到Web组件中:
属性
var obj = { name: "John", age: 30, city: "New York" };
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = '<h1>your DOM here</h1><pre id="content"></pre>';
}
connectedCallback() {
}
set content(val) {
this._content = val;
// render changes
let el = this.shadowRoot.querySelector('#content');
el.textContent = JSON.stringify(this._content,0,2);
}
get content() {
return this._content;
}
}
window.customElements.define('table-component', TabelComponent);
setTimeout(() => {
let el = document.getElementById('mine');
el.content = obj;
}, 10);<table-component id="mine"></table-component>
数据URI
但是,如果您确实希望通过属性传递某些内容,那么可以考虑使用数据URI的标准。(https://devdocs.io/http/basics_of_http/data_uris)
这是通过始终使用fetch来获取数据并将content属性当作一个URL来实现的。这允许您从URL加载数据,并且仍然允许您直接传入JSON数据。
您的数据需要完全兼容JSON,并且还需要对其进行URL编码。
最简单的方法是使用observedAttributes静态函数来定义您想要监视的属性,然后使用attributeChangedCallback来了解该属性何时发生更改。请注意,删除该属性时,newVal将为null,您需要对此进行不同的处理。
下面的例子很简单,需要一些错误检查。但是它展示了如何使用数据URI来完成该任务。
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = '<h1>your DOM here</h1><pre id="content"></pre>';
}
static get observedAttributes() {
return ['content'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
if (newVal === null) {
// Attribute was removed
this._content = null;
this.render();
}
else {
fetch(newVal).then(
(res) => res.json()
).then(
(data) => {
this._content = data;
this.render();
}
);
}
}
}
connectedCallback() {
}
render() {
let el = this.shadowRoot.querySelector('#content');
el.textContent = JSON.stringify(this._content,0,2);
}
get content() {
return this._content;
}
}
window.customElements.define('table-component', TabelComponent);
setTimeout(() => {
let el = document.getElementById('mine');
el.content = obj;
}, 10);<table-component content="data:application/json,%7B%22name%22%3A%22John%22%2C%22age%22%3A30%2C%22city%22%3A%22New%20York%22%7D" id="mine"></table-component>
attribute中的JSON
如果你真的不想使用完整的数据URI,你可以将代码减少到如下所示:
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = '<h1>your DOM here</h1><pre id="content"></pre>';
}
static get observedAttributes() {
return ['content'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
if (newVal === null) {
// Attribute was removed
this._content = null;
this.render();
}
else {
console.log(newVal);
this._content = JSON.parse(newVal);
this.render();
}
}
}
connectedCallback() {
}
render() {
let el = this.shadowRoot.querySelector('#content');
el.textContent = JSON.stringify(this._content,0,2);
}
get content() {
return this._content;
}
}
window.customElements.define('table-component', TabelComponent);<table-component content="{"name":"John","age":30,"city":"New York"}" id="mine"></table-component>
您可能会注意到,这确实要求您将双引号编码到"中,以防止意外的属性值结束。
当然,您总是可以强制您的属性使用单引号,然后不需要转义双引号,但您需要转义任何单引号:
<table-component content='{"name":"John","age":30,"city":"New York"}' id="mine"></table-component>
属性中的变量值
我真的认为您所要求的是通过在属性中设置变量名称来将变量的值传递到组件中的能力:
<table-component content='<variable name>' id="mine"></table-component>
这是可以做到的,但是您现在正在步入框架的领域。
问题是这个变量的作用域是什么?它是一个全局的吗?它是成员变量吗?还有别的原因吗?
如果你只想使用全局变量,那么这是非常简单的。但是非常有限!
var obj = { name: "John", age: 30, city: "New York" };
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = '<h1>your DOM here</h1><pre id="content"></pre>';
}
static get observedAttributes() {
return ['content'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (newVal === null) {
// Attribute was removed
this._content = null;
this.render();
}
else {
this._content = window[newVal];
this.render();
}
}
connectedCallback() {
}
render() {
let el = this.shadowRoot.querySelector('#content');
el.textContent = JSON.stringify(this._content,0,2);
}
get content() {
return this._content;
}
}
window.customElements.define('table-component', TabelComponent);<table-component content="obj"></table-component>
当obj的值更改时,这不会自动更新。要让组件重新读取变量,您需要更改属性的值。但这比仅仅设置属性要复杂得多。
多属性
这里没有代码,但最简单的版本可能是创建多个属性,每个属性都会影响DOM的一部分。然后,您可以在需要更改时设置每个属性,而不是一直重置所有内容。
发布于 2019-08-27 18:29:48
使用带有Element.setAttribute()的JSON.stringify()将对象转换为字符串:
var obj = { name: "John", age: 30, city: "New York" }
document.querySelector( 'table-component' ).setAttribute( 'content', JSON.stringify( obj ) )并使用带有Element.getAttribute()的JSON.parse()将字符串属性转换为对象:
get content() {
return JSON.parse( this.getAttribute( 'content' ) )
}
var obj = { name: "John", age: 30, city: "New York" };
document.querySelector( 'table-component' ).setAttribute( 'content', JSON.stringify(obj) )
const template = document.createElement('template');
class TabelComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
console.log(this.content);
}
get content() {
return JSON.parse( this.getAttribute( "content" ) )
}
}
window.customElements.define('table-component', TabelComponent);<table-component content=''></table-component>
发布于 2019-08-26 16:38:51
您可以将对象解析为JSON字符串,如下所示:
var obj = { name: "John", age: 30, city: "New York" };
var objString = JSON.stringify(obj);<table-component id="h" content="objString "></table-component>然后在你的web组件中应该把它解析回你的对象。
var obj = JSON.parse(this.content);https://stackoverflow.com/questions/57654383
复制相似问题