如何使用LitElement

时间:2018-05-18 09:41:43

标签: polymer lit-element

我不知道如何在LitElement中观察属性变化。

我一直在尝试这些方法,但我无法使用这些方法:

  static get properties() {
    return {
      temp1:String,
      temp2: {
       type:String,
       observer: '_temp2Changed'
        }
  };

  temp1Changed(newValue, oldValue){
    console.log("temp1 changed")
  }
  _temp2Changed(newValue, oldValue){
    console.log("temp2 changed")
  }

6 个答案:

答案 0 :(得分:7)

版本0.6.0 +

首先,您必须指定元素属性。 您可以通过创建一个静态getter来做到这一点,该方法会返回一个对象,其中包括其名称作为键以及与属性相关的配置。

更改的属性导致重新渲染时,将调用updated生命周期方法。第一个参数将在更新之前返回值。

class MyComponent extends LitElement {
  static get properties() {
    return {
      foo: {}
    };
  }

  constructor() {
    super();
    this.foo = 0;
    setInterval(() => this.foo++, 1000);
  }

  updated(changedProperties) {
    console.log(changedProperties); // logs previous values
    console.log(this.foo); // logs current value
  }

  render() {
    return html`${this.foo}`;
  }
}

customElements.define("my-component", MyComponent);

答案 1 :(得分:0)

我找到了Polymer的PWA入门套件的解决方案。

在元素定义中添加以下内容:

_propertiesChanged(props, changed, oldProps) {
    console.log("_propertiesChanged(props, changed, oldProps):");
    console.log(props);    
    console.log(changed);  
    console.log(oldProps); 
    if (changed && 'temp1' in changed) {
      console.log("if temp1:"+changed.temp1);
    }
    super._propertiesChanged(props, changed, oldProps); //This is needed here
}

console output:
_propertiesChanged(props, changed, oldProps):
{temp1: "newVal1", temp2: "val2"}
{temp1: "newVal1"}
{temp1: "val1"}
if temp1:newVal1

答案 2 :(得分:0)

只要属性在您的'_render'方法中定义,LitElement就会在属性每次更改时自动重新呈现。

这在LitElement readme中有所记录:

  

对更改做出反应:LitElement通过异步呈现对属性和属性的更改做出反应,确保对更改进行批处理。这样可以减少开销并维持一致的状态。

例如:

_render({firstName, lastName}) {
  return html`
    <div> Hello ${firstName} ${lastName} </div>
  `
};

每次您的firstName和lastName属性更改时,都会重新渲染。我希望这可以提供一些清晰度。

答案 3 :(得分:0)

我个人重写了“ requestUpdate”方法,以便在渲染之前知道更改。

我的用例是拦截“ label”属性的更改以触发异步数据请求。

下面的代码段(在TypeScript中):

@customElement('my-element')
export default class MyElement extends LitElement {

    @property({type: String})
    label: string | null = null;

    @property({attribute: false})
    private isLoading: boolean = false;

    @property({attribute: false, noAccessor: true})
    private data: MyData | null = null;

    protected render() {/*some code*/}

    requestUpdate(name?: PropertyKey, oldValue?: unknown) {
        if(name && name == "label" && this.label !== oldValue) {
            this.isLoading = true;
            requestData(this.label, this._callbackData);
        }
        return super.requestUpdate(name, oldValue);
    }

    private _callbackData(data: MyData}) {
        this.data = data;
        this.isLoading = false;
    }

}

这样,我的元素仅呈现两次:一个具有新标签并加载为true,然后在有数据时另一个呈现。

答案 4 :(得分:0)

属性“已更改”选项:

您可以在静态属性getter的属性声明中定义此“ hasChanged”选项。就像您使用“类型”选项一样。

hasChanged应该返回true以更新元素。

myProp: { hasChanged(newVal, oldVal) {
 // compare newVal and oldVal
 // return `true` if an update should proceed
}}

检查出来here

生命周期方法:已更新

有一个名为“ updated”的生命周期方法,该方法在每次属性更改时都会触发。

此方法将“ changedProperties”及其以前的值作为参数接收,以便您可以将它们与当前值进行比较,然后决定要执行的操作。

查看“更新的”文档here

答案 5 :(得分:0)

实施shouldUpdate()方法。 Source here.

控制是否应继续进行更新。实现shouldUpdate以指定哪些属性更改应引起更新。默认情况下,此方法始终返回true。

function shouldUpdate(changedProperties: Map<any, any>) {
    changedProperties.forEach((oldValue, propName) => {
        const newValue = JSON.stringify(this[propName]);
        console.log(`${propName} changed. oldValue: ${oldValue} newValue: ${newValue}`);
    });
    return true;
}