代码之家  ›  专栏  ›  技术社区  ›  Loren Cahlander

如何在polymer3组件中实现lit-html而不是juicy-html?

  •  2
  • Loren Cahlander  · 技术社区  · 7 年前

    我正在将一个应用程序从聚合物1转换为聚合物3。我用了多汁的html,但他们没有更新到聚合物3,我看到有点燃的html。我想知道如何将这个代码段改为使用lit-html。用于扩展字符串,如: 'Hello <span class="highlight">world</span>!'

    下面是我的polymer 1组件的代码片段。

    <template is="dom-repeat" items="[[item.snippets]]">
      <template is="dom-repeat" items="[[item.matches]]">
        <div><template is="juicy-html" content$="[[item.text]]"></template></div>
      </template>
    </template>
    

    我需要为内部div实现一个新组件吗?有没有我可以看的例子?

    下面是生成的Polymer 3元素,用于显示字符串中突出显示的文本:

    从“@polymer/lit element/lit element.js”导入{html,LitElement};

    /**
     * `search-snippet-highlight`
     * 
     *
     * @customElement
     * @polymer
     * @demo demo/index.html
     */
    class SearchSnippetHighlight extends LitElement {
    
      static get properties() {
        return {
          snippet: { type: String }
        };
      }
    
      render() {
        return html`
          <style>.highlight { background-color: yellow; }</style>
          <div .innerHTML="${this.sanitizeHtml(this.snippet)}"></div>`;
      }
    
      sanitizeHtml(input) {
        return input; // TODO: actually sanitize input with sanitize-html library
      }
    
    }
    
    window.customElements.define('search-snippet-highlight', SearchSnippetHighlight);
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   tony19 thanksd    7 年前

    相当于 <template> juicy-html 在聚合物中 LitElement (使用 lit-html

    render() {
      let content = '';
      for (const s of this.item.snippets) {
        for (const m of s.matches) {
          content += `<div>${m.text}</div>`;
        }
      }
      return html`<div .innerHTML="${this.sanitizeHtml(content)}"></div>`;
    }
    

    这个 render 上述函数执行以下操作:

    1. 从输入构建HTML字符串
    2. 清除HTML
    3. div innerHTML ,使用 语法( .PROPERTY="VALUE" )

    <html>
    <head>
      <!-- Polyfills only needed for Firefox and Edge. -->
      <script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
    </head>
    <body>
      <!-- Works only on browsers that support Javascript modules like
           Chrome, Safari, Firefox 60, Edge 17 -->
      <script type="module">
        import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';
    
        class MyElement extends LitElement {
    
          static get properties() {
            return {
              item: { type: Object }
            }
          }
    
          constructor() {
            super();
            this.item = {
              snippets: [
                {
                  matches: [
                    {text: 'hello <span class="highlight">world</span>'},
                    {text: 'we are the <span class="highlight">world</span>'},
                    {text: 'war of the <span class="highlight">world</span>s'},
                  ]
                },
                {
                  matches: [
                    {text: 'the <span class="highlight">cat</span> in the hat'},
                    {text: '<span class="highlight">cat</span>fish are in the water'},
                    {text: '<span class="highlight">cat</span>erpillars become butterflies'},
                  ]
                },
              ]
            };
          }
    
          render() {
            let content = '';
            for (const s of this.item.snippets) {
              for (const m of s.matches) {
                content += `<div>${m.text}</div>`;
              }
            }
            return html`
              <style>.highlight { background: rgb(255, 251, 222); }</style>
              <div .innerHTML="${this.sanitizeHtml(content)}"></div>`;
          }
    
          sanitizeHtml(input) {
            return input; // TODO: actually sanitize input with sanitize-html library
          }
        }
    
        customElements.define('my-element', MyElement);
      </script>
      
      <my-element mood="great"></my-element>
      
    </body>
    </html>
        2
  •  0
  •   akc42    7 年前

    我把这个放在一个答案里,因为@tony19建议可以正确格式化。我不是在问一个单独的问题,只是在问一个修辞性的问题,而不是提供一个单独的解决方案。

    您可以简化这种方法,因为lit允许您通过 map 功能。

    render() {    
        return html`
            <div>${this.item.snippets.map(s => s.matches.map(m => 
                    html`<div>${this.sanitizeHtml(m.text)}</div>`
                ))}
           </div>
        `; 
    }
    

    lit-html 有一个 guard

    render() {    
        return html`
            <div>${guard(this.item.snippets, () => this.item.snippets.map(s => 
                     guard(s.matches, () => s.matches.map(m => 
                    html`<div>${this.sanitizeHtml(m.text)}</div>`
                ))))}
           </div>
        `; 
    }
    

    这确实需要你对两者的关系施加一些约束 this.item.snippets 以及潜在的 matches 获取最新信息。您必须确保使用的“数组”引用在发生更新时发生更改。类似于这样的内容(假设使用新的匹配项更新匹配项)和 sindex snippet 你想更新和 mindex 是的索引 match 在这个范围内 代码段 您正在更新 newMatch ;

    this.items.snippets = this.items.snippets.map((snippet, index) => index === sindex ?
       {...snippet, matches: snippet.matches.map((match, index) => index === mindex ?
          newMatch : match)} : snippet);
    
    推荐文章