键入的Web组件为您带来了一种基于打印机的方式,以编写本机聚合物模块(聚合物工具箱友好)。整个过程在设计时间内完成,因此不需要添加其他依赖项。
npm install -g twc
TWC带有CLI。它的大部分配置来自tsconfig
(和bower.json
),并且与TSC相同。要将TS类转换为本机聚合物模块,只需输入项目root dir并在终端中执行以下操作:
twc
它像tsc
一样工作,从tsconfig.json
文件读取配置。唯一的区别是它使用聚合物模块而不是普通.js
输出.html
文件。
注释将在@types
NPM名称空间上找到。直到发生这种情况,Tsconfig中需要包括类型:
{
"compilerOptions": {
...
},
"files": [
...
],
"include": [
"node_modules/twc/types/polymer.decorators.d.ts"
]
}
TWC允许将相同的代码编译到聚合物1.x或聚合物2.x中。在编译之前,请检查bower.json
聚合物依赖性版本,然后将其用作目标。例如:
"polymer": "Polymer/polymer#^1.8.0"
将构建一个聚合物1.x模块,而该模块:
"polymer": "Polymer/polymer#^2.0.0"
构建基于ES6的聚合物2.x模块。
TypeScript编译器选项也可用于TWC,但是并非所有内容都得到了支持。以下是不支持选项的列表(将来可能最终会改变):
TWC中的模块包含了打字稿语言的语法和关键字,而只是类。遵循的约定匹配聚合物2.x(V1 Web组件规格)。
@ CustomElement ( )
export class MyElement extends Polymer . Element {
name : string ;
}
平等
<dom-module id="my-element">
<script>
Polymer({
is: "my-element",
properties: {
name: {
type: String
}
}
});
</script>
</dom-module>
有4种添加模板的方法(因此没有人感到无聊):
@template
Decorator中提供模板@template
Decorator中提供模板文件的路径template()
方法返回模板第一种方法非常普遍,您可能已经看到了多次。通常在<template>
标签之间进行的所有内容,现在都将进入装饰器。这里没有花哨的魔法。
@ CustomElement ( )
@ template ( `<h1>Hello [[name]]</h1>` )
export class MyElement extends Polymer . Element {
name : string ;
}
同样,第二种方法,您只需要提供对模板的相对路径(就像您通过<link rel="import">
tag导入的那样)。模板文件的内容应像第一个方法中的第一个方法 - <template>
标签之间的代码。
@ CustomElement ( )
@ template ( 'template.html' )
export class MyElement extends Polymer . Element {
name : string ;
}
如果您来自React世界,则可能喜欢render()
方法。因此,这里是一种非常相似的template()
方法。此方法的优点是您可以访问类原型,并且可以在模板字符串中使用它。每个this
都将用与属性的双向绑定代替(如果您有建议如何确定何时使用双向以及何时使用单向绑定,请告诉我)。
@ CustomElement ( )
export class MyElement extends Polymer . Element {
name : string ;
template ( ) {
return `<h1>Hello ${ this . name } </h1>` ;
}
}
最后的方法是将类放置并创建一个模板文件,名称与TS文件相同。在编译时间,TWC将拾取文件内容并将其附加(就像第二种方法一样)。虽然要小心!如果未指定OutDir,则最终模块可能会替换模板(默认情况下,它将以相同的基本名称生成HTML文件)。
请注意, TWC使用聚合物模板。要了解有关模板和绑定的更多信息,请参阅此文档。
ES导入尚不在浏览器中工作。相反,聚合物使用HTML导入。这使我们可以使用<link>
标签导入模块,但是我们如何在TWC中执行此操作?
import "./my-component.html";
相同的原理适用于脚本(转换为<script>
标签):
import "./some-library.js";
以上被编译为
<link rel="import" href="./my-component.html">
和
<script src="./some-library.js"></script>
分别。
处理Bower或NPM存储库的相对路径可能很痛苦。这是别名派上用场的地方:
import "bower:polymer/polymer-element.html";
import "npm:jquery/dist/jquery.min.js";
以上将被翻译为使用.bowerrc
的Bower目录,并将倒回bower_components
。由于大多数开发人员都会使用polymer-cli
来提供组件,因此bower_components
的路径将被翻译成好像项目根在该文件夹内一样。
如果出于任何原因需要更改NPM或Bower文件夹名称或路径,则可以通过设置bowerDir
和npmDir
环境变量来做到这一点。
也可以相对于项目根而导入。只需在路径的前面添加~
:
import "~demo/index.html";
import "~bower_components/polymer/polymer-element.html";
要导入其他模块的成员(例如导入行为),请使用ES导入:
import { IronControlState } from "bower:iron-behaviors/iron-control-state.html";
如果定义中有一个名称空间,它将自动升级所有导入成员的实例。
请注意,允许从HTML模块导入,您需要生成定义。
要从现有行为/组件中生成类型声明,请使用Potts工具。只需在全球安装它( npm install potts -g
),然后在项目root目录中运行potts
。默认情况下,声明将保存到potts.d.ts
文件(可通过--outFile
或-o
flag配置)。这将生成所有HTML文件的声明,请在每个Bower依赖项的bower.json
文件的main
部分中侦听。所有模块都将被宣布匹配可导入的路径(例如bower:polymer/polymer.html
)。
每个实体项目都应有适当的文档。这还包括记录组件发射的事件。 TWC可以通过创建一个扩展Event
或CustomEvent
接口来轻松地做到这一点。
/** My custom event, which fires when needed */
export interface SomeEvent extends CustomEvent {
detail: {
/** Property inside event.detail */
myCustomProp: string;
};
}
直接设置为属性声明的任何值都将用作默认值。任何非原始价值(数组,对象等)都将包裹着一个函数:
export class MyElement {
title : string = '' ;
categories : Array = [ ] ;
}
会翻译成
Polymer ( {
properties : {
title : {
type : string ,
value : ''
} ,
categories : {
type : Array ,
value : function ( ) {
return [ ] ;
}
}
}
} ) ;
并非所有内容都应添加到properties
配置中。要跳过该过程,必须将财产定义为私人:
export class MyElement {
name : string ; // is added to properties config
private hasName : boolean ; // is NOT added to properties config
}
并非使用Typecript关键字可以完成聚合物中的所有内容,但是仅阅读属性就像在读取readonly
一样容易:
export class MyElement {
readonly name : string ; // property will have `readOnly` flag
}
由于Typescript 2.2,因此支持ES Mixins。您可以在这里阅读有关它们的更多信息。
混合蛋白不受聚合物V1的支持
行为是在聚合物中共享功能的第一种方法(现在被ES Mixins取代)。它们被定义为具有聚合物属性的普通对象和列出的方法,就像聚合物V1配置对象一样。要添加行为,请使用Polymer.mixinBehaviors()
mixin(在此处提供更多信息)。对于聚合物V1,将它们添加到行为配置中,而聚合物V2将与上述混合蛋白一起使用。
如前所述,并非所有关键字都可以完成所有操作。这就是为什么TWC带有一组设计时间注释的原因。
要使用它们,请在本地安装TWC,并根据需要在元素的源文件中导入:
import { attr , compute , notify , observe , style , template } from 'twc/polymer' ;
要给您的组件一个主体,您需要为其提供模板。这是使用@template
注释来完成的,该注释接受HTML模板代码或HTML模板的路径(必须具有.html
扩展名)。
@ template ( `<h1>Hello {{name}}</h1>` )
export class MyElement {
name : string ;
}
@ template ( `template.html` )
export class MyElement {
name : string ;
}
造型该组件就像给它一个模板一样容易。 @style
注释接受CSS代码,CSS文件路径或共享样式名称。可以将多种样式提供给单个组件。
@ template ( `<h1>Hello {{name}}</h1>` )
@ style ( `:host {display: block;}` , `style.css` , `shared-styles` )
export class MyElement {
name : string ;
}
@attr
和@notify
添加反射reflectToAttribute
并将标志notify
properties
配置。
export class MyElement {
@ attr ( ) name : string ; // property will have `reflectToAttribute` flag
@ notify ( ) age : number ; // property will have `notify` flag
}
计算的属性是结合一个或多个依赖项(观察属性)的属性。每当任何依赖性更改时,计算的属性方法启动并将结果分配给属性。更多信息在这里。 TWC允许以两种方式创建它们:通过提供函数名称和依赖项数组,或直接传递解析器函数(在这种情况下,依赖项可以在字符串数组中或作为函数参数传递)。
export class MyElement {
name : string ;
age : number ;
cards : Array < string > ;
// Responds to `name` changes. Property name taken from function argument.
@ compute ( ( name : string ) => `Hi, I am ${ name } ` ) greetings : string ;
// Responds to `age` changes. Property name taken from an array.
@ compute ( ( value : number ) => value >= 18 , [ "age" ] ) isAdult : boolean ;
// Responds to both `age` and `name` changes.
@ compute ( ( age : number , name : string ) => ` ${ name } is ${ age } years old` ) aboutMe : string ;
// Responds to length of `cards` array changes. As dependency is a path, it has to be added to an array.
@ compute ( ( size ) => size , [ "cards.length" ] ) collectionSize : number ;
// Responds to name and length of `cards` array changes. Resolver method is provided by name.
@ compute ( '_summary' , [ "name" , "cards.length" ] ) summary : string ;
private _summary ( name , collectionSize ) {
return ` ${ name } has ${ collectionSize } cards` ;
}
}
您可以对任何属性或路径的反应,不仅可以通过计算的属性更改,而且可以通过观察者进行反应。观察者没有返回任何东西,这是它们之间的唯一区别。
export class MyElement {
name : string ;
cards : Array < string > ;
// Responds to name and length of `cards` array changes.
@ observe ( "name" , "cards.length" ) summary ( name , collectionSize ) {
console . log ( ` ${ name } cards collection size changed to ${ collectionSize } cards` ;
}
}
键入的Web组件处于早期阶段,需要您的反馈。请尝试一下,如果发现问题,请在问题中发布。另外,请随时发布想法!
classList
)要在Windows上运行测试( npm run test
),目前有必要修改tsconfig.json
文件的include
部分,以便包含以下模式:
{
"include" : [
" node_modules/@types/**/*.d.ts "
]
}