使用stencilJS生成动态Unorderlist Web组件

时间:2019-02-14 12:56:19

标签: stenciljs

使用stenciljs动态生成嵌套无序<ul><li>...</li></ul>列表,因此我遇到问题并以Obj={}的形式输入。这是下面的代码,请帮助我...

1. index.html
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
  <title>Stencil Component Starter</title> 
  <script src="/build/mycomponent.js"></script>

</head>
<body>   
  <list-component list-object='[
  {title: "Point", children: [
      {title: "Point"},
      {title: "Point"},
      {title: "Point"},
      {title: "Point", children: [
          {title: "Point"},
          {title: "Point"},
          {title: "Point"}
      ]}
  ]},
  {title: "Point", children: [
      {title: "Point"},
      {title: "Point", children: [
          {title: "Point"},
          {title: "Point"},
          {title: "Point"}
      ]},
      {title: "Point"}
  ]},
]' > </list-component>  
</body>
</html>

问题: 我将嵌套对象传递给自定义Web组件。 在这个list.tsx文件中,我在将参数传递给函数buildList("?","?") ...?

时遇到了问题。
2. list.tsx
import { Component, Prop, State, Watch, Element } from '@stencil/core';


@Component({
    tag:'list-component',
    styleUrl:'./list-component.css' 
})

export class ListComponent{

    @State() idName: string;   
    @Prop() listObject: string;
    @Element() flashElement: HTMLElement;   

    private ulContent: HTMLElement;

    componentWillLoad() { 
        this.ulContent  = this.flashElement.querySelector('.ul-content');
        this.buildList(this.ulContent,this.listObject);  
    }


    @Watch('listObject') 
    buildList(parentElement, listObject){ 
        console.log(listObject);
        var i, l, list, li, ul1;
        if( !listObject || !listObject.length ) { return; } 
        ul1 = document.createElement('ul');
        list = parentElement.appendChild(ul1);
        for(i = 0, l = listObject.length ; i < l ; i++) {
            li = document.createElement('li');
            li.appendChild(document.createTextNode(listObject[i].title)); 
            list.appendChild(li);
            this.buildList(li, listObject[i].children);
        } 
    } 

    render() {
        return ( 
            <div class="ul-content"></div>
        );
    }
}

1 个答案:

答案 0 :(得分:0)

我看到两个问题:

1:当Stencil调用@Watch方法时,它总是将新值和旧值作为参数传递,请参见https://stenciljs.com/docs/properties#prop-default-values-and-validation。这意味着您无法定义自定义参数。 您可以创建一个充当观察者的附加函数,然后调用buildList:

@Watch('listObject')
listObjectChanged() {
    this.buildList(this.ulContent, this.listObject);
}

2:listObject是一个字符串,因此需要JSON.parse才能对其进行循环(并对其进行重写,以便它是有效的JSON)。然后将解析后的列表存储在本地变量中,并使用它来生成列表。参见https://medium.com/@gilfink/using-complex-objects-arrays-as-props-in-stencil-components-f2d54b093e85


有一种使用JSX呈现列表而不是手动创建列表元素的简单方法:

import { Component, Prop, State, Watch, Element } from '@stencil/core';

@Component({
  tag: 'list-component',
  styleUrl: './list-component.css'
})

export class ListComponent {

  @Element() flashElement: HTMLElement;

  @State() idName: string;
  @Prop() listObject: string;
  @State() list: any[];

  @Watch('listObject')
  listObjectChanged() {
    this.list = JSON.parse(this.listObject);
  }

  componentWillLoad() {
    this.listObjectChanged();
  }

  renderList(list) {
    return list.map(list => <ul>
      <li>{list.title}</li>
      {list.children && this.renderList(list.children)}
    </ul>
    );
  }

  render() {
    return (
      <div class="ul-content">
        {this.renderList(this.list)}
      </div>
    );
  }
}

希望这会有所帮助。