原文:https://lit-element.polymer-project.org/guide/templates

1、定义一个渲染模板

1.1 基本规则

要用LitElement 组件定义一个模板,必须为你的模板类写一个render方法:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
render() {
return html`<p>template content</p>`;
}
}

这里 html`...` 中 html 是引用的父类函数,用模板字符串包裹原始的HTML标签

组件的 render 方法可以返回 lit-html 可以渲染的任何内容。通常,它返回单个 TemplateResult 对象(与 html 标记函数返回的类型相同)。

完整的例子

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {

  // Implement `render` to define a template for your element.
render(){
/**
* Return a lit-html `TemplateResult`.
*
* To create a `TemplateResult`, tag a JavaScript template literal
* with the `html` helper function.
*/
return html`
<div>
<p>A paragraph</p>
</div>
`;
}
}
customElements.define('my-element', MyElement);

1.2 动态更改模板内容

我们可以通过捕获加载消息作为属性,并根据事件设置属性来改变模板:update-properties.js

import { LitElement, html } from 'lit-element';

/**
* Use this pattern instead.
*/
class UpdateProperties extends LitElement {
static get properties(){
return {
message: String
};
}
constructor() {
super();
this.message = 'Loading';
this.addEventListener('stuff-loaded', (e) => { this.message = e.detail } );
this.loadStuff();
}
render() {
return html`
<p>${this.message}</p>
`;
}
loadStuff() {
setInterval(() => {
let loaded = new CustomEvent('stuff-loaded', {
detail: 'Loading complete.'
});
this.dispatchEvent(loaded);
}, 3000);
}
} customElements.define('update-properties', UpdateProperties);

该例子中为模板元素绑定了一个加载事件,事件函数模拟3秒后改变元素属性值,从而动态改变模板。这是动态改变模板的方法。

注意:每一个模板类都必须引用  import { html, LitElement } from 'lit-element'; 就算套用了其他模板也是一样

2、在模板中使用属性、循环和条件判断

2.1 属性

static get properties() {
return { myProp: String };
}
...
render() {
return html`<p>${this.myProp}</p>`;
}

通过静态的 get properties() 函数指定属性的类型, 构造函数 constructor() 初始化属性的初始值

2.2 循环

html`<ul>
${this.myArray.map(i => html`<li>${i}</li>`)}
</ul>`;

ES6数组的map方法,为每一个数组元素执行括号中的操作

2.3 三目运算符

html`
${this.myBool?
html`<p>Render some HTML if myBool is true</p>`:
html`<p>Render some other HTML if myBool is false</p>`}
`;

完整的例子

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() {
return {
myString: { type: String },
myArray: { type: Array },
myBool: { type: Boolean }
};
}
constructor() {
super();
this.myString = 'Hello World';
this.myArray = ['an','array','of','test','data'];
this.myBool = true;
}
render() {
return html`
<p>${this.myString}</p>
<ul>
${this.myArray.map(i => html`<li>${i}</li>`)}
</ul>
${this.myBool?
html`<p>Render some HTML if myBool is true</p>`:
html`<p>Render some other HTML if myBool is false</p>`}
`;
}
} customElements.define('my-element', MyElement);

一个包含了 get properties(), constructor(), render() 方法的模板

3、给模板元素绑定属性值

您可以插入JavaScript表达式作为HTML文本内容,基本属性,布尔属性,元素属性和事件处理器的占位符。

  • Text content: <p>${...}</p>
  • Attribute: <p id="${...}"></p>
  • Boolean attribute: ?disabled="${...}"
  • Property: .value="${...}"
  • Event handler: @event="${...}"

3.1 绑定到正文

html`<div>${this.prop1}</div>`

3.2 绑定到基本属性

html`<div id="${this.prop2}"></div>`

3.3 绑定到布尔类型属性

html`<input type="text" ?disabled="${this.prop3}">`

3.4 绑定到元素属性

html`<input type="checkbox" .value="${this.prop4}"/>`

3.5 绑定到事件处理程序

html`<button @click="${this.clickHandler}">pie?</button>`

完整的例子

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
static get properties() {
return {
prop1: String,
prop2: String,
prop3: Boolean,
prop4: String
};
}
constructor() {
super();
this.prop1 = 'text binding';
this.prop2 = 'mydiv';
this.prop3 = true;
this.prop4 = 'pie';
}
render() {
return html`
<!-- text binding -->
<div>${this.prop1}</div> <!-- attribute binding -->
<div id="${this.prop2}">attribute binding</div> <!-- boolean attribute binding -->
<div>
boolean attribute binding
<input type="text" ?disabled="${this.prop3}"/>
</div> <!-- property binding -->
<div>
property binding
<input type="text" .value="${this.prop4}"/>
</div> <!-- event handler binding -->
<div>event handler binding
<button @click="${this.clickHandler}">click</button>
</div>
`;
}
clickHandler(e) {
console.log(e.target);
}
} customElements.define('my-element', MyElement);

4、使用slot占位符给模板元素渲染子节点

4.1 slot标签

要实现如下形式的渲染,必须通过slot占位符标签实现

<my-element>
<p>A child</p>
</my-element>

默认情况下,如果元素具有阴影树,则其子元素根本不会渲染。

要渲染子节点,您的模板需要包含一个或多个<slot>元素,这些元素充当子节点的占位符。

例如定义如下形式的模板

render(){
return html`
<div>
<slot></slot>
</div>
`;
}

就可以在 <slot> 标签的位置渲染子节点

<my-element>
<p>Render me</p>
</my-element>

这些子项不会在DOM树中移动,但会像它们是<slot>的子项一样呈现。

任意多个子节点可以填充到一个slot:

<my-element>
<p>Render me</p>
<p>Me too</p>
<p>Me three</p>
</my-element>

4.2 使用命名的slot

要将子节点分配给特定的 slot ,请确保该子节点的 slot 属性与该 slot 的 name 属性匹配:

render(){
return html`
<div>
<slot name="one"></slot>
</div>
`;
}
<my-element>
<p slot="one">Include me in slot "one".</p>
</my-element>

命名 slot 仅接受具有匹配 slot 属性的子节点。

例如:

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
render(){
return html`
<div>
<slot name="one"></slot>
<slot name="two"></slot>
</div>
`;
}
}
customElements.define('my-element', MyElement);

one对one,two对two,没有名字的不会被渲染

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script> <script type="module" src="./my-element.js"></script>
<title>lit-element code sample</title>
</head>
<body>
<!-- Assign child to a specific slot --> <my-element>
<p slot="two">Include me in slot "two".</p>
</my-element> <!--
Named slots only accept children with a matching `slot` attribute. Children with a `slot` attribute can only go into a slot with a matching name.
--> <my-element>
<p slot="one">Include me in slot "one".</p>
<p slot="nope">This one will not render at all.</p>
<p>No default slot, so this one won't render either.</p>
</my-element>
</body>
</html>

5、多个模板组合成页面

您可以从其他LitElement模板组成新的LitElement模板。在以下示例中,我们通过导入其他元素并在模板中使用它们来组成新的<my-page>模板:

my-article.js

import { LitElement, html } from 'lit-element';

class MyArticle extends LitElement {
render() {
return html`
<article>article</article>
`;
}
}
customElements.define('my-article', MyArticle);

my-header.js

import { html, LitElement } from 'lit-element';

class MyHeader extends LitElement {
render() {
return html`
${this.headerTemplate}
`;
}
get headerTemplate() {
return html`<header>header</header>`;
}
}
customElements.define('my-header', MyHeader);

my-footer.js

import { LitElement, html } from 'lit-element';

class MyFooter extends LitElement {
render() {
return html`
<footer>footer</footer>
`;
}
}
customElements.define('my-footer', MyFooter);

用以上三个子模版元素组成页面元素my-page.js

import { LitElement, html } from 'lit-element';

import './my-header.js';
import './my-article.js';
import './my-footer.js'; class MyPage extends LitElement {
render() {
return html`
<my-header></my-header>
<my-article></my-article>
<my-footer></my-footer>
`;
}
}
customElements.define('my-page', MyPage);

然后配一个 模板元素整合文件,例如 mian.js

import './my-page.js';

在页面 my-page.html中引用这个文件

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lit-element code sample</title>
<script src="main.js"></script>
</head> <body>
<my-page></my-page>
<script src="webcomponents-loader.js"></script>
</body> </html>

此时可能有 index.html, my-page.html两个页面, index.js, main.js两个脚本文件,需要同时打包输出,修改rollup,config.js文件,以数组形式输出多个js文件

import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel'; export default [{
input: ['src/index.js'],
output: {
file: 'build/index.js',
format: 'es',
sourcemap: true
},
plugins: [
resolve(),
babel()
],
},{
input: ['src/main.js'],
output: {
file: 'build/main.js',
format: 'es',
sourcemap: true
},
plugins: [
resolve(),
babel()
]
}];

修改package.json中的html打包命令

"scripts": {
"copyindex": "cp src/*.html build",
"copywc": "cp -r node_modules/@webcomponents/webcomponentsjs/bundles build && cp node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js build",
"build": "rm -rf build && mkdir build && npm run copyindex && npm run copywc && rollup -c",
"start": "serve build"
},

就可以在build下生成两个html文件及其对应的js文件了,其他同理可得

6、 lit-html

lit-html作为LitElement的核心,可以使用很多它的其他功能

npm i lit-element@^2.0.0
npm i lit-html@^1.0.0

例如:

import { LitElement, html } from 'lit-element';
import { until } from 'lit-html/directives/until.js'; const content = fetch('./content.txt').then(r => r.text()); html`${until(content, html`<span>Loading...</span>`)}`

读取一个文件内容作为渲染内容

其他详见文档:https://lit-html.polymer-project.org/guide/template-reference#built-in-directives

LitElement(二)模板编写基本语法的更多相关文章

  1. thinkPHP 模板中的语法知识 详细介绍(十二)

    原文:thinkPHP 模板中的语法知识 详细介绍(十二) 本章节:介绍模板中的语法,详细的语法介绍 一.导入CSS和JS文件    ==>记住常量的是大写 1.css link .js  sc ...

  2. (转)dedecms网页模板编写

    网页模板就是templets中的htm文件,所以编写模板就是要编写html.这篇文章不是关于标签的具体使用,而是对网页模板的一些理解.包括基本的标签语法,封面模板,列表模板和文档模板的关系. 一 关于 ...

  3. python MVC、MTV 框架介绍 Django 模板系统常用语法

    Django 框架简介一.MVC框架和MTV框架1.MVC 全名Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分.优势: 耦合性低 重用性高 生命 ...

  4. c/c++ 模板与STL小例子系列<二> 模板类与友元函数

    c/c++ 模板与STL小例子系列 模板类与友元函数 比如某个类是个模板类D,有个需求是需要重载D的operator<<函数,这时就需要用到友元. 实现这样的友元需要3个必要步骤 1,在模 ...

  5. 一、 JSP概述 二、JSP的语法结构 三、JSP内置对象

    一.JSP概述###<1>概念 java服务器页面 可以编写动态页面 其内部是以HTML标签为主,可以在HTML标签嵌套java代码 jsp文件以.jsp为后缀 jsp本质上就是一个Ser ...

  6. iOS 11开发教程(二)编写第一个iOS 11应用

    iOS 11开发教程(二)编写第一个iOS 11应用 编写第一个iOS 11应用 本节将以一个iOS 11应用程序为例,为开发者讲解如何使用Xcode 9.0去创建项目,以及iOS模拟器的一些功能.编 ...

  7. JVM(二):Java中的语法糖

    JVM(二):Java中的语法糖 上文讲到在语义分析中会对Java中的语法糖进行解糖操作,因此本文就主要讲述一下Java中有哪些语法糖,每个语法糖在解糖过后的原始代码,以及这些语法糖背后的逻辑. 语法 ...

  8. Django(二)模板

    一.模板概念 1.Django通过模板动态生成html 2.模板的加载位置 模板一般建立在templates文件夹中,全局路径的设置在settings.py中 ​ DIRS:决定了整个项目的模板路径的 ...

  9. hexo文章编写部分语法总结以及hexo使用

    一.hexo的使用 1.1 新建一篇文章 1 $ hexo new [layout] <title> 1.2. 生成静态文件 1 $ hexo generate 可简写为 1 $ hexo ...

随机推荐

  1. PTA 汉诺塔的非递归实现(C 语言)

    借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c), 即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”), 并保证每个移动符合汉诺塔问题的要求 ...

  2. bootstrap支持ie8 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

    做一个在线系统,PC端也要做,但要兼容千恶的IE8[IE6 是万恶,打死我都不会管IE6],IE8 是我底线了md, 在IE8下 bottstrap 错乱,变形,不支持一些属性的问题,下面看了一篇 某 ...

  3. Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树

    给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...

  4. .NET/C# 万能 HTTP 模拟请求框架

    我是一名 ASP.NET 程序员,专注于 B/S 项目开发.累计文章阅读量超过一千万,我的博客主页地址:https://www.itsvse.com/blog_xzz.html HttpHelper ...

  5. Python If&字典 初学者笔记

    and 当俩个条件都满足时为True否为False or 任意一个条件满足时为True否为Flase not in  通常用于If语句,用来判断一个元素是否不在某个列表中 banned_user = ...

  6. C++->10.3.6.设有两个按升序排列的二进制文件a和b,将他们合并成一个新的升序二进制数据文件file。

    #include<iostream.h> #include<stdlib.h> #include<string.h> #include<fstream.h&g ...

  7. html行内元素、块级元素及空元素有哪些?区别是什么?

    一. html标签有哪些? 1)行内元素有哪些? 行内元素:行内大多为描述性标记 <span>...</span> <a>...</a>  链接. 锚点 ...

  8. 大话STM32F103系统架构

    前言 许多像我一样的STM32初学者,都往往忽视了STM32系统架构的学习.这对于实际应用并没有啥大的影响,但是总感觉怎么学也无法看清STM32的全貌,所以本文我将带领大家一起厘清STM32F103的 ...

  9. java打印出某一指定路径下的文件夹内的所有子文件夹和文件,并区分开来

    public class printoutFile { public static void main(String[] args) { printFile(new File("D:\\te ...

  10. Phalanx HDU - 2859 dp

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> us ...