用Web Components构建单页面应用

你是如何使用Polymer构建一个单页应用的?这个问题我们在Polymer团队里已经问过很多遍了。我们的答案(一如既往地)是“使用组件(component)!”。然而,使用新技术去解决现有的问题往往不会马上得到显著的效果。如何把一堆模块化组件组合到一个大型的实用的应用中去?

在本教程,我将会给你展示如何去构建一个功能完整的单页应用:

  • 完全使用Polymer的核心元素构建
  • 使用响应式设计
  • 使用数据绑定特性过渡视图
  • 使用URL路由和深层链接特性
  • 可访问键盘
  • 按需动态载入内容(可选)

 打开演示

应用架构

设计布局是开始一个项目的首要任务之一。作为核心元素集合的一部分,Polymer通过几个布局元素 来支撑应用程序的构架(<core-header-panel>, <core-drawer-panel>, <core-toolbar>)。这些组件本身就很好用,但是为了更快地开始项目,我们打算着重于<core-scaffold>。有了它你可以通过组装几个基本的元素就能做出一个响应式的移动端布局。

<core-scaffold>的子元素可以是指定特定的元素或使用特定的标签(或两者一起使用)。举个例子,使用<nav>元素创建应用抽屉菜单。你可以在任意的元素里使用navigation属性(e.g <core-header-panel navigation>)。工具栏通过工具属性标识。它的所有其他子元素都定义在主要内容区域里。

例子

让我们一起来深入这些内容的每一部分

抽屉菜单

你放在导航元素里的标记都定义在滑走的应用抽屉菜单里。为了我们的目标 ,我坚持使用标题(<core-toolbar>)和导航链接 (<core-menu>):

注意,现在<core-menu selected=”0″>被硬编码为选择第一个条目。我们以后会把它改为动态的。

工具栏

工具栏横跨了页面顶部并包含了功能按钮图标。满足这种功能的完美元素是<core-toolbar>:

主要内容

最后一部分是为你的内容而留的。它可以是任何的元素。<div>是一个很好的选择:

fit属性表示主要区域的内容会布满父元素的宽带和高度,layout horizontal center-center属性表示使用弹性框(flexbox)来使内容居中和垂直居中。

创建“视图”

多视图(或者多页面)可以使用<core-pages>或者<core-animated-pages>来创建。在一次只展示一个子元素时,两个元素都很有用。而使用<core-animated-pages>的好处是,它提供了更多的默认和灵活的页面过渡。

下面的演示(demo)使用了<core-animated-pages>元素的slide-from-right过渡效果。首先,导入元素定义和slide-from-right过渡效果。

然后插入你的内容:

注意,现在 <core-animated-pagesselected=”0″>这行代码是硬编码去选择第一页。不过我们以后会把它写成动态的。

现在你应该拥有了一个基本的应用,但是这里有一些小的问题需要注意。多亏了Polymer每个元素提供的布局属性默认样式,你可以不写任何的CSS代码就可以实现一个响应式应用。当然,从material design调色板里获取一些灵感,设置不到10 CSS规则就可以让这个应该变得更好看。

展示:没设置CSS      展示:设置CSS

使用数据绑定

我们拥有了一个应用,但这不值得一提。这离DRY还远着。类似的标记在这里重复出现:

这同样不是动态的。当用户选择一个菜单条目时,页面不会更新。幸运的是,这些问题都可以使用Polymer的数据绑定特性轻松解决。

自动绑定模板(template)

为了利用<polymer-element>外的绑定数据,包装一个Yo应用?利用里面的自动绑定<template>元素:

提示,<template>自动绑定元素允许我们在主要页面里使用{{}},表达式on-*来声明事件处理器

使用数据模型( data model)简化标记

利用数据模型来产生标记可以大量减少你写标记的数量。在我们的案例里,所有的菜单条目和页面都可以利用一对<template repeat>元素来呈现。

上面的标记由下面的数据模型来驱动:

注意,<core-animated-pages>和<core-menu>通过绑定它们的selected属性来关联在一起。现在,当用户点击一个导航条目时,页面会做出相应的更新。valueattr=”hash”设置告诉两个元素在每个条目里使用hash属性作为选择的值。

展示

URL路由(URL routing)和深层链接

<flatiron-director>是一个包装了 flatiron director JS library(一个JS库)的web组件。改变它的route属性把URL#号(URL hash)更新到相同的值。

当我们想在页面加载时维持上次的视图时,数据绑定再次派上用场。把路由(director.js里的director)、菜单和页面元素连接起来并使它们同步。当一个更新时,其他的同样跟着更新。

深层链接-当模板准备好时,初始化路由。

其他路由库

如果你不喜欢<flatiron-director>,可以试试<app-router>或者<more-routing>。它们都是可以实现更复杂功能的路由(通配符,HTML5历史API,动态内容)。我个人更喜欢<flatiron-director>,因为它简单易用并且可以和<core-animated-pages>很好地配合使用

例子: <more-routing>

例子: <app-router>

键盘导航

键盘支持的重要性不仅仅是为了方便的访问,它同样会使SPA用户刚到更开心。

<core-a11y-keys>是一个标准化浏览器键盘事件的嵌入组件。它可以在你的应用里添加键盘支持。这里有一个例子:

注意

事件的target属性数据绑定到我们的自动绑定模块的parentElement属性。在这个案例里,它是<body>元素。

key属性包含一个以空格分隔元素的列表,列表中包含了要监听键位。当这些组合的其中一个被按下,<core-a11y-keys>触发一个keys-pressed事件并调用你的回调函数。

keys-pressed事件的处理器使用<core-animated-pages>的selectNext/selectPrevious API去进入下一页或者返回上一页:

按需加载内容

如果你想用户在你的应用里导航时动态加载内容要怎样做?只需一些改动,我们就可以支持动态加载页面。

首先,更新数据模型,使它包含内容的URL:

然后改变菜单链接指向page.url而不是#:

最后,使用我们的<core-ajax>好友来获取内容:

你可以把<core-ajax>看作是一个内容控制器。它的url属性数据绑定到selectedPage.page.url。这意味着,无论什么时候一个新的菜单条目被选中,XHR(XMLHttpRequest的缩写,译者注)就会去获取相应的页面。当core-response触发时,onResponse就会把文档返回的一部分插入预先保留的容器里。

AJAX实例演示

润饰和收尾

这里有一些小技巧和诀窍你可以用来改善你的应用。

当一个菜单条目被选择后,关闭应用的抽屉菜单(drawer):

为导航选择条目设置不同的图标:

结束语

现在,你应该了解使用Polymer和web组件构建的单页应用的基本构架了。这可能和构建传统的应用有所不同,但总的来说,组件让事情变得简单多了。当你重用(核心)组件和使用Polymer的数据绑定特性时,你可以写更少的CSS/JS。可以写更少的代码的感觉真好!

收藏 评论

关于作者:周进林

茫茫大海中的一枚程序猿,为了进化为一个高富帅人类而努力着。关注java、python、linux、vim等(新浪微博:@酒肉和尚--进林) 个人主页 · 我的文章 · 19 ·  

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部