首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将对象(或关联数组)作为属性值传递给我的web组件

如何将对象(或关联数组)作为属性值传递给我的web组件
EN

Stack Overflow用户
提问于 2019-08-26 16:32:58
回答 3查看 1.7K关注 0票数 7

我正在制作vanilla-js web-component,需要将object作为其值传递给属性,但每次它都将其作为字符串。

我可以将字符串传递给组件的属性,但我知道我需要传递一个对象。

代码语言:javascript
复制
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);
代码语言:javascript
复制
<table-component content=obj></table-component>

我的"content“属性应该将obj作为object,而不是string。我应该在控制台中获取{ name: "John", age: 30, city: "New York" };

EN

回答 3

Stack Overflow用户

发布于 2019-08-26 22:34:39

你所要求的通常是一个框架的工作。

最好通过属性而不是属性将对象传递到Web组件中:

属性

代码语言:javascript
复制
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);
代码语言:javascript
复制
<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来完成该任务。

代码语言:javascript
复制
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);
代码语言:javascript
复制
<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,你可以将代码减少到如下所示:

代码语言:javascript
复制
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);
代码语言:javascript
复制
<table-component content="{&quot;name&quot;:&quot;John&quot,&quot;age&quot;:30,&quot;city&quot;:&quot;New York&quot;}" id="mine"></table-component>

您可能会注意到,这确实要求您将双引号编码到&quot;中,以防止意外的属性值结束。

当然,您总是可以强制您的属性使用单引号,然后不需要转义双引号,但您需要转义任何单引号:

<table-component content='{"name":"John","age":30,"city":"New York"}' id="mine"></table-component>

属性中的变量值

我真的认为您所要求的是通过在属性中设置变量名称来将变量的值传递到组件中的能力:

<table-component content='<variable name>' id="mine"></table-component>

这是可以做到的,但是您现在正在步入框架的领域。

问题是这个变量的作用域是什么?它是一个全局的吗?它是成员变量吗?还有别的原因吗?

如果你只想使用全局变量,那么这是非常简单的。但是非常有限!

代码语言:javascript
复制
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);
代码语言:javascript
复制
<table-component content="obj"></table-component>

obj的值更改时,这不会自动更新。要让组件重新读取变量,您需要更改属性的值。但这比仅仅设置属性要复杂得多。

多属性

这里没有代码,但最简单的版本可能是创建多个属性,每个属性都会影响DOM的一部分。然后,您可以在需要更改时设置每个属性,而不是一直重置所有内容。

票数 5
EN

Stack Overflow用户

发布于 2019-08-27 18:29:48

使用带有Element.setAttribute()JSON.stringify()将对象转换为字符串:

代码语言:javascript
复制
var obj = { name: "John", age: 30, city: "New York" }
document.querySelector( 'table-component' ).setAttribute( 'content', JSON.stringify( obj ) )

并使用带有Element.getAttribute()JSON.parse()将字符串属性转换为对象:

代码语言:javascript
复制
get content() {
    return JSON.parse( this.getAttribute( 'content' ) )
}

代码语言:javascript
复制
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);
代码语言:javascript
复制
<table-component content=''></table-component>

票数 1
EN

Stack Overflow用户

发布于 2019-08-26 16:38:51

您可以将对象解析为JSON字符串,如下所示:

代码语言:javascript
复制
var obj = { name: "John", age: 30, city: "New York" };
var objString = JSON.stringify(obj);
代码语言:javascript
复制
<table-component id="h" content="objString "></table-component>

然后在你的web组件中应该把它解析回你的对象。

代码语言:javascript
复制
var obj = JSON.parse(this.content);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57654383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档