{"id":15376116,"url":"https://github.com/xboxyan/web-template","last_synced_at":"2025-04-14T22:50:56.841Z","repository":{"id":54367226,"uuid":"313562107","full_name":"XboxYan/web-template","owner":"XboxYan","description":"web-template.js 是一款基于 ES6 模板字符串解析的模板引擎。","archived":false,"fork":false,"pushed_at":"2021-04-11T13:34:49.000Z","size":62,"stargazers_count":121,"open_issues_count":3,"forks_count":21,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T10:54:09.465Z","etag":null,"topics":["dom","dom-diff","dom-parser","es6","html","html5","javascript","template","vue"],"latest_commit_sha":null,"homepage":"http://xboxyan.codelabo.cn/web-template/index.html","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/XboxYan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-17T09:00:30.000Z","updated_at":"2024-11-10T15:45:46.000Z","dependencies_parsed_at":"2022-08-13T13:31:17.069Z","dependency_job_id":null,"html_url":"https://github.com/XboxYan/web-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XboxYan%2Fweb-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XboxYan%2Fweb-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XboxYan%2Fweb-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XboxYan%2Fweb-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/XboxYan","download_url":"https://codeload.github.com/XboxYan/web-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975299,"owners_count":21192199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dom","dom-diff","dom-parser","es6","html","html5","javascript","template","vue"],"created_at":"2024-10-01T14:06:05.996Z","updated_at":"2025-04-14T22:50:56.809Z","avatar_url":"https://github.com/XboxYan.png","language":"HTML","readme":"# web-template\n\nweb-template.js 是一款基于 [ES6 模板字符串](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings)解析的模板引擎。\n\n## 特点\n\n1. 纯原生浏览器解析，无任何依赖，无需编译，不拖泥带水\n1. 类 vue 模板语法，上手快，几乎可以不用看文档\n1. 支持 dom-diff 局部更新，性能高效\n1. 代码量极少，~~包含注释不到 100 行~~（由于添加了 dom-diff 特性，已经超过 100 行了~），方便学习和扩展\n\n[演示 demo](https://xboxyan.codelabo.cn/web-template/index.html)\n\n## 更新\n\n* 2020-11-27\n  * 列表渲染支持 `key` 属性\n* 2020-11-24\n  * 支持 `dom-diff` 局部更新\n* 2020-11-20\n  * 新增 `mount` 方法\n  * 新增 `block` 标签\n* 2020-11-19\n  * 支持 `{{}}` 插值表达式\n  * 新增 `fragment` 标签\n  * 新增 `open` 布尔值属性\n\n## 适用场景\n\n适用于原生开发，又希望有一定模板渲染能力的场景，比如一大堆列表循环渲染\n\n在使用之前\n\n```js\nvar html = '';\narrData.forEach(function (obj, index) {\n    html = html + '\\\n    \u003ctr\u003e\\\n        \u003ctd\u003e\u003cinput type=\"checkbox\" value=\"' + obj.id + '\"\u003e\u003c/td\u003e\\\n        \u003ctd\u003e\u003cdiv class=\"ell\"\u003e' + obj.title + '\u003c/div\u003e\u003c/td\u003e\\\n        \u003ctd\u003e' + obj.time + '\u003c/td\u003e\\\n        \u003ctd align=\"right\"\u003e' + obj.comment + '\u003c/td\u003e\\\n    \u003c/tr\u003e';\n});\nconsole.log(html);\n```\n\n使用 ES6 模板字符串\n\n```js\nlet html = `${data.map(function (obj, index) {\n  return `\u003ctr\u003e\n    \u003ctd\u003e\u003cinput type=\"checkbox\" value=\"${obj.id}\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cdiv class=\"ell\"\u003e${obj.title}\u003c/div\u003e\u003c/td\u003e\n    \u003ctd\u003e${obj.time}\u003c/td\u003e\n    \u003ctd align=\"right\"\u003e${obj.comment}\u003c/td\u003e\n  \u003c/tr\u003e`;\n}).join('')}`;\nconsole.log(html);\n```\n\n使用 web-template.js 之后\n\n```html\n\u003ctemplate id=\"template\" rule=\"v-\"\u003e\n    \u003ctr v-for=\"obj in data\"\u003e\n        \u003ctd\u003e\u003cinput type=\"checkbox\" value=\"${obj.id}\"\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003cdiv class=\"ell\"\u003e${obj.title}\u003c/div\u003e\u003c/td\u003e\n        \u003ctd\u003e${obj.time}\u003c/td\u003e\n        \u003ctd align=\"right\"\u003e${obj.comment}\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/template\u003e\n```\n\n```js\nconsole.log(template.render(data).content); // dom节点\nconsole.log(template.render(data).innerTHML); // dom字符串\n```\n\n是不是清爽了许多，可读性也更强了\n\n## 使用方式 \n\n直接引用 `web-template.js`\n\n```html\n\u003cscript src=\"web-template.js\"\u003e\u003c/script\u003e\n```\n\n在 HTML 页面上添加 `template` 标签，放入模板\n\n```html\n\u003cul id=\"list\"\u003e\n\n\u003c/ul\u003e\n\n\u003ctemplate id=\"template\"\u003e\n  \u003cli $for=\"(item,index) in list\"\u003e${ index + 1} - ${ item }\u003c/li\u003e\n\u003c/template\u003e\n```\n\n假设有如下数据\n\n```js\nconst data = {\n  list : [ 'Apple', 'Banana', 'Cat']\n}\n\nlist.appendChild(template.render(data).content)\n```\n\n最终，页面上 ul 会被渲染成\n\n```html\n\u003cul id=\"list\"\u003e\n  \u003cli\u003e1 - Apple\u003c/li\u003e\n  \u003cli\u003e2 - Banana\u003c/li\u003e\n  \u003cli\u003e3 - Cat\u003c/li\u003e\n\u003c/ul\u003e\n```\n\n更多用法，可参考下面的详细介绍\n\n\n## 模板语法\n\n模板必须放在 `\u003ctemplate\u003e\u003c/template\u003e` 标签中\n\n```html\n\u003ctemplate\u003e\n    \u003c!-- 你的模板 --\u003e\n\u003c/template\u003e\n```\n\n\u003e 以下所有规则都在这个标签中\n\n### 1.插值\n\n数据绑定采用的是 ES6 模板字符串的语法， `${ }`：\n\n*目前已兼容 `{{ }}` 的语法*\n\n```html\n\u003cspan\u003eMessage: ${ msg }\u003c/span\u003e\n```\n\n```js\nconst data = {\n    msg: 'hello'\n}\n```\n\n返回\n\n```html\n\u003cspan\u003eMessage: hello\u003c/span\u003e\n```\n\n各种属性，或者说只要出现插值语法的地方都会被替换成普通文本\n\n```html\n\u003cspan data-type=\"${type}\"\u003eMessage: ${ msg }\u003c/span\u003e\n```\n\n```js\nconst data = {\n    msg: 'hello',\n    type: 'normal',\n}\n```\n\n返回\n\n```html\n\u003cspan data-type=\"normal\"\u003eMessage: hello\u003c/span\u003e\n```\n\n一些为布尔值的属性，比如 `disabled`、`hidden`、`required`、`checked`、`selected`、`readonly`,`open`（欢迎补充~），如果设置值为 `false` ，那么将会移除该属性\n\n```html\n\u003cbutton disabled=\"${disabled}\"\u003ebutton\u003c/button\u003e\n\u003cbutton hidden=\"${hidden}\"\u003ebutton\u003c/button\u003e\n```\n\n```js\nconst data = {\n    disabled: true,\n    hidden: false,\n}\n```\n\n返回\n\n```html\n\u003cbutton disabled=\"true\"\u003ebutton\u003c/button\u003e\n\u003cbutton\u003ebutton\u003c/button\u003e \u003c!-- hidden属性被移除 --\u003e\n```\n\n### 2.JavaScript 表达式\n\nJavaScript 表达式也可以用到模板中的任意地方\n\n```html\n\u003cspan\u003e${ number + 1 }\u003c/span\u003e\n${ ok ? 'YES' : 'NO' }\n```\n\n```js\nconst data = {\n    number: 10,\n    ok: true,\n}\n```\n\n返回\n\n```html\n\u003cspan\u003e11\u003c/span\u003e\nYES\n```\n\n\u003e 注意，这里是单个表达式，推荐使用三元表达式，vue 和 react 也是同样的规定\n\nJavaScript 函数也可以直接访问，可以是全局函数，也可以是自己定义的函数\n\n```html\n\u003cspan\u003e${ new Date() }\u003c/span\u003e\n\u003cspan\u003e${ add(1,2) }\u003c/span\u003e\n```\n\n```js\n// 定义在全局的函数\nfunction add(m,n){\n    return m + n\n}\n```\n\n\n返回\n\n```html\n\u003cspan\u003eTue Nov 17 2020 11:13:44 GMT+0800 (中国标准时间)\u003c/span\u003e\n\u003cspan\u003e3\u003c/span\u003e\n```\n\n更极端的是，可以直接嵌套函数，但是必须是立即执行函数\n\n```html\n\u003cspan\u003e${\n    (()=\u003e{\n        return 'hello';\n    })()    \n}\u003c/span\u003e\n```\n\n返回\n\n```html\n\u003cspan\u003ehello\u003c/span\u003e\n```\n\n\u003e 当然强烈不推荐这么做，把一段 js 放在 html 中实在不怎么优雅\n\n### 3.指令\n\n指令是带有特殊前缀的属性，默认是 `$`，当然你也可以更换成你喜欢的，比如 `v-`，通过修改 `template` 标签的 rule 属性\n\n```html\n\u003ctemplate rule=\"v-\"\u003e\n    \u003c!-- 模板 --\u003e\n\u003c/template\u003e\n```\n\n\u003e 以下就以 `v-` 为例\n\n目前有两个指令，分别是**条件渲染**和**列表渲染**\n\n#### 3.1.条件渲染\n\n`v-if` 用来条件性地渲染一块内容，当值为 false 时，内容会被完全移除\n\n```html\n\u003ch1 v-if=\"show\"\u003eTemplate is awesome!\u003c/h1\u003e\n\u003ch1 v-if=\"!show\"\u003eOh no 😢\u003c/h1\u003e\n```\n\n```js\nconst data = {\n    show: true\n}\n```\n\n返回\n\n```html\n\u003ch1\u003eTemplate is awesome!\u003c/h1\u003e\n\u003c!-- $if H1 --\u003e\n```\n\n\u003e 注意，指令的属性值不需要包裹 `${ }`\n\n `v-show` 内部通过属性 `hidden` 来实现样式上的隐藏\n\n```html\n\u003ch1 v-show=\"show\"\u003eTemplate is awesome!\u003c/h1\u003e\n\u003ch1 v-show=\"!show\"\u003eOh no 😢\u003c/h1\u003e\n```\n\n```js\nconst data = {\n    show: true\n}\n```\n\n返回\n\n```html\n\u003ch1\u003eTemplate is awesome!\u003c/h1\u003e\n\u003ch1 hidden\u003eOh no 😢\u003c/h1\u003e \u003c!--样式上被隐藏--\u003e\n```\n\n\u003e 注意，这里是普通的属性，所以需要包裹 `${ }`\n\n#### 3.2.列表渲染\n\n##### 别名\n\n`v-for` 用来循环渲染一个列表，格式形如 `item in items`，其中 `items` 是数据源，`item` 是被循环的数组元素的**别名**。\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"item in items\"\u003e\n    ${ item.message }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n```js\nconst data = {\n    items: [\n        { message: 'Foo' },\n        { message: 'Bar' }\n    ]\n}\n```\n\n返回\n\n```html\n\u003cli\u003eFoo\u003c/li\u003e\n\u003cli\u003eBar\u003c/li\u003e\n```\n\n##### 索引\n\n此外，还支持第二个可选参数，表示**索引**（默认为 `index` ），形如 `(item,index) in items`\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"(item,index) in items\"\u003e\n    ${ index } - ${ item.message }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cli\u003e0 - Foo\u003c/li\u003e\n\u003cli\u003e1 - Bar\u003c/li\u003e\n```\n\n##### 作用域\n\n每个循环都有自己的作用域，这在多重循环中特别有用，如下可以轻易的实现一个 9*9 乘法表\n\n```html\n\u003ctemplate\u003e\n  \u003cdiv v-for=\"i in [1,2,3,4,5,6,7,8,9]\"\u003e\n    \u003cspan v-for=\"j in [1,2,3,4,5,6,7,8,9]\" v-if=\"i\u003e=j\"\u003e ${i*j} \u003c/span\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cdiv\u003e\n    \u003cspan\u003e 1 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 2 \u003c/span\u003e\u003cspan\u003e 4 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 3 \u003c/span\u003e\u003cspan\u003e 6 \u003c/span\u003e\u003cspan\u003e 9 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 4 \u003c/span\u003e\u003cspan\u003e 8 \u003c/span\u003e\u003cspan\u003e 12 \u003c/span\u003e\u003cspan\u003e 16 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 5 \u003c/span\u003e\u003cspan\u003e 10 \u003c/span\u003e\u003cspan\u003e 15 \u003c/span\u003e\u003cspan\u003e 20 \u003c/span\u003e\u003cspan\u003e 25 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 6 \u003c/span\u003e\u003cspan\u003e 12 \u003c/span\u003e\u003cspan\u003e 18 \u003c/span\u003e\u003cspan\u003e 24 \u003c/span\u003e\u003cspan\u003e 30 \u003c/span\u003e\u003cspan\u003e 36 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 7 \u003c/span\u003e\u003cspan\u003e 14 \u003c/span\u003e\u003cspan\u003e 21 \u003c/span\u003e\u003cspan\u003e 28 \u003c/span\u003e\u003cspan\u003e 35 \u003c/span\u003e\u003cspan\u003e 42 \u003c/span\u003e\u003cspan\u003e 49 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 8 \u003c/span\u003e\u003cspan\u003e 16 \u003c/span\u003e\u003cspan\u003e 24 \u003c/span\u003e\u003cspan\u003e 32 \u003c/span\u003e\u003cspan\u003e 40 \u003c/span\u003e\u003cspan\u003e 48 \u003c/span\u003e\u003cspan\u003e 56 \u003c/span\u003e\u003cspan\u003e 64 \u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003cspan\u003e 9 \u003c/span\u003e\u003cspan\u003e 18 \u003c/span\u003e\u003cspan\u003e 27 \u003c/span\u003e\u003cspan\u003e 36 \u003c/span\u003e\u003cspan\u003e 45 \u003c/span\u003e\u003cspan\u003e 54 \u003c/span\u003e\u003cspan\u003e 63 \u003c/span\u003e\u003cspan\u003e 72 \u003c/span\u003e\u003cspan\u003e 81 \u003c/span\u003e\n\u003c/div\u003e\n```\n\n##### 简写\n\n每次都要写 `item in items` 有些麻烦，这里可以简写成 `items`，此时默认**别名**和**索引**分别是 `item` 和 `index`\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"items\"\u003e\n    ${ index } - ${ item.message }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cli\u003e0 - Foo\u003c/li\u003e\n\u003cli\u003e1 - Bar\u003c/li\u003e\n```\n\n##### 重复次数\n\n`v-for` 也可以接受整数。在这种情况下，它会把模板重复对应次数。\n\n```html\n\u003ctemplate\u003e\n  \u003cspan v-for=\"10\"\u003e${ index } \u003c/span\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cspan\u003e0\u003c/span\u003e\n\u003cspan\u003e1\u003c/span\u003e\n\u003cspan\u003e2\u003c/span\u003e\n\u003cspan\u003e3\u003c/span\u003e\n\u003cspan\u003e4\u003c/span\u003e\n\u003cspan\u003e5\u003c/span\u003e\n\u003cspan\u003e6\u003c/span\u003e\n\u003cspan\u003e7\u003c/span\u003e\n\u003cspan\u003e8\u003c/span\u003e\n\u003cspan\u003e9\u003c/span\u003e\n```\n\n\u003e 虽然有些鸡肋，某些情况下还是有点作用的\n\n返回如上\n\n##### 使用 key 属性\n\n如果列表有可能会发生顺序改变，可以指定一个不重复的 key ，这样在渲染时会优先根据 key 的顺序重新排序，而不会重新渲染。\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"items\" key=\"${item.id}\"\u003e\n    ${ index } - ${ item.message }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n\u003e 目前仅适用于循环渲染\n\n##### 对象迭代\n\n你也可以用 `v-for` 来遍历一个对象，这里用 `of` 来区分，形如 `value of object`\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"value of object\"\u003e\n    ${ value }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n```js\nconst data = {\n    object: {\n        title: 'How to do lists in Vue',\n        author: 'Jane Doe',\n        publishedAt: '2016-04-10'\n    }\n}\n```\n\n返回\n\n```html\n\u003cli\u003eHow to do lists in Vue\u003c/li\u003e\n\u003cli\u003eJane Doe\u003c/li\u003e\n\u003cli\u003e2016-04-10\u003c/li\u003e\n```\n\n同时，支持三个参数，形如 `(value, name, index) of object`，分别为**值**、**键名**、**索引**\n\n```html\n\u003ctemplate\u003e\n  \u003cli v-for=\"(value, name, index) of object\"\u003e\n    ${ index }. ${ name }. ${ value }\n  \u003c/li\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cli\u003e0. title. How to do lists in Vue\u003c/li\u003e\n\u003cli\u003e1. author. Jane Doe\u003c/li\u003e\n\u003cli\u003e2. publishedAt. 2016-04-10\u003c/li\u003e\n```\n\n\u003e 对象迭代不支持简写，尽量多使用数组遍历吧\n\n#### 3.3 fragment 片段\n\n有时候我们可能需要遍历这样一种没有父级的元素\n\n```html\n\u003cdl\u003e\n  \u003cdt\u003e\u003c/dt\u003e  \n  \u003cdd\u003e\u003c/dd\u003e\n  \u003cdt\u003e\u003c/dt\u003e  \n  \u003cdd\u003e\u003c/dd\u003e \n  \u003cdt\u003e\u003c/dt\u003e  \n  \u003cdd\u003e\u003c/dd\u003e \n\u003cdl\u003e\n```\n\n这时可以借助 fragment 标签包裹，渲染后 fragment 标签会被移除\n\n```html\n\u003ctemplate\u003e\n  \u003cdl\u003e\n    \u003cfragment v-for=\"[1,2,3]\"\u003e\n      \u003cdt\u003e\u003c/dt\u003e\n      \u003cdd\u003e\u003c/dd\u003e\n    \u003c/fragment\u003e\n  \u003c/dl\u003e\n\u003c/template\u003e\n```\n\n在 `v-if` 中也适用的\n\n```html\n\u003ctemplate\u003e\n  \u003cdl\u003e\n    \u003cfragment v-if=\"true\"\u003e\n      \u003cdt\u003e1 dt\u003c/dt\u003e\n      \u003cdd\u003e1 dd\u003c/dd\u003e\n    \u003c/fragment\u003e\n    \u003cfragment v-if=\"false\"\u003e\n      \u003cdt\u003e2 dt\u003c/dt\u003e\n      \u003cdd\u003e2 dd\u003c/dd\u003e\n    \u003c/fragment\u003e\n  \u003c/dl\u003e\n\u003c/template\u003e\n```\n\n返回\n\n```html\n\u003cdl\u003e\n  \u003cdt\u003e1 dt\u003c/dt\u003e\n  \u003cdd\u003e1 dd\u003c/dd\u003e\n\u003c/dl\u003e\n```\n\n其他任意地方也可以添加，只不过不会被渲染\n\n\u003e 也可使用 block 标签，功能完全一致 （参考微信小程序）\n\n### 4.渲染\n\n在原生 `template` 标签扩展了 `render` 方法，可以传入一个对象，然后返回一个 `template`文档片段（[`document-fragment`](https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment)）\n\n```js\nconst tpl = template.render(data) // template document-fragment\n\ntpl.content;  // 返回dom节点\ntpl.innerHTML;  // 返回字符串\n```\n\n一般通过 `.content` 可以得到模板的 dom 结构，直接以 `appendChild` 的方式渲染到页面，这种方式在追加数据的时候更加有效\n\n```js\ncontainer.appendChild(tpl.content);\n```\n\n如果内容需要重置，可以简单粗暴的使用 `.innerHTML`\n\n```js\ncontainer.innerHTML = tpl.innerHTML;\n```\n\n如果需要局部更新，可使用 `.html()` 方法\n\n```js\n// 支持dom节点\ncontainer.html(tpl.content);\n// 字符串也支持\ncontainer.html(tpl.innerHTML);\n```\n\n### 5. 挂载\n\n一般情况通过 `template.render(data)` 来获取到模板的内容，然后再通过容器的 `.innerHTML` 就可以了，但是有些啰嗦，这里提供一个更为简单的方法 `template.mount()`\n\n需要在容器上指定和模板 id 相同的值，形成映射关系，比如\n\n```html\n\u003cdiv is=\"tpl\"\u003e\u003c/div\u003e\n\n\u003ctemplate id=\"tpl\"\u003e\n  \u003cspan class=\"name\"\u003e${name}\u003c/span\u003e\n\u003c/template\u003e\n```\n\n然后执行\n\n```js\ntpl.mount(data);\n```\n\n这样模板内容就自动挂载在页面上了\n\n\u003e 一般情况下均可满足，不满足的情况可以采用 render 方式，更加灵活\n\n如果需要局部更新，可以传入第2个参数，表示是否进行 diff 比较\n\n```js\ntpl.mount(data, isDiff);\n```\n\n\u003e 一般情况下，diff 并不会比直接 innerHTML 要快，但是可以保留元素的状态，建议初次渲染选择 innerHTML，后面更新使用 dom-diff\n\n## 兼容性和一些局限\n\n需要支持 ES6 模板字符串语法的浏览器，还在用 IE 的小伙伴可以放弃了\n\ndom-diff 基本够用，还有待完善\n\n由于使用了很多 DOM API，依赖浏览器环境，因此不支持 Node 等其他非浏览器环境，不支持服务端渲染\n\n## 参考\n\n[Vue 模板语法](https://cn.vuejs.org/v2/guide/syntax.html)\n\n[ES6模板字符串在HTML模板渲染中的应用](https://www.zhangxinxu.com/wordpress/2020/10/es6-html-template-literal/)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxboxyan%2Fweb-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxboxyan%2Fweb-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxboxyan%2Fweb-template/lists"}