有趣的聚合物 1.1

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在过去的两周假期里,我一直在玩 javascript、 polymer node express restify mongo 。今天,我想介绍一下我使用 polymer 这个 google 的 web ui 组件框架的乐趣,将它与其他框架进行对比,并给出我的总体印象。由此,您将对聚合物的用途、使用方法以及需要注意的事项有一个深刻的了解。

什么是聚合物?

polymer 是 google 的开源 web component ui 框架。目标是让开发人员今天以跨浏览器的方式利用最新的 Web 组件 Web 标准。 Web 组件 是标准的保护伞,特别是 影子 dom 自定义元素 html 导入

这些是浏览器构建 Web 组件所需的核心技术。考虑到 Web 社区是“由委员会设计”,在这种情况下它实际上是一个快速移动的标准,因此 polymer 版本 0.5 和版本 1.x 之间发生了很大变化。也就是说,谷歌在保护您免受这些核心变化以及包括在以前的工作之上迭代的新功能方面做得很好。

…创建 ui 框架的重点,嘿。

简而言之,Polymer 允许您比过去更轻松地创建自己的 UI 控件,它基于 Web 标准构建,并且考虑到了性能。那,他们已经遵循了 材料设计指南

代码在实践中是什么样子的?

虽然这在浏览器中是原生的:

结果是:

你现在可以这样做:

你会看到这个:

注意在 bootstrap 中,你必须将 css 类应用于标签:

与 bootstrap 不同,和 atomify 一样,polymer 的目标是封装一切;不仅是 css,还有 javascript 功能,以及构成它的其他 html 标签。

您会看到 polymer 的一个共同主题主要围绕标记,特别是 html 标签。如果您来自 angular react ,您将立即获得创建自己的元素以供使用的概念。聚合物也是一样的。

这样做的原因是试图减轻“div 汤”,其中有许多使用 css 样式的嵌套 div 创建用户界面,并帮助创建语义:允许各种技术从您的页面中收集含义。语义有助于搜索引擎优化、可访问性,甚至在开发过程中有助于减少开发人员和设计人员的认知开销。

对比 gmail 的构建方式:

与使用自定义组件相比:

尽管 Polymer 的术语是关于“标签”和“自定义元素”,但您真正在做的是创建“组件”:视觉和非视觉。

为什么还要这样做?

组件、组成、封装和设计。

组件:它是接口的开始方式

一旦您构建了一些应用程序,您就会开始认识到每个项目都会出现的 2 种模式。你有一个你遵循的视觉风格指南,无论是官方的还是非官方的。按钮的外观、工作方式、按钮与文本的颜色以及它的形状都是细节的例子。

另一种模式是重复使用。这不仅仅是一个与 dry 相关的编程概念,也是一个设计概念。规则是您应该对相同的用户操作使用相同的 UI 控件,以便用户可以更轻松地使用您的应用程序。雅各布·尼尔森在“2.他的 十大应用程序设计错误文章 中的“不一致”部分。

无论是使用 angular、react 还是 polymer,您都将创建 1 个按钮,1 次,然后在您的应用程序中需要按钮的每个地方使用它。

这适用于所有用户控件。 polymer 的核心概念是构建这些组件,同时提供您需要的许多开箱即用的组件,因此您不必从头开始创建所有组件。也就是说,如果您想选择退出 Material Design,您可以使用它提供的核心 Web 组件库来使用您自己的外观。

组合:接口是如何制作的

一旦构建了组件,就可以开始将它们组合成容纳其他组件的大型组件。这称为 组合 ,在另一件事中使用某事。您要么将这些部分一起使用来构建更复杂的组件,要么构建容器。这可以是日历控件内的自定义按钮:

这是由一个 html 标签创建的:

或者在独立的登录表单中输入一个按钮和一个文本字段:

这也是由一个 html 标签创建的:

最后,您有时会创建容纳动态内容并使用 html 的声明性特性的容器。 polymer 的 <paper-card> 就是一个很好的例子。您不仅可以放置自定义内容,它们还为您提供了 2 个区域供其使用,按钮的“内容”和“操作”区域:

就像 angular 的 ngtransclude backbone marionette 的 regions 一样,你只需在你的组件中使用一个 <content></content> 标签,这就是东西要去的地方。

组件和屏幕越复杂,您创建的组合和容器就越多。聚合物很容易使组合物和容器成为可能。

封装:做好一件事,不要告诉任何人你是怎么做到的

虽然函数式编程和反应式编程流行,但面向对象编程仍然是大多数项目的主要完成方式,也是大多数编程的教学方式。好的 oop 是当您创建具有易于理解的 api 并且不会泄漏太多细节和状态的组件时。

在 html、javascript 和 css 中做到这一点真的很难。 html 的 dom api 使您的文档成为一本打开的书。标记 ID 和类名实际上是全局变量,不能冲突。 javascript 没有模块 api,也没有内置的隐私方式,而无需解决 javascript 的工作原理。 css 应该级联;这是CSS的核心特征。

聚合物试图解决网络的封装问题。

网页格式

shadow dom 使您能够从文档中隐藏 dom。就像您无法打开本机 <button> 一样,您的普通 dom api 代码也不会深入到您的组件中。

CSS

这是不断变化的,但与 html 类似,您在 shadow dom 中定义的 css 样式仅适用于该组件。它们不会泄漏并覆盖其他样式。相反,您实际上拥有来自级联样式的保护伞,因此如果组件的样式与其他样式具有相同的名称,则它们不会被覆盖。您可以自信地将您的组件放在任何其他应用程序中,并确信它看起来是一样的。

javascript

除了使 object.prototype 更易于使用之外,它们在这里并没有做太多事情,因为 Web 组件对此有很多其他解决方案。但是,它们确实使通过 html 导入更容易导入。无论您的代码是代码还是可视化代码,都可以使用相同的标签导入。

谷歌对聚合物所做的工作意味着您只需执行 2 个步骤即可使用您或其他人编写的组件:导入并使用它。

进口:

然后在 light dom 或 shadow dom 中将其用作普通 html:

或通过 javascript:

这比我和其他人今天使用的大量 devops、转译器和模块库要容易得多。这也是为什么多年前 angular dart 使用 组件模型 ,而 angular 2 使用 类注释 的原因。虽然功能性存在,但模块、包组织和封装的基本概念仍然有效,这些都是使用和构建应用程序的好概念。

设计用户界面,然后(主要)构建自己

设计应用程序不同于设计网站。 Web 开发世界广阔、复杂,并且有多种方法。我所看到的关于设计的唯一一致性是那些构建应用程序倾向于将他们的设计封装到他们用来构建应用程序的组件中,而网页设计师倾向于从他们的 css/less/scss 中做到这一点。

聚合物显然在这个拥抱影子 dom 的开发人员方面,我可以布局我的组件的视觉部分,对其进行编码以使其工作,并在同一个地方设置样式。一旦我分发它,我就不必担心有意义的样式名称、css 的组织方式、我使用什么构建任务来重新编译 less 等等。

取而代之的是,您要么只是编写与您的组件内联的 css,并确信您不会对另一个组件产生负面影响,要么您使用 通用样式 ,这是一种安全的选择加入方法。这样,如果您想共享一个样式表或支持​​主题化,您可以在不破坏封装的情况下做到这一点。

此时,您可以帮助缓解网页设计师面临的最大问题:开发人员。

我遇到的大多数开发人员都说他们关心设计,但实际上并不关心。这不是恶意的,他们只是专注于自己的工作,这让事情顺利进行。当他们不工作时,他们会被追究责任。如果颜色或字体错误?没关系。没有正确编译或显示数据库中的数据?那不行。

这种文化强化了开发人员远离设计问题,除非他们也有,因为很多设计更改不能像他们的代码那样容易地进行单元测试。

使用 Polymer,一旦您将填充、字体和颜色已经正确的组件交给开发人员,他们就很难搞砸,除非他们深入研究源组件。对于设计师来说,这很强大。对于讨厌 css 或喜欢设计但没有时间的开发人员来说,它太棒了。对于业务分析师来说,这不是污染积压工作的 jira 工单,而且永远不会及时完成让人们记住工单所指的内容。

此外,对于其他设计师,您可以通过变量公开组件,以允许他们以干净且有据可查的方式突破影子 dom,但仍然抽象实现,以防您以后必须重构组件。

组件使设计人员能够确保开发人员使用的构建块不会那么容易损坏,而开发人员则不必担心“废话,我忘了重新添加那个我不记得它的名字的 css 类”在我重构了那个部分之后。”

所以……为什么又是?

应用程序的界面是使用组件构建的。 polymer 通过将它们保存在同一个文件中,使您可以轻松地使用 javascript、html 和 css 构建组件。

应用程序界面通常是通过在组件中组合组件来创建更复杂的视图和屏幕来构建的。聚合物可以使用聚合物组件内部的聚合物组件。您还可以创建容器以动态启用此功能。

polymer 通过 shadow dom 封装 html 名称和 id,确保您不会因命名冲突而破坏您的应用程序,而不会出现运行时异常,让您知道它因某些随机设计更改而中断。它还在那里封装了你的 css,反转了 css 工作方式的控制,确保你可以进行的唯一 css 更改是选择加入,或者通过容易找到的关键字(如 /deep/)或开发人员创建的变量来显式更改。

对于开发人员而言,它可以轻松地重用您创建的可视化和非可视化组件,从而更轻松地封装和遵守 oop 概念。

对于设计师来说,通过将它们包装在开发人员不需要进入的核心构建块组件中,有助于确保他们的 css 更难被不了解的开发人员破坏。

我该如何使用它?

我选择了艰难的道路。我建议你有更多的乐趣,选择简单的方法。

首先,检查 yeoman generator-polymer 。它会让你快速启动和运行,并且已经为你设置了一个构建系统。

其次,如果你不喜欢自耕农,请直接使用 入门工具包 (这是生成器帮助你入门的东西)。

第三,您可以直接进入 种子元素 ,在本地启动并运行一些简单且较小的东西来玩。

第四,对我来说最有启发性的是使用 0.5 文档“ 你的第一个聚合物应用程序 ”构建一个组件。它们尚未针对 1.0 进行更新,但如果您不介意点击 迁移指南 ,它仍然可以让您了解核心概念的 90%。

第五, rob dodson 有一个很棒的 youtube 频道,叫做 polycasts ,他在这个频道上介绍了聚合物组件的构建,涵盖了所有内容,并以早期的内容为基础。

聚合物陷阱

这里有一些让我困惑的事情。

事件

当您阅读铁和纸元素的文档时,它们具有属性和方法文档,但没有事件。作为构建 gui 的人,这似乎是一个明显的疏忽。要修复它,首先,记住事件是如何通过 fire 方法 工作的。

如果有人去:

那么你知道要监听的事件是“on-change”:

论文中的每一个元素都直接链接到源代码。在那里挖掘“火”方法。如果你没有找到它,那么看看它实现了哪些行为(想想 装饰器模式 或多重继承)并通过搜索功能在 polymer repo 中找到它们的源代码。否则,滚动回顶部,查看它使用的是什么组件。默认情况下,fire 方法会冒泡,因此组合使用的组件可能是实际触发原始事件的组件。

请记住,fire('moo-cow') 会产生一个 <component on-moo-cow=”onwubwubwub()”></component>。如果你在火灾事件中使用驼峰式而不是破折号式,当事情不起作用时你会把自己逼疯的。

动画配置放置

我花了 2 天时间试图让动画工作,因为我两次都把它放在属性对象之外。它应该 进入内部 。如果您认为我不是白痴, 请为这个公关 +1

非视觉组件

一旦你开始深入构建可视化聚合物组件几天,你就会忘记你也可以构建非可视化组件。因为您只能在本机控件上使用继承,所以您的大部分代码将是组合:增强现有标签。

没有人告诉你的核心事情

如果您已经在前端构建应用程序一段时间了,您就会开始对基本的东西在哪里有一些期望。他们来了。

ajax/xhr/http 请求

使用 铁阿贾克斯

制作可选列表

使用 铁选择器

发布订阅

如果你错过了你的 _.trigger $rootscope.$broadcast 然后使用 iron-signals

基本的CSS布局

阅读 iron-flex-layout 的源代码,并删除你脑中的破折号。这允许你做 你在 0.5 中能做的一切 ,除了使用 class 属性。

这:

变成这样:

响应式布局/媒体查询

当您构建具有 2 种布局的组件或屏幕时,您可以使用内嵌的 iron-media-query 。如果您开始为每个媒体查询复制标记,只需将其重构为一个组件即可。

图标

大约有 5 个图标类……忽略它们。只需安装 iron-icons ,然后导入您需要的或全部。要查看哪些可用,请导航至本地 Web 服务器上的 bower_components/iron-icons/demo/ 文件夹以查看您可以使用哪些。

所有图标都使用相同的命名结构:“category:name”,无论是 iron-icon 还是 paper-icon-button 。所以如果你看到图标属性,那就是图标名称的真正含义。

无限滚动列表

......啊,你希望 c# 开发人员在面试时问你的问题与红/黑树排序...... *咳咳* 如果你需要一个,请使用 iron-list

图片

他们有一个非常酷的 uber-image 组件,叫做 iron-image 。比 img 标签更好。

本地存储

他们在 localstorage 周围有一个很好的包装器,叫做 iron-localstorage ,这会为我节省很多时间。基本上允许您将聚合物的内置数据绑定与本地存储一起使用。

路由

聚合物不随路由器一起提供。他们在 0.5 中做到了,但在 1.x 中他们假定您将使用适合您的路由器。 github 和 customelements.io 上有一些特定于聚合物的。

我尝试了一些,但没有一个与我使用调解器视图的方式一起工作,因为它完成了大部分繁重的工作。有些不够明确或不支持自定义 <templates>。更糟糕的是,大多数人只支持 0.5,而不是 1.x。

我试图将 Angular 的 ui-router 包装在一个组件中,但很快就因为无法轻松地让它们相互交谈而感到沮丧,所以只好使用 page.js 。它工作得很好。

范围

polymer 专注于 html 和 css 改进,而不是 javascript。因此,聚合物脚本标签中存在所有相同的范围问题,因为它是基本的 javascript。到处都是“var me = this”。如果您不打算使用框架,我推荐 lodash' bindall

开发运营

代码质量

jshint grunt gulp 中工作,但我无法让 jscs 工作,除非你外部化你的脚本文件并忽略聚合物 html 文件。

喷油器和wiredep

随着项目的增长,您将需要某种类型的模块系统。聚合物的好处在于它可以为您处理加载顺序;只要您将所有导入都放在那里,它们的顺序并不重要。但是,聚合物的构建工具 vulcanize 并不总是与第 3 方库一起使用。我使用注入器( grunt / gulp ),它现在嵌入了 wiredep ,因此它会自动为所有 npm bower 类放置脚本标签。

我发现首先运行这些,然后运行 ​​vulcanize,排除 ignorepath 选项中的构建路径类似乎有效。我没有尝试缩小/丑化聚合物特定脚本,因为它们没有外化。我发现在开发过程中,如果我正在使用的 dom 在同一个文件中并且我向上滚动,那么定位我正在使用的 dom 会更容易。最好找到一种构建方法来自动外部化 javascript 和 css。

另外,我无法让 grunt 或 gulp vulcanize 插件与我的构建结构路径一起使用,所以只为它编写了 原始 javascript 并且它起作用了。

单元测试

我无法让 Web 组件测试器 工作。在与各种缺失的路径进行了数小时的战斗之后,我放弃了。我想如果我使用了 yeoman 生成器,它会起作用。不过,我确实得到了示例种子元素项目的测试。

x-tags 呢?

为什么我要使用聚合物而不是引导程序或基础之类的东西?

polymer 是部分组件框架,但它也是一种使用最新内容的方式,现在可以帮助向 google 提供有关方向的反馈。自去年以来,Polymer 一直是 Web 组件标准的“活原型”,并且随着人们对它的使用而发生变化,谷歌不得不改进它的想法,并且标准委员会已经开始对实现进行标准化。

与 bootstrap/ foundation 不同,您正在构建真正的 Web 组件,而不是带有装饰的 div。

聚合物提供的很多价值在于它实现了谷歌的材料设计。如果你不想要那种外观和感觉,你仍然可以使用大部分的 霓虹 动画元素,只是远离纸张。

对于我们这些在企业开发中构建大型应用程序的人来说,bootstrap 是至高无上的,主要是因为它现在拥有我们需要的所有组件。与聚合物相比,我不得不构建一个 日历/日期选择器 ,因为我发现的大多数只有 0.5。然后我第二天找到了另一个 v1。社区确实在 github 上构建了很多东西,但质量确实参差不齐,而且它不像 bootstrap 那样是一个单一的项目。

最重要的是,bootstrap 在设计、排版、组件和布局方面拥有更多您需要的一切。

我可以使用具有角度、骨架或反应的聚合物吗?

如果你打算将它与角度一起使用,请先尝试 角度材料 。您基本上是在将自己与 Material Design 的外观和感觉结合起来,但我认识的大多数客户都对此表示满意。

如果你想自己做,我不推荐它。 angular 1.0 还不能很好地与 shadow dom 配合使用,而 angular 2 正在实现。除非你做得 恰到好处 ,否则你会遇到 奇怪的错误 ……这真的感觉不对。如果你继续前进,你会喜欢你的大部分角度指令都可以只将它作为它们的模板:

请注意它是模板,而不是 templateurl,这意味着这是为您的聚合物组件提供控制器的好方法……有点。虽然这些方法有效,但很难确定绑定和事件是否有效。

对于 backbone ,事情是模糊的。主干视图基本上是您的聚合物组件的 javascript,<template></template> 标签内容是车把模板。 polymer 已经有一个 pub sub 库,所以不需要骨干事件。虽然从理论上讲主干视图可以成为很好的控制器类,但自己做这件事会更容易,从您的组件中监听附加/分离的事件,a la robotlegs context

我自己还没有尝试过,但我知道一家大银行去年正在研究这种方法,主要是因为他们仍然有很多无法构建完整应用程序的 jsp 和门户网站,因此他们共享小型应用程序。聚合物似乎非常适合这个。

在使用他们的组合策略获得一些经验后,angular 和 backbone 都比我原先想象的更难集成,因为一旦你离开聚合物领域,事情就会变得更难处理。绑定不起作用,因此您必须获取/设置内容。事件不受数据限制,因此您必须使用 addeventlistener。像这样的东西。在聚合物领域生活和工作更容易,并采用与骨干架构相同的方法:根据需要添加 yagni 样式。

需要进行更多调查,因为我可能会错过一些事情或在外部世界整合方面做错了。

反应 对聚合物没有意义。他们都在尝试解决同一件事:更快、更容易的 dom。 react 声称 它很快 ,而 <template> 标签和 shadow dom 的许多聚合物理由是性能。我不知道谁是对的,但两者都构建可重用的组件,具有数据绑定,具有良好的组件生命周期,使 dom 更易于使用,并且没有隐含的 mvc 架构。我认为在聚合物中使用反应会更容易,但同样,除非您相信速度优势可以帮助影子 dom 领域,否则我不明白这一点。

结论

聚合物很棒。我非常喜欢 v1.1 版本。使用组件感觉很自然,这也是我在 director、flash、silverlight 和 flex 时代构建应用程序的方式。虽然我讨厌 css,但我喜欢 flexbox 大多数情况下的工作,而且很多材料设计已经为我实现了。我喜欢开箱即用的铁和纸部件。

我很失望它没有引导程序那么多。我也想念我已经习惯的所有角度功能,主要是 ui-router、控制器和依赖注入,以便于单元测试。陪审团在 devops 上。我也想念 0.5 文档;我猜谷歌的大量标准变化真的很快,也许他们缺乏文档资源,或者没有一个简单的方法让开源在这方面做出贡献。

如果我有一个较小的演出,我没有与 20 多个开发人员一起构建一个长达一年的大型应用程序,并且我可以证明构建缺少的引导程序组件/css(如果有的话)的时间是合理的,我肯定会选择聚合物。作为一个被迫上网的人,与它一起工作肯定会变得更加有趣。

如果您想了解更多信息,我有 一个我构建的日历组件 以及一个 聚合物、节点和 mongo 参考应用程序