【问题标题】:How to declare a required property in lit-element如何在 lit-element 中声明必需的属性
【发布时间】:2021-06-16 19:10:57
【问题描述】:

在 react 中,我们可以使用 PropTypes 将特定的 prop 标记为必需的。

requiredFunc: PropTypes.func.isRequired,

Vue 还支持所需的道具:

    propC: {
      type: String,
      required: true
    },

如何在 lit-element 中做到这一点?一个框架声称它非常好,但不支持诸如必需属性之类的简单事物,这真是太有趣了。

【问题讨论】:

  • 也许 Lit 适合那些知道如何编程的程序员。我不知道。我用 Vanilla JavaScript 编写 Web 组件,并且知道如何使用 IF 语句。不需要臃肿的 50 kB 框架来为我处理所需的属性。 #if_you_can_do_sarcasm_I_can_too

标签: web-component lit-element lit


【解决方案1】:

React 和 Vue 组件使用它们各自的运行时在受控环境中执行。 Web 组件不能具有相同级别的净化环境。渲染周期是为 React/Vue/Angular/etc 完美定义的。 Web 组件可以通过多种方式初始化:

    // Using custom registered tag
    const myComp = document.createElement('my-custom');

    // Using constructor
    const myComp = new MyCustom();

    // Initialization using plain html
    <div>
      <my-comp>
    </div>

所以,生命周期不容易不可控。让我们假设您有一个带有道具的 Web 组件 - myRequiredProp。并且,它被初始化为:

    // Pass prop at the time of initialization
    const myComp1 = new MyCustom({ myRequiredProp: 10 });

    // Pass prop at a later time.
    const myComp2 = new MyCustom();

    // ... after some time
    myComp2.myRequiredProp = 10;

    // And how to pass props if component is being used directly in HTML.
    // Is this right way? What if `my-required-prop` should be object and not a primitive like number or string?
    <div>
      <my-comp my-required-prop="10" />
    </div>

另外,每个使用你的组件的框架都可以有自己的初始化 props 的方式。什么时候应该触发 prop 的验证。如果组件刚刚初始化并且从未渲染怎么办。在 Web 组件的情况下,要解决每个场景,这些都不是容易做出的决定。因此,最好将这种担忧留在核心之外。 lit-element 有意避免此类开放式决定。

话虽如此,您可以为道具构建自己的验证系统。您可以控制何时应该进行道具验证。例如,您可以在render 时间验证道具。

    export class MyElement extends LitElement {

      @property({})
      count = 0;

      @property()
      name = 'World';

      validateAllProps() {
        // Your validation logic.
        // Use joi or zod to validation `this`.
        return true;
      }
      
      render() {

        // Trigger validation here
        if (!this.validateAllProps) {
          console.warn('Invalid props');
        }


        return html`
          <h1>Hello, ${this.name}!</h1>
          <button @click=${this._onClick}>
            Click Count: ${this.count}
          </button>
        `;
      }
    }

或者您也可以使用自定义设置器或使用转换器功能验证道具。

    export class MyElement extends LitElement {

      #name = 'World';

      set name(name) {
        if (typeof name !== 'string') {
          console.warn('Invalid prop name for MyElement');
        }

        this.#name = name;
      }

      
      render() {
        return html`
          <h1>Hello, ${this.name}!</h1>
        `;
      }
    }

您应该能够使用扩展 LitElement 的通用基类或使用自定义装饰器来管理属性验证来概括验证行为

我同意LitElement 与 React 和 Vue 相比可能会感到尴尬,但总的来说,它有太多需要处理的问题,而 React 根本不需要处理。它很容易变得复杂。

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2023-03-09
    • 1970-01-01
    • 2021-07-29
    • 2021-04-10
    相关资源
    最近更新 更多