Polymer - 自定义元素

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

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

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

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

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

//ElementDemo 类扩展了 HTMLElement
class ElementDemo extends HTMLElement {
    // 代码在这里
};

//将新类与元素名称链接
window.customElements.define('element-demo', ElementDemo);

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

<element-demo></element-demo>

注意 − 自定义元素名称应以小写字母开头,并在名称之间包含破折号。

自定义元素生命周期

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

Sr.No. 反应和描述
1

constructor

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

2

connectedCallback

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

3

disconnectedCallback

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

4

attributeChangedCallback

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

元素升级

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

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

  • uncustomized − 有效的自定义元素名称是内置元素或未知元素,后者不能成为自定义元素。

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

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

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

定义元素

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

//ElementDemo 类正在扩展 Polymer.Element
class ElementDemo extends Polymer.Element {
   static get is() { return 'element-demo'; }
   static get properties() {
      . . .
      . . .
   }
   constructor(){
      super();
      . . .
      . . .
   }
   . . .
   . . .
}

//将新类与元素名称关联
window.customElements.define(ElementDemo.is, ElementDemo);

// 使用 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 标签名称。

示例

//注册元素
ElementDemo = Polymer ({
   is: 'element-demo',
   
   //这是一个遗留的回调,在元素创建时调用
   created: function() {
     this.textContent = 'Hello World!!!';
   }
});

//'createElement' 用于创建实例
var myelement1 = document.createElement('element-demo');

//使用构造函数创建实例
var myelement2 = new ElementDemo();

生命周期回调

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

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

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

  • ready −在设置属性值并初始化本地 DOM 后创建元素时会调用它。

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

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

  • attributeChanged −当元素的属性发生变化时,它会被调用,并且它保存与声明的属性不兼容的属性更改。

声明属性

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

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

  • 当属性值发生变化时,它会调用观察者方法。

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

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

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

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

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

Sr.No. 键 &描述 类型
1

type

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

构造函数(布尔值、日期、数字、字符串、数组或对象)
2

value

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

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

reflectToAttribute

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

boolean
4

readOnly

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

boolean
5

notify

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

boolean
6

computed

当参数发生变化时,可以通过调用方法来计算参数的值,值将简化为方法名和参数列表。

string
7

observer

当属性值发生变化时,调用方法名,方法名将简化为值。

string

属性反序列化

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

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

配置布尔属性

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

对象和数组属性可以通过以 JSON 格式传递它们作为 − 来进行配置

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

配置默认属性值

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

示例

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

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

//它指定元素本地 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 配置默认属性值

readOnly 属性

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

示例

以下示例描述了在 properties 对象中使用只读属性的方法。创建一个 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">

//它指定元素本地 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 的文件并添加以下代码。

//它指定元素本地 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 只读属性

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

Polymer 只读属性

将属性反映到属性

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

属性序列化

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

  • String − 无需序列化。

  • Date 或 Number − 使用 toString 序列化值。

  • Boolean − 将显示的无值属性设置为 true 或 false。

  • Array 或 Object − 使用 JSON.stringify 序列化值。