From cd401b84366c2ea6647a9131f63487e03b9b51f9 Mon Sep 17 00:00:00 2001 From: errorrik Date: Sun, 17 Dec 2023 00:53:34 +0800 Subject: [PATCH] deploy san website --- archives/2020/06/index.html | 41 +- archives/2020/06/page/2/index.html | 41 +- archives/2020/06/page/3/index.html | 41 +- archives/2020/06/page/4/index.html | 41 +- archives/2020/06/page/5/index.html | 41 +- archives/2020/06/page/6/index.html | 41 +- archives/2020/07/index.html | 41 +- archives/2020/10/index.html | 41 +- archives/2020/index.html | 41 +- archives/2020/page/2/index.html | 41 +- archives/2020/page/3/index.html | 41 +- archives/2020/page/4/index.html | 41 +- archives/2020/page/5/index.html | 41 +- archives/2020/page/6/index.html | 41 +- archives/2021/10/index.html | 41 +- archives/2021/10/page/2/index.html | 41 +- archives/2021/index.html | 41 +- archives/2021/page/2/index.html | 41 +- archives/2023/12/index.html | 339 ++++++++++++++++ archives/2023/12/page/2/index.html | 339 ++++++++++++++++ archives/2023/index.html | 339 ++++++++++++++++ archives/2023/page/2/index.html | 339 ++++++++++++++++ archives/index.html | 41 +- archives/page/10/index.html | 339 ++++++++++++++++ archives/page/2/index.html | 41 +- archives/page/3/index.html | 41 +- archives/page/4/index.html | 41 +- archives/page/5/index.html | 41 +- archives/page/6/index.html | 41 +- archives/page/7/index.html | 41 +- archives/page/8/index.html | 41 +- archives/page/9/index.html | 339 ++++++++++++++++ categories/component/index.html | 339 ++++++++++++++++ categories/component/page/2/index.html | 339 ++++++++++++++++ categories/doc/index.html | 41 +- categories/practice/index.html | 41 +- categories/practice/page/2/index.html | 41 +- categories/practice/page/3/index.html | 41 +- categories/practice/page/4/index.html | 41 +- categories/tutorial/index.html | 41 +- categories/tutorial/page/2/index.html | 41 +- categories/tutorial/page/3/index.html | 41 +- categories/tutorial/page/4/index.html | 41 +- component/async/index.html | 306 +++++++++++++++ component/data/index.html | 312 +++++++++++++++ component/define/index.html | 301 +++++++++++++++ component/error/index.html | 307 +++++++++++++++ component/hydrate/index.html | 324 ++++++++++++++++ component/lifecycle/index.html | 314 +++++++++++++++ component/template-component/index.html | 314 +++++++++++++++ component/tree/index.html | 361 ++++++++++++++++++ component/view/index.html | 334 ++++++++++++++++ css/article.css | 5 +- css/style.css | 6 +- doc/api/index.html | 229 +++++++---- doc/main-members/index.html | 189 +++++---- en/component/async/index.html | 307 +++++++++++++++ en/component/data/index.html | 312 +++++++++++++++ en/component/define/index.html | 301 +++++++++++++++ en/component/error/index.html | 307 +++++++++++++++ en/component/hydrate/index.html | 322 ++++++++++++++++ en/component/lifecycle/index.html | 314 +++++++++++++++ en/component/template-component/index.html | 291 ++++++++++++++ en/component/tree/index.html | 361 ++++++++++++++++++ en/component/view/index.html | 333 ++++++++++++++++ en/doc/api/index.html | 181 ++++++--- en/doc/main-members/index.html | 150 +++++--- en/example/index.html | 59 ++- en/index.html | 44 ++- .../index.html | 91 +++-- en/practice/auto-camel/index.html | 91 +++-- en/practice/can-we-use-dom/index.html | 90 +++-- en/practice/child-to-grandparent/index.html | 88 +++-- en/practice/child-to-parent/index.html | 80 ++-- en/practice/data-invalid/index.html | 84 ++-- en/practice/data-valid/index.html | 76 ++-- en/practice/dynamic-parent-child/index.html | 87 +++-- .../how-to-show-or-hide-an-element/index.html | 131 +++++-- en/practice/index.html | 59 ++- en/practice/parent-to-child/index.html | 91 +++-- en/practice/position-absolute-dom/index.html | 113 ++++-- en/practice/question-and-answer/index.html | 78 ++-- en/practice/san-composition-api/index.html | 142 ++++--- en/practice/san-router-spa/index.html | 89 +++-- en/practice/san-store-spa/index.html | 101 +++-- en/practice/traverse-object/index.html | 81 ++-- en/tutorial/background/index.html | 91 +++-- en/tutorial/component/index.html | 218 +++++++---- en/tutorial/data-checking/index.html | 83 ++-- en/tutorial/data-method/index.html | 177 ++++++--- en/tutorial/event/index.html | 110 ++++-- en/tutorial/for/index.html | 108 ++++-- en/tutorial/form/index.html | 100 +++-- en/tutorial/if/index.html | 95 +++-- en/tutorial/reverse-flag/index.html | 168 +++++--- en/tutorial/reverse/index.html | 104 +++-- en/tutorial/setup/index.html | 120 ++++-- en/tutorial/slot/index.html | 130 ++++--- en/tutorial/ssr-before-3.8/index.html | 87 +++-- en/tutorial/ssr/index.html | 107 ++++-- en/tutorial/start/index.html | 110 ++++-- en/tutorial/style/index.html | 94 +++-- en/tutorial/template/index.html | 129 +++++-- en/tutorial/transition/index.html | 102 +++-- example/index.html | 59 ++- index.html | 45 ++- page/10/index.html | 339 ++++++++++++++++ page/2/index.html | 41 +- page/3/index.html | 41 +- page/4/index.html | 41 +- page/5/index.html | 41 +- page/6/index.html | 41 +- page/7/index.html | 41 +- page/8/index.html | 41 +- page/9/index.html | 339 ++++++++++++++++ .../index.html | 93 +++-- practice/auto-camel/index.html | 91 +++-- practice/can-we-use-dom/index.html | 92 +++-- practice/child-to-grandparent/index.html | 90 +++-- practice/child-to-parent/index.html | 86 +++-- practice/data-invalid/index.html | 90 +++-- practice/data-valid/index.html | 78 ++-- practice/dynamic-parent-child/index.html | 89 +++-- .../how-to-show-or-hide-an-element/index.html | 141 +++++-- practice/ie-compatibility/index.html | 122 ++++-- practice/index.html | 59 ++- practice/parent-to-child/index.html | 95 +++-- practice/position-absolute-dom/index.html | 111 ++++-- practice/question-and-answer/index.html | 84 ++-- practice/san-composition-api/index.html | 148 ++++--- practice/san-router-spa/index.html | 92 +++-- practice/san-store-spa/index.html | 103 +++-- practice/traverse-object/index.html | 87 +++-- service-worker.js | 268 ------------- tutorial/background/index.html | 91 +++-- tutorial/component/index.html | 281 ++++---------- tutorial/data-checking/index.html | 87 +++-- tutorial/data-method/index.html | 177 ++++++--- tutorial/event/index.html | 116 ++++-- tutorial/for/index.html | 113 ++++-- tutorial/form/index.html | 106 +++-- tutorial/if/index.html | 107 ++++-- tutorial/reverse-flag/index.html | 166 +++++--- tutorial/reverse/index.html | 109 ++++-- tutorial/setup/index.html | 120 ++++-- tutorial/slot/index.html | 132 ++++--- tutorial/ssr-before-3.8/index.html | 87 +++-- tutorial/ssr/index.html | 101 +++-- tutorial/start/index.html | 113 ++++-- tutorial/style/index.html | 96 +++-- tutorial/template/index.html | 150 +++++--- tutorial/transition/index.html | 110 ++++-- 152 files changed, 15994 insertions(+), 3792 deletions(-) create mode 100644 archives/2023/12/index.html create mode 100644 archives/2023/12/page/2/index.html create mode 100644 archives/2023/index.html create mode 100644 archives/2023/page/2/index.html create mode 100644 archives/page/10/index.html create mode 100644 archives/page/9/index.html create mode 100644 categories/component/index.html create mode 100644 categories/component/page/2/index.html create mode 100644 component/async/index.html create mode 100644 component/data/index.html create mode 100644 component/define/index.html create mode 100644 component/error/index.html create mode 100644 component/hydrate/index.html create mode 100644 component/lifecycle/index.html create mode 100644 component/template-component/index.html create mode 100644 component/tree/index.html create mode 100644 component/view/index.html create mode 100644 en/component/async/index.html create mode 100644 en/component/data/index.html create mode 100644 en/component/define/index.html create mode 100644 en/component/error/index.html create mode 100644 en/component/hydrate/index.html create mode 100644 en/component/lifecycle/index.html create mode 100644 en/component/template-component/index.html create mode 100644 en/component/tree/index.html create mode 100644 en/component/view/index.html create mode 100644 page/10/index.html create mode 100644 page/9/index.html delete mode 100644 service-worker.js diff --git a/archives/2020/06/index.html b/archives/2020/06/index.html index 673e70258..362251815 100644 --- a/archives/2020/06/index.html +++ b/archives/2020/06/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/06/page/2/index.html b/archives/2020/06/page/2/index.html index 61e0b35e9..fc6dd85ee 100644 --- a/archives/2020/06/page/2/index.html +++ b/archives/2020/06/page/2/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/06/page/3/index.html b/archives/2020/06/page/3/index.html index 8fc83a2fc..98c182dd1 100644 --- a/archives/2020/06/page/3/index.html +++ b/archives/2020/06/page/3/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/06/page/4/index.html b/archives/2020/06/page/4/index.html index c286b512b..00643eee7 100644 --- a/archives/2020/06/page/4/index.html +++ b/archives/2020/06/page/4/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/06/page/5/index.html b/archives/2020/06/page/5/index.html index dbfd11f0d..ea5441ae3 100644 --- a/archives/2020/06/page/5/index.html +++ b/archives/2020/06/page/5/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/06/page/6/index.html b/archives/2020/06/page/6/index.html index a208df733..12a723636 100644 --- a/archives/2020/06/page/6/index.html +++ b/archives/2020/06/page/6/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/6 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/07/index.html b/archives/2020/07/index.html index cce9de617..e40b10352 100644 --- a/archives/2020/07/index.html +++ b/archives/2020/07/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/7 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/10/index.html b/archives/2020/10/index.html index 619abed02..f9f5cac14 100644 --- a/archives/2020/10/index.html +++ b/archives/2020/10/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020/10 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/index.html b/archives/2020/index.html index 00b93731e..7a8b5e272 100644 --- a/archives/2020/index.html +++ b/archives/2020/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/page/2/index.html b/archives/2020/page/2/index.html index b5fc1165d..4178cb06f 100644 --- a/archives/2020/page/2/index.html +++ b/archives/2020/page/2/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/page/3/index.html b/archives/2020/page/3/index.html index 412413d42..08482b1e5 100644 --- a/archives/2020/page/3/index.html +++ b/archives/2020/page/3/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/page/4/index.html b/archives/2020/page/4/index.html index 65d95794c..c0815993f 100644 --- a/archives/2020/page/4/index.html +++ b/archives/2020/page/4/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/page/5/index.html b/archives/2020/page/5/index.html index 74a0760c1..d952d3341 100644 --- a/archives/2020/page/5/index.html +++ b/archives/2020/page/5/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2020/page/6/index.html b/archives/2020/page/6/index.html index 72ac64391..2105eb25b 100644 --- a/archives/2020/page/6/index.html +++ b/archives/2020/page/6/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2020 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2021/10/index.html b/archives/2021/10/index.html index 9bc74fc85..799cb5d7d 100644 --- a/archives/2021/10/index.html +++ b/archives/2021/10/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2021/10 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2021/10/page/2/index.html b/archives/2021/10/page/2/index.html index 162020206..662f3d97f 100644 --- a/archives/2021/10/page/2/index.html +++ b/archives/2021/10/page/2/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2021/10 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2021/index.html b/archives/2021/index.html index 005555720..a7b753ddd 100644 --- a/archives/2021/index.html +++ b/archives/2021/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2021 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2021/page/2/index.html b/archives/2021/page/2/index.html index f660f2de5..e006071f2 100644 --- a/archives/2021/page/2/index.html +++ b/archives/2021/page/2/index.html @@ -1,12 +1,12 @@ - + - + Archives: 2021 | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/2023/12/index.html b/archives/2023/12/index.html new file mode 100644 index 000000000..7afb1eb3e --- /dev/null +++ b/archives/2023/12/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives: 2023/12 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/archives/2023/12/page/2/index.html b/archives/2023/12/page/2/index.html new file mode 100644 index 000000000..b23932d8d --- /dev/null +++ b/archives/2023/12/page/2/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives: 2023/12 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/archives/2023/index.html b/archives/2023/index.html new file mode 100644 index 000000000..f42492a9c --- /dev/null +++ b/archives/2023/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives: 2023 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/archives/2023/page/2/index.html b/archives/2023/page/2/index.html new file mode 100644 index 000000000..c2c29f9ef --- /dev/null +++ b/archives/2023/page/2/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives: 2023 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/archives/index.html b/archives/index.html index 337a966ea..5f2a1d312 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/10/index.html b/archives/page/10/index.html new file mode 100644 index 000000000..ef7035d2f --- /dev/null +++ b/archives/page/10/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/archives/page/2/index.html b/archives/page/2/index.html index b57e30bab..ebd45f8e7 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/3/index.html b/archives/page/3/index.html index 985250482..db70a2378 100644 --- a/archives/page/3/index.html +++ b/archives/page/3/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/4/index.html b/archives/page/4/index.html index 18e08ee60..67c703274 100644 --- a/archives/page/4/index.html +++ b/archives/page/4/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/5/index.html b/archives/page/5/index.html index 5c7c6753a..e3184e4e3 100644 --- a/archives/page/5/index.html +++ b/archives/page/5/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/6/index.html b/archives/page/6/index.html index acb9be6ee..d2ed25e64 100644 --- a/archives/page/6/index.html +++ b/archives/page/6/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/7/index.html b/archives/page/7/index.html index 359a4675d..2fd4b3d95 100644 --- a/archives/page/7/index.html +++ b/archives/page/7/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/8/index.html b/archives/page/8/index.html index 97635adb0..0900f0dcd 100644 --- a/archives/page/8/index.html +++ b/archives/page/8/index.html @@ -1,12 +1,12 @@ - + - + Archives | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/archives/page/9/index.html b/archives/page/9/index.html new file mode 100644 index 000000000..46dbc68e3 --- /dev/null +++ b/archives/page/9/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Archives | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/categories/component/index.html b/categories/component/index.html new file mode 100644 index 000000000..903d3c8a7 --- /dev/null +++ b/categories/component/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Catégorie: component | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/categories/component/page/2/index.html b/categories/component/page/2/index.html new file mode 100644 index 000000000..da722dd8b --- /dev/null +++ b/categories/component/page/2/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + Catégorie: component | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

San

+ +

一个快速、轻量、灵活的 JavaScript 组件框架

+ 快速开始 + +
+ + + + + +
+ + + +
+ + +
+
+ +
+
+ +
HTML模版
+

声明式的模板,在编写视图时就像是在写一个普通的页面,更符合 HTML 开发人员的习惯。

+
+
+ +
数据驱动
+

修改数据,视图引擎会根据绑定关系自动刷新视图,从此摆脱手工调用 DOM API 的繁琐与可能的遗漏。

+
+
+ +
组件化
+

组件是数据、逻辑与视图的聚合体。通过组件,我们封装独立的功能区块,小到输入组合,大到一个页面。

+
+
+ +
+
+ +
高性能视图
+

通过修改数据的方法,视图引擎能够直接刷新需要变更的视图区域,无需进行任何检测,性能更高。

+
+
+ +
组件反解
+

为首屏时间优化,服务端通常直接输出HTML。我们能从现有的元素中反向解析出组件,并构建绑定关系。

+
+
+ +
体积小巧
+

小于17k (gzipped) 的体积,无需担心对页面下载带来负担。体积强迫症患者的福音。

+
+
+ +
+
+ +
良好的兼容性
+

通过方法修改数据的另一好处是,可以获得更好的浏览器兼容性。毕竟有时我们产品的受众用户有点死板。

+
+
+ +
模块管理自由
+

项目中可以任意选择 ESNext Module 或 AMD 管理模块。当然,如果你想要用全局变量也是支持的。

+
+
+ +
引用方便
+

支持多种引用方式:NPM、GitHub、下载、HTTP 与 HTTPS CDN,让开发和线上引用更便利。

+
+
+
+
+ + +
+
+
+

资料

+

这里有一些教程、文档或示例,可以帮助你学习和了解 San

+
+ + +
+ + + + +
+
+
+

周边

+

一些工具和库能够帮助你更快、更便捷地搭建自己的应用

+
+ + + + + +
+ + + + + + + + + + + + + + + + diff --git a/categories/doc/index.html b/categories/doc/index.html index 9f4e0cf84..dab1f827a 100644 --- a/categories/doc/index.html +++ b/categories/doc/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: doc | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/practice/index.html b/categories/practice/index.html index 2bedfc891..414f78dea 100644 --- a/categories/practice/index.html +++ b/categories/practice/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: practice | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/practice/page/2/index.html b/categories/practice/page/2/index.html index 3da38a3ff..4a768971b 100644 --- a/categories/practice/page/2/index.html +++ b/categories/practice/page/2/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: practice | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/practice/page/3/index.html b/categories/practice/page/3/index.html index b5f7b692f..d9e4ae3b9 100644 --- a/categories/practice/page/3/index.html +++ b/categories/practice/page/3/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: practice | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/practice/page/4/index.html b/categories/practice/page/4/index.html index 1550a7794..770e14e4c 100644 --- a/categories/practice/page/4/index.html +++ b/categories/practice/page/4/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: practice | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/tutorial/index.html b/categories/tutorial/index.html index e9b64fb91..d145fe5e2 100644 --- a/categories/tutorial/index.html +++ b/categories/tutorial/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: tutorial | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/tutorial/page/2/index.html b/categories/tutorial/page/2/index.html index d519dbbf5..94f6d105a 100644 --- a/categories/tutorial/page/2/index.html +++ b/categories/tutorial/page/2/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: tutorial | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/tutorial/page/3/index.html b/categories/tutorial/page/3/index.html index 7ef377d12..a507e5b4a 100644 --- a/categories/tutorial/page/3/index.html +++ b/categories/tutorial/page/3/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: tutorial | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/categories/tutorial/page/4/index.html b/categories/tutorial/page/4/index.html index ffc34925a..29b5a7c90 100644 --- a/categories/tutorial/page/4/index.html +++ b/categories/tutorial/page/4/index.html @@ -1,12 +1,12 @@ - + - + Catégorie: tutorial | San @@ -17,10 +17,9 @@ - + + - - @@ -29,12 +28,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + + @@ -303,7 +314,7 @@
Sanny
diff --git a/component/async/index.html b/component/async/index.html new file mode 100644 index 000000000..fc7a373cb --- /dev/null +++ b/component/async/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + + 异步组件 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 异步组件 +

+ + + 编辑本文 +
+ +
+ +

版本:>= 3.7.0

+

createComponentLoader 方法返回一个组件加载器。components 中的声明为组件加载器时,将进行异步渲染:在 attach 过程中将不渲染该组件,组件将在加载完成后进行渲染。异步渲染有如下特性:

+
    +
  • 对同一个createComponentLoader 方法返回的组件加载器,只会进行一次加载。换句话说,load 方法只会调用一次
  • +
  • 组件的渲染一定是异步的。即使组件加载器当前已经完成加载,也会在主体渲染完成后的下一个 macro task,进行异步组件渲染
  • +
+

createComponentLoader 方法可以接受一个返回 Promise 的函数,加载完成后,使用组件类 resolve。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var InputComponent = san.defineComponent({
template: '<input type="text" value="{{value}}"/>'
});

// 模拟加载,1秒后加载完成
var inputLoader = san.createComponentLoader(function () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(InputComponent);
}, 1000);
});
});

var MyApp = san.defineComponent({
components: {
'x-input': inputLoader
},

template: '<div><x-input value="{{name}}"/></div>'
});

var myApp = new MyApp({
data: {
name: 'San'
}
});
myApp.attach(document.body);
+ +

通常情况,需要异步加载的组件都会有一定的复杂度。如果期望在加载过程中显示简单的替代视图,可以传入一个 Object 给 createComponentLoader 方法,通过 load 属性传入加载方法,并指定一个 placeholder 组件。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var InputComponent = san.defineComponent({
template: '<input type="text" value="{{value}}"/>'
});

var LabelComponent = san.defineComponent({
template: '<u>{{value}}</u>'
});

// 模拟加载,1秒后加载完成
var inputLoader = san.createComponentLoader({
load: function () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(InputComponent);
}, 1000);
});
},

placeholder: LabelComponent
});

var MyApp = san.defineComponent({
components: {
'x-input': inputLoader
},

template: '<div><x-input value="{{name}}"/></div>'
});

var myApp = new MyApp({
data: {
name: 'San'
}
});
myApp.attach(document.body);
+ +

你可以指定一个 fallback 组件,用于加载失败时使用的视图组件。但是,标识失败需要你 reject 返回的 Promise。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var LabelComponent = san.defineComponent({
template: '<u>{{value}}</u>'
});

// 模拟加载,1秒后加载完成
var inputLoader = san.createComponentLoader({
load: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject();
}, 1000);
});
},

fallback: LabelComponent
});

var MyApp = san.defineComponent({
components: {
'x-input': inputLoader
},

template: '<div><x-input value="{{name}}"/></div>'
});

var myApp = new MyApp({
data: {
name: 'San'
}
});
myApp.attach(document.body);
+ +

加载失败时使用的视图组件,除了通过 fallback 指定,也可以通过 reject 指定。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var LabelComponent = san.defineComponent({
template: '<u>{{value}}</u>'
});

// 模拟加载,1秒后加载完成
var inputLoader = san.createComponentLoader(function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject(LabelComponent);
}, 1000);
});
});

var MyApp = san.defineComponent({
components: {
'x-input': inputLoader
},

template: '<div><x-input value="{{name}}"/></div>'
});

var myApp = new MyApp({
data: {
name: 'San'
}
});
myApp.attach(document.body);
+ +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/data/index.html b/component/data/index.html new file mode 100644 index 000000000..6a81d3b2e --- /dev/null +++ b/component/data/index.html @@ -0,0 +1,312 @@ + + + + + + + + + + + 组件数据 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件数据 +

+ + + 编辑本文 +
+ +
+ +

所有组件数据相关的操作,都由组件实例的 data 成员提供。

+

获取数据

通过 data.get 方法可以获取数据。

+
1
2
3
4
5
6
san.defineComponent({
attached: function () {
var params = this.data.get('params');
this.data.set('list', getList(params[1]));
}
});
+ +

data.get 方法接受一个表示 property accessor 的字符串,所以上面的例子也可以写成这样:

+
1
2
3
4
5
6
san.defineComponent({
attached: function () {
var param = this.data.get('params[1]');
this.data.set('list', getList(param));
}
});
+ +

操作数据

data 上提供了一些数据操作的方法,具体请参考数据操作文档。

+

初始数据

组件在实例化时可以通过 option 传入 data,指定组件初始化时的数据。

+
1
2
3
4
5
6
7
8
9
10
var MyApp = san.defineComponent({
template: '<ul><li s-for="item in list">{{item}}</li></ul>'
});

var myApp = new MyApp({
data: {
list: ['san', 'er', 'esui', 'etpl', 'esl']
}
});
myApp.attach(document.body);
+ +

new 时传入初始数据是针对实例的特例需求。当我们希望在定义组件时,就设置每个实例的初始数据,可以通过 initData 方法指定组件初始化时的数据。initData 方法返回组件实例的初始化数据。

+
1
2
3
4
5
6
7
8
9
10
11
12
var MyApp = san.defineComponent({
template: '<ul><li s-for="item in list">{{item}}</li></ul>',

initData: function () {
return {
list: ['san', 'er', 'esui', 'etpl', 'esl']
};
}
});

var myApp = new MyApp();
myApp.attach(document.body);
+ +

计算数据

有时候,一个数据项的值可能由其他数据项计算得来,这时我们可以通过 computed 定义计算数据。 computed 是一个对象,key 为计算数据项的名称,value 是返回数据项值的函数。

+
1
2
3
4
5
6
7
8
9
10
san.defineComponent({
template: '<a>{{name}}</a>',

// name 数据项由 firstName 和 lastName 计算得来
computed: {
name: function () {
return this.data.get('firstName') + ' ' + this.data.get('lastName');
}
}
});
+ +

上面的例子中,name 数据项是计算数据,依赖 firstName 和 lastName 数据项,其值由 firstName 和 lastName 计算得来。

+

注意:计算数据的函数中只能使用 this.data.get 方法获取数据项的值,不能通过 this.method 调用组件方法,也不能通过 this.data.set 设置组件数据。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
san.defineComponent({
template: '<a>{{info}}</a>',

// name 数据项由 firstName 和 lastName 计算得来
computed: {
name: function () {
return this.data.get('firstName') + ' ' + this.data.get('lastName');
},

info: function () {
return this.data.get('name') + ' - ' + this.data.get('email');
}
}
});
+ +

计算数据项可以依赖另外一个计算数据项,上面的例子中,info 项依赖的 name 项就是一个计算数据项。但是使用时一定要注意,不要形成计算数据项之间的循环依赖。

+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/define/index.html b/component/define/index.html new file mode 100644 index 000000000..817bdcfb1 --- /dev/null +++ b/component/define/index.html @@ -0,0 +1,301 @@ + + + + + + + + + + + 组件 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件 +

+ + + 编辑本文 +
+ +
+ +

定义组件最基本的方法是,从 san.Component 继承。San 提供了 san.inherits 方法,用于继承。

+
1
2
3
4
5
6
7
8
9
10
function MyApp(options) {
san.Component.call(this, options);
}
san.inherits(MyApp, san.Component);

MyApp.prototype.template = '<ul><li s-for="item in list">{{item}}</li></ul>';

MyApp.prototype.attached = function () {
this.data.set('list', ['san', 'er', 'esui', 'etpl', 'esl']);
};
+ +

然后,通过 new 的方式就可以使用这个组件了。当然,通常你可能希望让组件出现在页面上,所以需要调用 attach 方法,将组件添加到页面的相应位置。

+
1
2
var myApp = new MyApp();
myApp.attach(document.body);
+ +

通过继承的方式定义组件的好处是,当你使用 ESNext 时,你可以很自然的 extends。

+

注意:由于 ESNext 没有能够编写 prototype 属性的语法,所以 San 对组件定义时的属性支持 static property。通过 ESNext 的 extends 继承时,template / filters / components 属性请使用 static property 的方式定义。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {Component} from 'san';

class HelloComponent extends Component {

constructor(options) {
super(options);
// .....
}

static template = '<p>Hello {{name}}!</p>';

initData() {
return {name: 'San'}
}
}

new HelloComponent().attach(document.body);
+ +

对于不使用 ESNext 时,写一个 function 然后调用 san.inherits 再写各种 prototype 实在是有点麻烦,San 提供了快捷方法 san.defineComponent 用于方便地定义组件。

+
1
2
3
4
5
6
7
var MyApp = san.defineComponent({
template: '<ul><li s-for="item in list">{{item}}</li></ul>',

attached: function () {
this.data.set('list', ['san', 'er', 'esui', 'etpl', 'esl']);
}
});
+ +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/error/index.html b/component/error/index.html new file mode 100644 index 000000000..d165515a0 --- /dev/null +++ b/component/error/index.html @@ -0,0 +1,307 @@ + + + + + + + + + + + 组件异常 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件异常 +

+ + + 编辑本文 +
+ +
+ +

版本:>= 3.10.7

+

当组件本身,或者是它的一个子孙节点发生异常时,会调用该组件的 error 钩子函数,此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含异常来源信息的字符串,比如:

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var Child = san.defineComponent({
template: '<h1>test</h1>',
attached: function () {
throw new Error('error');
}
});
var myApp = san.defineComponent({
template: '<div><x-child /></div>',
components: {
'x-child': Child
},
error: function (err, instance, info) {
// some code
}
});
myApp.attach(myApp);
+ +

其中,异常来源信息包括:

+
    +
  • hook:{{ hookName }}:生命周期钩子里的异常
  • +
  • initData:数据初始化执行异常
  • +
  • computed:{{ computedName }}:计算数据执行异常
  • +
  • watch:{{ watchName }}:数据监听的回调函数执行异常
  • +
  • message:{{ messageName }}:消息处理函数执行异常
  • +
  • filter:{{ filterName }}:过滤器执行异常
  • +
  • event:{{ eventName }}:事件处理函数执行异常
  • +
  • transitionCreate动画控制器 Creator 执行异常
  • +
  • transitionEnter:进入动画控制器执行异常
  • +
  • transitionLeave:离开动画控制器执行异常
  • +
+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/hydrate/index.html b/component/hydrate/index.html new file mode 100644 index 000000000..32447dcad --- /dev/null +++ b/component/hydrate/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + + 组件反解 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件反解 +

+ + + 编辑本文 +
+ +
+ +

版本:>= 3.4.0

+

提示:通过 San 进行服务端渲染,一定能通过相同版本的 San 在浏览器端进行反解。

+

概述

组件初始化时传入 el,其将作为组件根元素,并以此反解析出视图结构。

+

该特性的意图是:有时我们为了首屏时间,期望初始的视图是直接的 HTML,不由组件渲染。但是我们希望组件为我们管理数据、逻辑与视图,后续的用户交互行为与视图变换通过组件管理。

+
1
2
3
var myComponent = new MyComponent({
el: document.getElementById('wrap').firstChild
});
+ +

el 初始化组件时,San 会尊重 el 的现时 HTML 形态,不会执行任何额外影响视觉的渲染动作。

+
    +
  • 不会使用预设的 template 渲染视图
  • +
  • 不会创建根元素
  • +
  • 直接到达 compiled、created、attached 生命周期
  • +
+

数据

组件的视图是数据的呈现。我们需要通过在组件起始时标记 data,以指定正确的初始数据。初始数据标记是一个 s-data: 开头的 HTML Comment,在其中声明数据。

+

警告:San 的组件反解过程基于数据和组件模板进行视图结构反推与匹配。反解的组件必须拥有正确的标记数据,否则反解过程会发生错误。比如对于模板中的 s-if 条件进行视图反推,如果没有正确的标记数据,反推就会因为元素对应不上,得到不期望的结果。

+
1
2
3
4
5
<a id="wrap"><!--s-data:{
email: 'errorrik@gmail.com',
name: 'errorrik'}-->
<span title="errorrik@gmail.com">errorrik</span>
</a>
+ +
1
2
3
4
5
6
7
8
9
10
var MyComponent = san.defineComponent({
template: ''
+ '<a>\n'
+ ' <span title="{{email}}">{{name}}</span>\n'
+ '</a>'
});

var myComponent = new MyComponent({
el: document.getElementById('wrap')
});
+ + + +

如果一个组件拥有 owner,不用标记初始数据。其初始数据由 owner 根据绑定关系灌入。

+
1
2
3
4
<!-- ui-label 组件拥有 owner,无需进行初始数据标记 -->
<div id="main"><!--s-data:{"name":"errorrik"}-->
<span>errorrik</span>
</div>
+ +
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Label = san.defineComponent({
template: '<span>{{text}}</span>'
});

var MyComponent = san.defineComponent({
components: {
'ui-label': Label
},

template: ''
+ '<div>\n'
+ ' <ui-label text="{{name}}"></ui-label>\n'
+ '</div>'
});

var myComponent = new MyComponent({
el: document.getElementById('main')
});
+ + +

复合插值文本

San 支持在插值文本中直接输出 HTML,此时插值文本对应的不是一个 TextNode,而可能是多个不同类型的元素。对于这种复合插值文本,需要在内容的前后各添加一个注释做标记。

+
    +
  • 文本前的注释内容为 s-text,代表插值文本片段开始。
  • +
  • 文本后的注释内容为 /s-text,代表插值文本片段结束。
  • +
+
1
2
3
4
<a id="wrap"><!--s-data:{
name: 'new <b>San</b>'}-->
<span>Hello <!--s-text-->new <b>San</b><!--/s-text-->!</span>
</a>
+ +
1
2
3
4
5
6
7
8
9
10
var MyComponent = san.defineComponent({
template: ''
+ '<a>\n'
+ ' <span>Hello {{name|raw}}!</span>\n'
+ '</a>'
});

var myComponent = new MyComponent({
el: document.getElementById('wrap')
});
+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/lifecycle/index.html b/component/lifecycle/index.html new file mode 100644 index 000000000..21dc7e719 --- /dev/null +++ b/component/lifecycle/index.html @@ -0,0 +1,314 @@ + + + + + + + + + + + 组件生命周期 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件生命周期 +

+ + + 编辑本文 +
+ +
+ +

San 的组件是 HTML 元素扩展的风格,所以其生命周期的命名风格与 WebComponents 相符合。

+
    +
  • compiled - 组件视图模板编译完成
  • +
  • inited - 组件实例初始化完成
  • +
  • created - 组件元素创建完成
  • +
  • attached - 组件已被附加到页面中
  • +
  • detached - 组件从页面中移除
  • +
  • disposed - 组件卸载完成
  • +
+

组件的生命周期有这样的一些特点:

+
    +
  • 生命周期代表组件的状态,生命周期本质就是状态管理。
  • +
  • 在生命周期的不同阶段,组件对应的钩子函数会被触发运行。
  • +
  • 并存。比如 attached 和 created 等状态是同时并存的。
  • +
  • 互斥。attached 和 detached 是互斥的,disposed 会互斥掉其它所有的状态。
  • +
  • 有的时间点并不代表组件状态,只代表某个行为。当行为完成时,钩子函数也会触发。如 updated 代表每次数据变化导致的视图变更完成。
  • +
+

通过生命周期的钩子函数,我们可以在生命周期到达时做一些事情。比如在生命周期 attached 中发起获取数据的请求,在请求返回后更新数据,使视图刷新。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var ListComponent = san.defineComponent({
template: '<ul><li s-for="item in list">{{item}}</li></ul>',

initData: function () {
return {
list: []
};
},

attached: function () {
requestList().then(this.updateList.bind(this));
},

updateList: function (list) {
this.data.set('list', list);
}
});
+ + +

下图详细描述了组件的生存过程:

+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/template-component/index.html b/component/template-component/index.html new file mode 100644 index 000000000..c4c03275f --- /dev/null +++ b/component/template-component/index.html @@ -0,0 +1,314 @@ + + + + + + + + + + + 模版组件 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 模版组件 +

+ + + 编辑本文 +
+ +
+ +

版本:>= 3.12.0

+

模板组件,也叫 纯视图组件。有时候我们的组件只具有视图部分,只是为了封装相应的视图结构或样式表达,这时候使用 模板组件 可以让运行时更快更轻量。

+

和普通组件相比, 模板组件 不支持如下功能:

+
    +
  • 子组件
  • +
  • filter
  • +
  • computed
  • +
  • messages
  • +
  • 组件事件机制
  • +
  • attached、inited 等生命周期钩子
  • +
  • watch、slot、ref 等方法
  • +
+

模板组件 仅支持:

+
    +
  • template 指定组件模板
  • +
  • 在模板中通过 slot 设置插槽
  • +
  • trimWhitespace、delimiters 等与组件模板相关的设置项
  • +
  • initData 方法指定初始数据
  • +
+

通过 defineTemplateComponent 方法,可以创建模板组件。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var PanelWithHeader = san.defineTemplateComponent({
template: '<dl><dt><slot name="header"/></dt><dd><slot/></dd></dl>'
});

var MyApp = san.defineComponent({
components: {
'x-panel': PanelWithHeader
},

template: '<div><x-panel>'
+ '<b slot="header">{{name}}</b>'
+ '<a>{{desc}}</a>'
+ '</x-panel></div>'
});

var myApp = new MyApp({
data: {
name: 'San',
desc: 'JS Component Framework'
}
});
myApp.attach(document.body);
+ +

通过 native 修饰符,可以给 模板组件 的根元素(如包含)挂载事件。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var PanelWithHeader = san.defineTemplateComponent(
'<dl><dt><slot name="header"/></dt><dd><slot/></dd></dl>'
);

var MyApp = san.defineComponent({
components: {
'x-panel': PanelWithHeader
},

template: '<div><x-panel on-click="native:clicker">'
+ '<b slot="header">{{name}}</b>'
+ '<a>{{desc}}</a>'
+ '</x-panel></div>',

clicker: function () {
console.log('Panel clicked');
}
});

var myApp = new MyApp({
data: {
name: 'San',
desc: 'JS Component Framework'
}
});
myApp.attach(document.body);
+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/tree/index.html b/component/tree/index.html new file mode 100644 index 000000000..179c4b4c1 --- /dev/null +++ b/component/tree/index.html @@ -0,0 +1,361 @@ + + + + + + + + + + + 组件树结构 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件树结构 +

+ + + 编辑本文 +
+ +
+ +

我们知道组件体系下,组件必须是可嵌套的树形关系。下面从一段代码,做一些说明。在下面的代码中,AddForm 内部使用了两个自定义组件:ui-calendar 和 ui-timepicker。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- Template -->
<div class="form">
<input type="text" class="form-title" placeholder="标题" value="{= title =}">
<textarea class="form-desc" placeholder="备注" value="{= desc =}"></textarea>

<div>预期完成时间:
<ui-calendar value="{= endTimeDate =}" s-ref="endDate"></ui-calendar>
<ui-timepicker value="{= endTimeHour =}" s-ref="endHour"></ui-timepicker>
</div>

<div class="form-op">
<button type="button" on-click="submit">ok</button>
</div>
</div>
+ +
1
2
3
4
5
6
7
8
9
10
11
12
13
var AddForm = san.defineComponent({
// template

components: {
'ui-timepicker': require('../ui/TimePicker'),
'ui-calendar': require('../ui/Calendar')
},

submit: function () {
this.ref('endDate')
this.ref('endHour')
}
});
+ + +

components

组件中通常通过声明自定义元素,使用其它组件。

+

组件视图可以使用哪些子组件类型,必须通过定义组件的 components 成员指定。key 是自定义元素的标签名,value 是组件的类。

+

注意:考虑到组件的独立性,San 没有提供全局组件注册的方法,组件必须在自身的 components 中声明自己内部会用到哪些组件。

+

有些组件可能在内容中会使用自己,比如树的节点。我们可以将 components 中这一项的值设置为字符串 self

+
1
2
3
4
5
6
7
var Node = san.defineComponent({
// template

components: {
'ui-node': 'self'
}
});
+ +

owner 与 parent

ownerparent 的概念已经被 react 明确过了,但这里还是要专门明确下。

+

owner 指的是目标在声明时位于哪个组件的组件视图中,其生存时间、交互的通信等行为都由 owner 管理。owner 必须是一个组件。ui-calendar 的 owner 是 AddForm 组件。

+

parent 指的是目标在视图中对应的直接父级元素。ui-calendar 的 parent 是其上层的 div。parent 对组件管理并没有直接的意义。

+

ref

声明子组件时,如果通过 s-ref 指定了名称,则可以在owner组件实例的 ref 方法调用到。

+

提示:有了声明式的初始化、数据绑定与事件绑定,我们很少需要在 owner 中拿到子组件的实例。虽然 San 提供了这个途径,但当你用到它的时候,请先思考是不是非要这么干。

+

消息

通过 dispatch 方法,组件可以向组件树的上层派发消息。

+
1
2
3
4
5
6
7
8
9
10
var SelectItem = san.defineComponent({
template: '<li on-click="select"><slot></slot></li>',

select: function () {
var value = this.data.get('value');

// 向组件树的上层派发消息
this.dispatch('UI:select-item-selected', value);
}
});
+ +

消息将沿着组件树向上传递,直到遇到第一个处理该消息的组件,则停止。通过 messages 可以声明组件要处理的消息。messages 是一个对象,key 是消息名称,value 是消息处理的函数,接收一个包含 target(派发消息的组件) 和 value(消息的值) 的参数对象。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
var Select = san.defineComponent({
template: '<ul><slot></slot></ul>',

// 声明组件要处理的消息
messages: {
'UI:select-item-selected': function (arg) {
var value = arg.value;
this.data.set('value', value);

// arg.target 可以拿到派发消息的组件
}
}
});
+ +

消息主要用于组件与非 owner 的上层组件进行通信。比如,slot 内组件 SelectItem 的 owner 是更上层的组件,但它需要和 Select 进行通信。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
san.defineComponent({
components: {
'ui-select': Select,
'ui-selectitem': SelectItem
},

template: ''
+ '<div>'
+ ' <ui-select value="{=value=}">'
+ ' <ui-selectitem value="1">one</ui-selectitem>'
+ ' <ui-selectitem value="2">two</ui-selectitem>'
+ ' <ui-selectitem value="3">three</ui-selectitem>'
+ ' </ui-select>'
+ '</div>'
});
+ + +

动态子组件

在 3.10.0 以上的版本,支持 s-is 指令,在渲染过程动态选择组件类型。s-is 特性有以下要点:

+
    +
  • s-is 可以声明一个表达式,其运算结果 应该 是一个 string
  • +
  • 动态选择的组件类型是在 components 中声明的子组件,s-is 表达式运算结果对应 components 声明中的 key
  • +
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var BLabel = san.defineComponent({
template: '<b>{{text}}</b>'
});

var ULabel = san.defineComponent({
template: '<u>{{text}}</u>'
});

var App = san.defineComponent({
components: {
'BLabel': BLabel,
'ULabel': ULabel
},

template: '<div><x-label s-is="type" text="{{name}}"/></div>'
});

(new App({
data: {
name: 'San',
type: 'BLabel'
}
})).attach(document.body);
+ +

手动创建子组件

在一些场景下,我们不希望组件通过声明式,在自身视图渲染时创建子组件;而希望通过 JavaScript 灵活控制在未来的某些时间点创建子组件。比如:

+
    +
  • 浮动层子组件的 parent 不在其根元素 el 内,声明式用着不方便
  • +
  • 列表只有在用户点击时才需要创建并展示
  • +
+

手动创建子组件对开发者要求更高,我们在这里给出一些需要注意的地方,下面节选的代码也做了一些简单的说明:

+
    +
  • 手动创建的子组件无需在 components 中声明类型
  • +
  • 确保不要重复创建。常见的做法是在实例的属性上持有对创建组件的引用,并以此作判断
  • +
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
san.defineComponent({
mainClick: function () {
if (!this.layer) {
this.layer = new Layer();
this.layer.attach(document.body);
}

this.layer.show();
},

disposed: function () {
if (this.layer) {
this.layer.dispose();
}

this.layer = null;
}
});
+ +

在 3.7.0 以上的版本,手动创建的子组件支持 owner 和 source 参数。

+

指定 owner 可以自动维护 owner 与手动创建的子组件之间的关系:

+
    +
  • owner 可以收到手动创建的子组件 dispatch 的消息
  • +
  • owner dispose 时,手动创建的子组件将自动 dispose
  • +
+

注意

+

指定 owner 后,不允许将组件 push 到 owner 的 children 中,否则组件 dispose 过程中,会对手动创建的子组件进行多次 dispose 操作。

+

source 可以声明手动创建的子组件与 owner 之间的绑定关系:

+
    +
  • 数据绑定,含双向绑定
  • +
  • 事件
  • +
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 手动创建的子组件的数据与事件绑定,指定owner和source
// 3.7.0+
var Person = san.defineComponent({
template: '<div>'
+ ' <input type="text" value="{=name=}">'
+ ' <input type="text" value="{=email=}">'
+ ' <button on-click="done">Done</button>'
+ '</div>',

done: function () {
this.fire('done', {
name: this.data.get('name'),
email: this.data.get('email')
});
}
});

var MyApp = san.defineComponent({
template: '<div>'
+ ' name: {{author.name}}; email{{author.email}}'
+ ' <button on-click="edit">edit</button>'
+ '</div>',

edit: function () {
if (!this.editor) {
this.editor = new Person({
owner: this,
source: '<x-person name="{{author.name}}" email="{{author.email}}" on-done="editDone($event)"/>'
});
this.editor.attach(document.body)
}
},

editDone: function (e) {
this.data.set('author', e);
}
});

var myApp = new MyApp({
data: {
author: {
name: 'erik',
email: 'errorrik@gmail.com'
}
}
});
myApp.attach(document.body);
+ + +
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 手动创建的子组件双向绑定,指定owner和source
// 3.7.0+
var Person = san.defineComponent({
template: '<div>'
+ ' <input type="text" value="{=name=}">'
+ ' <input type="text" value="{=email=}">'
+ '</div>'
});

var MyApp = san.defineComponent({
template: '<div>'
+ ' name: {{author.name}}; email{{author.email}}'
+ ' <button on-click="edit">edit</button>'
+ '</div>',

edit: function () {
if (!this.editor) {
this.editor = new Person({
owner: this,
source: '<x-person name="{=author.name=}" email="{=author.email=}"/>'
});
this.editor.attach(document.body)
}
}
});

var myApp = new MyApp({
data: {
author: {
name: 'erik',
email: 'errorrik@gmail.com'
}
}
});
myApp.attach(document.body);
+ + +
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 手动创建的子组件指定owner,可以dispatch
// 3.7.0+
var Person = san.defineComponent({
template: '<div>'
+ ' <input type="text" value="{=name=}">'
+ ' <input type="text" value="{=email=}">'
+ ' <button on-click="done">Done</button>'
+ '</div>',

done: function () {
this.dispatch('person-done', {
name: this.data.get('name'),
email: this.data.get('email')
});
}
});

var MyApp = san.defineComponent({
template: '<div>'
+ ' name: {{author.name}}; email{{author.email}}'
+ ' <button on-click="edit">edit</button>'
+ '</div>',

edit: function () {
if (!this.editor) {
this.editor = new Person({
owner: this,
source: '<x-person name="{{author.name}}" email="{{author.email}}"/>'
});
this.editor.attach(document.body)
}
},

messages: {
'person-done': function (e) {
this.data.set('author', e.value);
}
}
});

var myApp = new MyApp({
data: {
author: {
name: 'erik',
email: 'errorrik@gmail.com'
}
}
});
myApp.attach(document.body);
+ +

提示:如果你的组件包含指定 source 声明的手动创建的子组件,并且预期会被循环多次创建,可以将 source 模板手动预编译,避免框架对 source 字符串进行多次重复编译,提升性能。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 手工预编译 source
// 3.7.0+
var PersonDetail = san.defineComponent({
template: '<div>'
+ ' {{name}}, {{email}}'
+ ' <button on-click="close">close</button>'
+ '</div>',

close: function () { this.el.style.display = 'none' },
open: function () { this.el.style.display = 'block' }
});

var Person = san.defineComponent({
template: '<div>'
+ ' name: {{info.name}}'
+ ' <button on-click="showDetail">detail</button>'
+ '</div>',

// 手工预编译 source
detailSource: san.parseTemplate('<x-person name="{{info.name}}" email="{{info.email}}"/>')
.children[0],

showDetail: function () {
if (!this.detail) {
this.detail = new PersonDetail({
owner: this,
source: this.detailSource
});
this.detail.attach(document.body)
}

this.detail.open();
}
});

var MyApp = san.defineComponent({
template: '<div><x-p s-for="p in members" info="{{p}}" /></div>',

components: {
'x-p': Person
}
});

var myApp = new MyApp({
data: {
members: [
{ name: 'errorrik', email: 'errorrik@what.com' },
{ name: 'otakustay', email: 'otakustay@what.com' }
]
}
});
+ +

在 3.7.1 以上的版本,手动创建的子组件的 source 参数允许声明子元素,指定插入 slot 部分的内容。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 指定插入 slot 部分的内容
// 3.7.1+
var Dialog = san.defineComponent({
template: '<span><slot name="title"/><slot/></span>'
});

var MyApp = san.defineComponent({
template: '<div><button on-click="alterStrong">alter strong</button></div>',

attached: function () {
if (!this.dialog) {
this.dialog = new Dialog({
owner: this,
source: '<x-dialog>'
+ '<h2 slot="title">{{title}}</h2>'
+ '<b s-if="strongContent">{{content}}</b><u s-else>{{content}}</u>'
+ '</x-dialog>'
});
this.dialog.attach(this.el);
}
},

alterStrong: function () {
this.data.set('strongContent', !this.data.get('strongContent'));
}
});

var myApp = new MyApp({
data: {
title: 'MyDialog',
content: 'Hello San',
strongContent: true
}
});
+ +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/component/view/index.html b/component/view/index.html new file mode 100644 index 000000000..8ba496230 --- /dev/null +++ b/component/view/index.html @@ -0,0 +1,334 @@ + + + + + + + + + + + 组件视图 | San + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + LOGO + + + + + + + +
+ +
+
+ + + +
+ +
+
+ + +
+ + +

+ 组件视图 +

+ + + 编辑本文 +
+ +
+ +

视图模板

定义组件时,通过 template 可以定义组件的视图模板。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
san.defineComponent({
template: '<div>'
+ '<label><input type="checkbox" value="errorrik" checked="{= online =}">errorrik</label>'
+ '<label><input type="checkbox" value="otakustay" checked="{= online =}">otakustay</label>'
+ '<label><input type="checkbox" value="firede" checked="{= online =}">firede</label>'
+ '</div>',

initData: function () {
return {
online: ['errorrik', 'otakustay']
};
}
});
+ +

通常,将 HTML 片段写在 JavaScript 中是不友好的,我们可以把模板写在单独的文件里,通过工具或装载器去管理。

+

在 webpack + ESNext 环境下引用模板:

+
1
待补充
+ +

在 AMD 环境下通过 text plugin 引用模板:

+
1
2
3
4
5
6
7
8
9
san.defineComponent({
template: require('text!./template.html'),

initData: function () {
return {
online: ['errorrik', 'otakustay']
};
}
});
+ +

强调:San 要求组件对应 一个 HTML 元素,所以视图模板定义时,只能包含一个 HTML 元素,其它所有内容需要放在这个元素下。

+
1
2
3
4
5
6
7
8
9
<!-- 正确 -->
<dl>
<dt>name - email</dt>
<dd s-for="p in persons" title="{{p.name}}">{{p.name}}({{dept}}) - {{p.email}}</dd>
</dl>

<!-- 错误 -->
<p>name</p>
<p>email</p>
+ +

组件对应的 HTML 元素可能是由其 owner 组件通过视图模板指定的,视图模板不好直接定死对应 HTML 元素的标签。此时可以将视图模板对应的 HTML 元素指定为 template

+
1
<template class="ui-timepicker">{{ value | valueText }}</template>
+ + +

过滤器

在定义视图模板时,插值是常用的展现数据的方式。在编写插值时,我们常使用 过滤器 将数据转换成适合视图展现的形式。

+
1
{{createTime | dateFormat('yyyy-MM-dd')}}
+ +

内置过滤器

San 针对常用场景,内置了几个过滤器:

+
    +
  • html - HTML 转义。当不指定过滤器时,默认使用此过滤器
  • +
  • url - URL 转义
  • +
  • raw - 不进行转义。当不想使用 HTML 转义时,使用此过滤器
  • +
+

定制过滤器

通过定义组件的 filters 成员,可以指定组件的视图模板可以使用哪些过滤器。

+
1
2
3
4
5
6
7
8
9
san.defineComponent({
template: '<a>{{createTime | dateFormat("yyyy-MM-dd")}}</a>',

filters: {
dateFormat: function (value, format) {
return moment(value).format(format);
}
}
});
+ +

过滤器函数的第一个参数是表达式对应的数据值,过滤器调用时传入的参数从第二个参数开始接在后面。

+

注意:考虑到组件的独立性,San 没有提供全局过滤器注册的方法,组件要使用的过滤器必须在自身的 filters 中定义。

+

插槽

在视图模板中可以通过 slot 声明一个插槽的位置,其位置的内容可以由外层组件定义。具体请参考插槽文档。

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var Panel = san.defineComponent({
template: '<div>'
+ ' <div class="head" on-click="toggle">title</div>'
+ ' <p style="{{fold | yesToBe(\'display:none\')}}"><slot></slot></p>'
+ '</div>',

toggle: function () {
this.data.set('fold', !this.data.get('fold'));
}
});

var MyComponent = san.defineComponent({
components: {
'ui-panel': Panel
},

template: '<div><ui-panel>Hello San</ui-panel></div>'
});

/* MyComponent渲染结果
<div>
<div class="head">title</div>
<p style="display:none">Hello San</p>
</div>
*/
+ + +

el

组件实例的属性 el 表示组件对应的 HTML 元素,组件初始化时可以通过 option 传入。

+

基本上在编写组件时不需要关心它,但是在初始化组件时如果传入 el,意味着让组件以此元素作为组件根元素。元素将:

+
    +
  • 不会使用预设的 template 渲染视图
  • +
  • 不会创建根元素
  • +
  • 直接到达 compiled、created、attached 生命周期
  • +
+

有时我们为了首屏时间,期望初始的视图是直接的 HTML,不希望初始视图是由组件渲染的。但是我们希望组件为我们管理数据、逻辑与视图,后续的用户交互行为与视图变换通过组件管理,此时就可以通过 el 传入一个现有元素。

+

组件将以 el 传入的元素作为组件根元素并反解析出视图结构。这个过程我们称作 组件反解。详细请参考组件反解文档。

+ + +
+
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/css/article.css b/css/article.css index 1dafa094c..530af914b 100644 --- a/css/article.css +++ b/css/article.css @@ -21,9 +21,8 @@ display: inline-block; text-decoration: none; font-weight: 300; - font-size:1.05em; - line-height: 1; - margin: 9px 0; + line-height: 1.5rem; + margin: 7px 0; padding-left: 5px; transition-timing-function: ease; transition-duration: .2s; diff --git a/css/style.css b/css/style.css index 35fc0e040..f58050041 100644 --- a/css/style.css +++ b/css/style.css @@ -205,8 +205,8 @@ footer { .recommend dt { font-size: 1.7rem; - margin-top: 3.5rem; - margin-bottom: 1.25rem; + margin-top: 2.6rem; + margin-bottom: .8rem; font-weight: 500; color: #2da2f8; } @@ -215,7 +215,7 @@ footer { { color: #818688; text-decoration: none; - line-height: 2.2em; + line-height: 2em; font-weight: 300; font-size:1.05em; transition-timing-function: ease; diff --git a/doc/api/index.html b/doc/api/index.html index 02761dcfd..836d43fe6 100644 --- a/doc/api/index.html +++ b/doc/api/index.html @@ -1,26 +1,26 @@ - + - + 组件API | San - + - - - + + + + + - - @@ -29,12 +29,24 @@ - - - - - - + + + + + + + + + + + + + + + + + + - + - - + +
@@ -103,7 +115,6 @@
@@ -349,7 +407,7 @@

ne @@ -373,7 +431,6 @@

ne