1
头图

Write in front

Let me talk about the problem first: same custom tag in Vue and React, the incoming attributes will have different results .

To facilitate the following description, first customize a label <my-cell /> , the code is as follows:

class MyCell extends HTMLElement {
  static get observedAttributes() {
    return ['desc'];
  }
  constructor() {
    super();
  }
  get desc() {
    console.log('get');
    return this.getAttribute('desc');
  }
  set desc(value) {
    console.log('set', typeof value);
    this.setAttribute('desc', value);
  }
  attributeChangedCallback(name, oldValue, newValue) {
    console.log('attributeChangedCallback!', name, 1);
  }
  connectedCallback() {
    console.log('connectedCallback!', typeof this.desc);
    const shadowRoot = this.attachShadow({
      mode: 'open'
    });
    shadowRoot.innerHTML = `
    <style>
      :host{
        background: red;
      }
    </style>
    <slot></slot>
    ${this.desc}
    `;
  }
}
customElements.define('my-cell', MyCell);

Then use in Vue and React

<my-cell desc="false">Cell</my-cell>

See how it will be printed?
image.png
As shown in the figure, you can see set in the Vue project, but not in the React project.

In addition, it is verified that Vue passes DOM Property :

// 属性传递是 DOM property!
<my-cell desc="false">Cell</my-cell> // 字符串

// 属性传递是 DOM property!
<my-cell :desc="false">Cell</my-cell> // 布尔值

Summarize:

  • The attribute in vue is DOM property , which will trigger set
  • The properties in react are DOM attribute set will not be triggered

How to solve consistent performance in Vue and React?

The difference between DOM property and DOM attribute leads to different performance of custom tags when used in Vue and React. The core idea is to do a good job of mapping.

Execute within WCs:

connectedCallback() {
+  this.desc = this.desc; // attribute -> property 映射
}

Assignment to this.desc on the left side of the equal sign will trigger the execution of set :

set desc(value) {
    this.setAttribute('desc', value); // 设置为 attribute
}

this.desc on the right side of the equal sign is a get action, which will call get :

get desc() {
    return this.getAttribute('desc'); // 获取 attribute
}

In the end, we will uniformly transfer the incoming attributes to Dom Attribute .

Summary: No matter what attributes are passed in from the outside, use this.xx = this.xx uniformly set the incoming attributes to DOM attribute .

Write at the end

Please leave a message to discuss about Web Components issues~


Allan91
2.3k 声望2.6k 粉丝