Polymer - 自定义元素



Polymer 是一个允许使用标准 HTML 元素创建自定义元素的框架。自定义 Web 元素提供以下功能:

  • 它提供与类关联的自定义元素名称。

  • 当您更改自定义元素实例的状态时,它将请求生命周期回调。

  • 如果更改实例上的属性,则将请求回调。

您可以使用 ES6 类定义自定义元素,并且类可以与自定义元素关联,如下面的代码所示。

//ElementDemo class is extending the HTMLElement 
class ElementDemo extends HTMLElement { 
   // code here
};

//link the new class with an element name
window.customElements.define('element-demo', ElementDemo);

自定义元素可以用作标准元素,如下所示:

<element-demo></element-demo>

注意 - 自定义元素名称应以小写字母开头,并在名称之间包含一个短横线。

自定义元素生命周期

自定义元素生命周期提供一组自定义元素反应,这些反应负责元素生命周期的变化,并在下表中定义。

序号 反应及描述
1

constructor

当您创建元素或定义先前创建的元素时,将调用此元素反应。

2

connectedCallback

当您将元素添加到文档时,将调用此元素反应。

3

disconnectedCallback

当您从文档中删除元素时,将调用此元素反应。

4

attributeChangedCallback

每当您更改、追加、删除或替换文档中的元素时,都会调用此元素反应。

元素升级

我们可以根据规范在定义自定义元素之前使用它们,并且通过向该元素添加定义,任何现有元素实例都将升级到自定义类。

自定义元素状态包含以下值:

  • uncustomized - 有效的自定义元素名称是内置元素或未知元素,无法成为自定义元素。

  • undefined - 元素可以具有有效的自定义元素名称,但无法定义。

  • custom - 元素可以具有有效的自定义元素名称,可以定义和升级。

  • failed - 尝试升级无效类的失败元素。

定义元素

可以通过创建一个扩展 Polymer.Element 的类来定义自定义元素,并将该类传递给 customElements.define 方法。该类包含 is getter 方法,该方法返回自定义元素的 HTML 标签名称。例如:

//ElementDemo class is extending the Polymer.Element 
class ElementDemo extends Polymer.Element {
   static get is() { return 'element-demo'; }
   static get properties() {
      . . .
      . . .
   }
   constructor(){
      super();
      . . .
      . . .
   }
   . . .
   . . .
}

//Associate the new class with an element name
window.customElements.define(ElementDemo.is, ElementDemo);

// create an instance with createElement
var el1 = document.createElement('element-demo');

导入和 API

可以通过指定以下三个 HTML 导入来定义 Polymer 元素:

  • polymer-element.html - 它指定 Polymer.Element 基类。

  • legacy-element.html - 它使用 Polymer.LegacyElement 基类扩展 Polymer.Element 并添加 1.x 兼容的旧版 API。它还通过定义旧版 Polymer() 工厂方法来创建混合元素。

  • polymer.html - 它包含 Polymer 基类以及包含在 1.x polymer.html 中的辅助元素。

在主 HTML 文档中定义元素

您可以使用 HTMLImports.whenReady() 函数在主 HTML 文档中定义元素。

示例

以下示例显示如何在主 HTML 文档中定义元素。创建一个 index.html 文件并添加以下代码。

<!doctype html>
<html lang = "en">
   <head>
      <title>Polymer Example</title>
      <script src = "bower_components/webcomponentsjs/webcomponents-lite.js"></script>
      <link rel = "import" href = "bower_components/polymer/polymer.html">
      <link rel = "import" href = "define-element.html">
   </head>
   
   <body>
      <define-element></define-element>
   </body>
</html>

现在创建一个名为 define-element.html 的自定义元素并包含以下代码。

<dom-module id = "define-element">
   <template>
      <h2>Welcome to Tutorialspoint!!!</h2>
   </template>
   
   <script>
      HTMLImports.whenReady(function(){
         Polymer ({
            is: "define-element"
         })
      })  
   </script>
</dom-module>

输出

要运行应用程序,请导航到已创建的项目目录并运行以下命令。

polymer serve

现在打开浏览器并导航到 http://127.0.0.1:8081/。输出如下所示。

Polymer Define Element

定义旧版元素

旧版元素可用于使用 Polymer 函数注册元素,该函数采用新元素的原型。原型应包含 is,该原型定义自定义元素的 HTML 标签名称。

示例

//registering an element
ElementDemo = Polymer ({
   is: 'element-demo',
   
   //it is a legecy callback, called when the element has been created
   created: function() {
     this.textContent = 'Hello World!!!';
   }
});

//'createElement' is used to create an instance
var myelement1 = document.createElement('element-demo');

//use the constructor create an instance
var myelement2 = new ElementDemo();

生命周期回调

生命周期回调用于完成Polymer.Element类的内置功能的任务。Polymer 使用 ready 回调,该回调将在 Polymer 完成创建和初始化 DOM 元素时调用。

以下是 Polymer.js 中旧版回调的列表。

  • created - 在设置属性值和初始化本地 DOM 之前创建元素时调用。

  • ready - 在设置属性值和初始化本地 DOM 之后创建元素时调用。

  • attached - 将元素附加到文档后调用,并且在元素的整个生命周期中可以多次调用。

  • detached - 从文档中分离元素后调用,并且在元素的整个生命周期中可以多次调用。

  • attributeChanged - 当元素的属性发生更改时调用,它保存与声明的属性不兼容的属性更改。

声明属性

可以在元素上声明属性以添加默认值和其他特定功能到数据系统中,并且可以使用它们来指定以下功能:

  • 它指定属性类型和默认值。

  • 当属性值发生更改时,它调用观察者方法。

  • 它指定只读状态以阻止对属性值的意外更改。

  • 它支持双向数据绑定,当您更改属性值时会触发事件。

  • 它是一个计算属性,它根据其他属性动态计算值。

  • 当您更改属性值时,它会更新并反映相应的属性值。

下表显示了属性对象支持的每个属性的键。

序号 键及描述 类型
1

type

它从属性反序列化,该属性的类型使用类型的构造函数确定。

constructor (Boolean, Date, Number, String, Array 或 Object)
2

value

它指定属性的默认值,如果它是函数,则它使用返回值作为属性的默认值。

布尔值、数字、字符串或函数。
3

reflectToAttribute

如果此键设置为 true,则它会在主机节点上设置相应的属性。如果将属性值设置为布尔值,则可以将其创建为标准 HTML 布尔属性。

布尔值
4

readOnly

如果此键设置为 true,则不能通过赋值或数据绑定直接设置属性。

布尔值
5

notify

如果此键设置为 true,则可以使用该属性进行双向数据绑定,并且当您更改属性时,将触发 property-name-changed 事件。

布尔值
6

computed

您可以通过调用方法来计算参数的值(无论何时更改),并且值将简化为方法名称和参数列表。

字符串
7

observer

当属性值更改时,调用简化值为方法名称的方法。

字符串

属性反序列化

根据指定的类型反序列化与实例上属性匹配的属性名称以及元素实例上的相同属性名称(如果在属性对象中配置了该属性)。

如果在属性对象中没有定义其他属性选项,则可以直接将指定的类型设置为属性的值;否则,它将向属性配置对象中的 type 键提供值。

配置布尔属性

布尔属性可以通过将其设置为 false 从标记进行配置,如果将其设置为 true,则不能从标记进行配置,因为带有或不带值的属性都等于 true。因此,它被称为 Web 平台中属性的标准行为。

对象和数组属性可以通过以 JSON 格式传递它们来配置,如下所示:

<element-demo player = '{ "name": "Sachin", "country": "India" }'></element-demo>

配置默认属性值

可以使用属性对象中的 value 字段配置默认属性,它可以是原始值,也可以是返回值的函数。

示例

以下示例描述了如何在属性对象中配置默认属性值。

<link rel = "import" href = "../../bower_components/polymer/polymer-element.html">

//it specifies the start of an element's local DOM
<dom-module id="polymer-app">
   <template>
      <style>
         :host {
            color:#33ACC9;
         }
      </style>
      <h2>Hello...[[myval]]!</h2>	
   </template>

   <script>
      //cusom element extending the Polymer.Element class
      class PolymerApp extends Polymer.Element {
         static get is() { return 'polymer-app'; }
         static get properties() {
            return {
               myval: {
                  type: String,
                  //displaying this value on screen
                  value: 'Welcome to Tutorialspoint;!!!'
               },
               data: {
                  type: Object,
                  notify: true,
                  value: function() { return {}; }
               }
            }
         }
      }
      window.customElements.define(PolymerApp.is, PolymerApp);
   </script>
</dom-module>

输出

运行如前例所示的应用程序,并导航到 http://127.0.0.1:8000/。输出如下所示。

Polymer Configure Default Property Value

只读属性

您可以通过在属性对象中将 readOnly 标志设置为 true 来避免对生成的數據进行意外更改。元素使用约定 _setProperty(value) 的 setter 来更改属性值。

示例

以下示例描述了在属性对象中使用只读属性。创建一个 index.html 文件并在其中添加以下代码

<!doctype html>
<html>
   <head>
      <title>Polymer Example</title>
      <script src = "bower_components/webcomponentsjs/webcomponents-lite.js"></script>
    
      <link rel = "import" href = "bower_components/polymer/polymer.html">
      <link rel = "import" href = "my-element.html">
   </head>
   
   <body>
      <my-element></my-element>
   </body>
</html>

现在,创建另一个名为 my-element.html 的文件并包含以下代码。

<link rel = "import" href = "bower_components/polymer/polymer-element.html">
<link rel = "import" href = "prop-element.html">

//it specifies the start of an element's local DOM
<dom-module id = "my-element">
   <template>
      <prop-element my-prop = "{{demoProp}}"></prop-element>
      <p>Present value: <span>{{demoProp}}</span></p>
   </template>

   <script>
      Polymer ({
         is: "my-element", properties: {
            demoProp: String
         }
      });
   </script>
</dom-module>

接下来,创建一个名为 prop-element.html 的文件并添加以下代码。

//it specifies the start of an element's local DOM
<dom-module id="prop-element">
   <template>
      <button on-click="onClickFunc">Change value</button>
   </template>
   
   <script>
      Polymer ({
         is: "prop-element", properties: {
            myProp: {
               type: String,
               notify: true,
               readOnly: true,
               value: 'This is initial value...'
            }
         },
         onClickFunc: function(){
            this._setMyProp('This is new value after clicking the button...');
         }
      });
   </script>
</dom-module>

输出

运行如前例所示的应用程序,并导航到 http://127.0.0.1:8081/。输出如下所示。

Polymer Read Only Properties

单击按钮后,它将更改值,如下面的屏幕截图所示。

Polymer Read Only Properties

将属性反映到属性

可以通过在属性配置对象中的属性上将 reflectToAttribute 设置为 true 来与属性值同步 HTML 属性。

属性序列化

在将属性反射或绑定到属性时,可以将属性值序列化为属性,并且默认情况下,可以根据值的当前类型序列化值。

  • 字符串 - 无需序列化。

  • 日期或数字 - 使用 toString 序列化值。

  • 布尔值 - 将显示的无值属性设置为 true 或 false。

  • 数组或对象 - 使用 JSON.stringify 序列化值。

广告