xmlplus组件设计系列之选项卡(Tabbar)(5)

这一章将设计一个选项卡组件,选项卡组件在手持设备上用的比较多,下面是一个示意图:

选项卡组成

在具体实现之前,想像一下目标组件是如何使用的,对于设计会有莫大的帮助。通过观察,可以将选项卡组件分为容器部分和子项部分,正如下面的 XML 结构所展示的。

<Tabbar id="tabbar">
  <TabItem id="home" label="首页"/>
  <TabItem id="setting" label="设置"/>
  <TabItem id="logs" label="日志"/>
  <TabItem id="about" label="关于"/>
</Tabbar>

现在我们把目光切换到选项卡组件的子项部分,来看看子项部分是如何分解的。通过示意图,你可以发现子项部分可以分解为子项容器以及包含一个图标和一个文本的子级部分。

<a id="tabitem">
  <Icon id="icon"/>
  <span id="label">首页</span>
</a>

所以,现在我们的目标已经很明确了,主要设计三个组件:图标组件 Icon、选项卡组件的子项 TabItem 以及选项卡组件的容器 Tabbar。

结构图

由于该组件比较简单,所以可以将三种子组件放置在同一层级。但请注意,我们还有四个图标组件,可以创建一个子级用于容纳它们。下面给出我们的组件结构图:

Tabbar/
├── Tabbar
├── TabItem
└── Icon/
     ├── About
     ├── Home
     ├── Logs
     └── Setting

图标的实现

我们从最简单的开始,先看四个图标组件,图标组件主要通过封装 SVG 文本来实现,由于图标文本较长,所以这里仅截取每个图标文本的一段。

About: {
  xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
        <path d="M507.577907 23.272727C240.142852..."/>
     </svg>`
},
Home: {
  xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
        <path d="M949.082218 519.343245 508.704442..."/>
     </svg>`
},
Logs: {
  xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
        <path d="M576 125.344l32 0 0 64-32 0 0-64Z..."/>
     </svg>`
},
Setting: {
  xml: `<svg width="48" height="48" viewBox="0 0 1024 1024">
        <path d="M512 336.664c-96.68 0-175.336 78...."/>
     </svg>`
}

请注意,这些图标位于虚拟目录 /icon 之下,也就是你要像下面这样导入:

xmlplus("ui", function (xp, $_, t) {
  $_().imports({Tabbar: {... }, TabItem: {...}});

  $_("icon").imports({--这里包含了四个图标组件--});
});

下面来实现图标组件 Icon,这里的图标组件与上面是不同的,它会根据输入的图标类型实例化不同的图标。这样设计可以复用部分相同的代码,避免冗余。

Icon: {
  css: "#icon { width: 1.5em; height: 1.5em; display: inline-block; }",
  opt: { icon: "about" },
  xml: `<span id="icon"/>`,
  fun: function (sys, items, opts) {
    sys.icon.replace("icon/" + opts.icon).addClass("#icon");
  }
}

该组件的函数项根据输入的图标类型创建图标组件并替换已有的 span 元素对象。注意,替换完后需要重新添加样式。

子项的实现

按从内到外的原则,接下来实现选项卡组件的子项 TabItem。对于此组件,需要在组件的映射项中做一次异名的属性映射,把 id 属性值映射给内部的图标组件的 icon 属性。

TabItem: {
  css: "这里是样式项部分,为便于组件整体展示,略去...",
  map: {"attrs": { icon: "id->icon" } },
  xml: `<a id="tabitem">
       <Icon id="icon"/>
       <span id="label">首页</span>
     </a>`,
  fun: function (sys, items, opts) {
    sys.label.text(opts.label);
    function select() {
      sys.tabitem.addClass("#primary");
    }
    function unselect() {
      sys.tabitem.removeClass("#primary");
    }
    return { select: select, unselect: unselect };
  }
}

此组件提供了用于选项切换时选中与非选中状态之间切换的接口。以供选项卡容器使用。

选项卡的实现

最后来看下选项卡组件 Tabbar 的实现。该组件侦听了用户触击选项卡时的事件,在侦听器里主要做两件事:一是维持选项卡状态的切换;另一是派发一选项卡切换时的状态改变事件。

Tabbar: {
  css: "这里是样式项部分,为便于组件整体展示,略去...",
  xml: `<nav id="tabbar"/>`,
  fun: function (sys, items, opts) {
    var sel = this.first();
    this.on("touchend", "./*[@id]", function (e) {
      sel.value().unselect();
      (sel = this).value().select();
      this.trigger("switch", this.toString());
    });
    if (sel) sel.value().select();
  }
}

至此,一个选项卡组件算是完成了,下面来看下具体的一个应用:

xmlplus("example", function (xp, $_, t) {
  $_().imports({
  Index: {
    xml: `<Footer id='footer'/>`,
    fun: function (sys, items, opts) {
      this.on("switch", (e, target) => console.log(target));
    }
  },
  Footer: {
    xml: `<Tabbar id="footer">
         <TabItem id="home" label="首页"/>
         <TabItem id="setting" label="设置"/>
         <TabItem id="logs" label="日志"/>
         <TabItem id="about" label="关于"/>
       </Tabbar>`
  }
  });
});

在组件 Index 中,你可以侦听来自选项卡的切换事件来做相应的操作。比如结合后续我们介绍的视图栈组件做页面之间的切换操作。

本系列文章基于 xmlplus 框架。如果你对 xmlplus 没有多少了解,可以访问 www.xmlplus.cn。这里有详尽的入门文档可供参考。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • xmlplus组件设计系列之路由(ViewStack)(7)

    在浏览器端,对路由的理解一般是根据不同的 URL 完成页面的切换.在服务器端,则是根据不同的 URL 请求回馈相关的页面.在本章,我们广义的组件路由的定义:根据接收到的不同命令,组件对象呈现出不同的子级页面.在这里将介绍与路由相关的一个组件,即视图栈 ViewStack. 视图栈初步 该组件在<文档>部分的最后一个章节<延迟实例化>已经出现过了.这里将对一些细节部分进行解读.下面再次给出该组件的源码. ViewStack: { xml: "<div id='view

  • xmlplus组件设计系列之图标(ICON)(1)

    网页上使用的图标分可为三种:文件图标.字体图标和 SVG 图标.对于文件图标,下面仅以 PNG 格式来说明. PNG 图标 对于 PNG 图标的引用,有两种方式.一种是直接由 HTML 元素 img 的 src 属性给出.下面是一个简单的示例. Icon: { css: "#icon { width: 68px; height: 68px; }", xml: "<img id='icon'/>", fun: function (sys, items, o

  • xmlplus组件设计系列之文本框(TextBox)(3)

    文本框是页面中最常用的输入组件,它的默认使用方式如下: <input type='text'/> 当然,这里的 `type='text' 可以略去不写.大部分情况下,使用默认的文本框作为输入组件是没什么问题的,但在具体的项目中,难免会有功能扩展的需求.这里仅以如何增加文本框数据的格式化输入输出能力为例说明如何扩展原生的文本框组件.除了本章的内容,你也可以参考官方文档中的 参数映射 一章. 目标组件的功能分析 对于原生的文本框,我们获取到的值是文本类型的,就像下面的示例所展示的: Example

  • xmlplus组件设计系列之树(Tree)(9)

    树形组件是一种具有层级结构的组件,广泛应用于各种场景.本章会实现一个简单的树形组件,尽管功能有限,但你可以通过扩展它来实现自己所需要的树形组件. 数据源 树形组件的数据源可以是 JSON 格式的数据对象,也可以是具有 XML 结构的数据或者是其它的具有层级结构的数据.本章将采用具有如下 JSON 格式的数据对象. var data = { name: 'My Tree', children: [ { name: 'hello' }, { name: 'world' }, { name: 'chi

  • xmlplus组件设计系列之按钮(2)

    除了图标以外,按钮也许是最简单的组件了,现在来看看如何定义按钮组件. 使用原生按钮组件 在 xmlplus 中,HTML 元素也以组件的方式存在.所以,你可以直接通过使用 button 标签或者 input 标签来使用按钮组件.如下示例所示: Example: { xml: "<div id='example'>\ <button>Default</button>\ <input type='submit'>Primary</input>

  • xmlplus组件设计系列之分隔框(DividedBox)(8)

    分隔框(DividedBox)是一种布局类组件,可以分为两类,其中一类叫水平分隔框(HDividedBox),另一类叫垂直分隔框(VDividedBox).水平分隔框会将其子级分为两列,而垂直分隔框则会将其子级分为两行.列与列之间以及行与行之间一般都会有一条可以拖动的用以改变子级组件大小的分隔条.下面仅以垂直分隔框为例来介绍此类组件是如何设计以及实现的. 成品组件用例 按照以往的设计经验,我们可以先写出想像中的成品组件用例,这将有助于我们后续的进一步的设计与实现.垂直分隔框既然是布局类的组件,那

  • xmlplus组件设计系列之网格(DataGrid)(10)

    这一章我们要实现是一个网格组件,该组件除了最基本的数据展示功能外,还提供排序以及数据过滤功能. 数据源 为了测试我们即将编写好网格组件,我们采用如下格式的数据源.此数据源包含两部分的内容,分别是表头数据集和表体数据集.网格组件实例最终的列数由表头数据集的长度决定. var data = { gridColumns: ['name', 'power'], gridData: [ { name: 'Chuck Norris', power: Infinity }, { name: 'Bruce Le

  • xmlplus组件设计系列之下拉刷新(PullRefresh)(6)

    "下拉刷新"由著名设计师 Loren Brichter 设计,并应用于 Twitter 第三方应用 Tweetie 中.2010年4月,Twitter 收购 Tweetie 开发商 Atebits 后,该专利归 Twitter 所有.这一章我们就来看看如何实现一个简单的下拉刷新组件. 目标组件分析 和前面在设计组件时的做法一样,我们先想想看最终的成品组件是如何使用的,这需要点想像力.下拉刷新组件看成一个容器组件是合理的,用户可以对容器的内容进行下拉操作.如果用户完成了完整的下拉触发操作

  • xmlplus组件设计系列之列表(4)

    列表组件是极其常用的一类组件,是许多视图组件系统的必须包含的.列表可以做的很简单,只显示简洁的内容.列表也可以做的很复杂,用于展示非常丰富的内容. 组成元素 列表离不开列表项以及包含列表项的容器.下面是最简单的列表组件,它包含一个列表项组件 Item 以及一个列表项容器组件 List. Item: { xml: "<li id='item'/>" }, List: { xml: "<ul id='list'/>" } 此列表组件尽管简单,但所

  • xmlplus组件设计系列之选项卡(Tabbar)(5)

    这一章将设计一个选项卡组件,选项卡组件在手持设备上用的比较多,下面是一个示意图: 选项卡组成 在具体实现之前,想像一下目标组件是如何使用的,对于设计会有莫大的帮助.通过观察,可以将选项卡组件分为容器部分和子项部分,正如下面的 XML 结构所展示的. <Tabbar id="tabbar"> <TabItem id="home" label="首页"/> <TabItem id="setting"

随机推荐