Open Tech Pub

那些年关注的技术

Weex语法

  • 数据绑定
  • 样式
  • 事件处理
  • 展示逻辑控制
  • 渲染逻辑控制
  • 组件封装
  • 找节点
  • 组件通信
  • 页面配置和页面数据

首先运行Weex代码有两种方式:

  1. 安装本地环境
  2. 使用dotwe.org

语法介绍

1
2
3
4
5
6
7
8
9
<template>
  /* (required) the structure of page */
</template>
<style>
  /* (optional) stylesheet */
</style>
<script>
  /* (optional) the definition of data, methods and life-circle */
</script>

Weex代码由<template><style><script>三个部分构成。 可以对应理解成HTML、CSS、JavaScript。

数据绑定

Weex在<template>使用mustache语法{{…}}绑定<script>中的数据

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
<template>
  <div>
    <text style="font-size: { {size} }">{ {title} }</text>
    <text>{ {fullName} }</text>
    <text onclick="toggle">事件绑定: { {result} }</text>
  </div>
</template>

<script>
  module.exports = {
    data: {
      size: 50,
      title: 'www.openwudi.com',
      firstName:'Wu',
      lastName:'Di',
      result:true
    },
    computed:{
      fullName: function(){
        return this.firstName + ' ' + this.lastName
      }
    },
    methods:{
      toggle: function () {
        this.result = !this.result
      }
    }
  }
</script>

根据上面的例子,可以看到,data中声明了一些变量,这些变量直接对应<template>中的数据,进行绑定。通过computed属性生命计算相关的数据操作。<template>中以on...开头的就是用于事件绑定操作,对应methods中声明的方法。

样式

Weex支持CSS基础语法,由一系列的键值对进行声明,每对键值由;分隔。
width: 400; height: 50; ...

Weex声明样式有两种方式:

  • <template>中的style属性
  • <style>样式表

<template>中声明style

1
2
3
4
<template>
  <div style="width: 400; height: 50;">
  </div>
</template>

<style>中声明

1
2
3
4
5
<style>
  .wrapper { width: 600; }
  .title { width: 400; height: 50; }
  .highlight { color: #ff0000; }
</style>

class选择器

1
2
3
4
5
6
7
8
9
10
11
<template>
  <div class="wrapper">
    <text class="title">...</text>
    <text class="title highlight">...</text>
  </div>
</template>
<style>
  .wrapper { width: 600; }
  .title { width: 400; height: 50; }
  .highlight { color: #ff0000; }
</style>

注意事项

  • 为了简化页面设计和实现,屏幕的宽度统一为750像素,不同设备屏幕都会按照比例转化为这一尺寸进行长度计算。
  • 标准 CSS 支持很多样式选择器,但 Weex 目前只支持单个class name的选择器。
  • 标准 CSS 支持很多的长度单位,但 Weex 目前只支持像素,并且px单位可以忽略不写,直接使用对应的数值。更多详情请查看通用样式。
  • 子元素的样式不会继承自父元素,这一点与标准 CSS 不同,比如 color 和 font-size 等样式作用在 上层的
    上是无效的。
  • 标准 CSS 包含了非常多的样式属性,但 Weex 只支持了其中的一部分,比如盒模型、flexbox、position 等布局属性,以及 font-size、color 等其它样式。

事件处理

使用属性名为on...前缀为<template>增加事件绑定。

1
2
3
4
5
6
7
8
9
10
11
12
<template>
  <image onclick="handler" ...></image>
</template>
<script>
  module.exports = {
    methods: {
      handler: function (e) {
        // TODO
      }
    }
  }
</script>

添加参数,获取事件对象

1
2
3
4
5
6
7
8
9
10
11
12
<template>
  <image onclick="handler('arg1', $event)" ...></image>
</template>
<script>
  module.exports = {
    methods: {
      handler: function (arg1, e) {
        // TODO
      }
    }
  }
</script>

当一个事件函数被调用,它会收到的第一个参数就是事件对象。每个事件对象包含一下属性。

  • type: 事件名称, 如: click
  • target: 目标元素
  • timestamp: 事件触发的时间戳

展示逻辑控制

Weex前端语义支持通过两种特殊属性(if和repeat)的设置来确定组件的显示状态,这会使得整个页面布局显得更加灵活。

if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<container>
    <text onclick="toggle">Toggle</text>
    <image src="..." if=""></image>
</container>
</template>
<script>
    module.exports = {
    data: {
        shown: true
    },
    methods: {
    toggle: function () {
        this.shown = !this.shown
    }
    }
}
</script>

repeat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  <template>
    <container>
        <container repeat="" class="">
            <image src=""></image>
            <text></text>
        </container>
    </container>
    </template>
    <style>
    .male {...}
    .female {...}
    </style>
    <script>
    module.exports = {
        data: {
            list: [
            {gender: 'male', nickname: 'Li Lei', avatar: '...'},
            {gender: 'female', nickname: 'Han Meimei', avatar: '...'},
         ...
        ]
     }
    }
</script>

渲染逻辑控制

append属性没有做数据绑定的工作。它不会改变最终的渲染效果。但是此属性确定是以一整棵树或子节点的方式添加。

append有两个关键属性,treenode,使用方法如下:

1
2
3
4
5
6
7
8
9
10
<template>
  <container>
    <container id="world" append="tree">
      <text>Hello World!</text>
    </container>
    <container id="weex" append="node">
      <text>Hello Weex!</text>
    </container>
  </container>
</template>

组件封装

经常我们会发现很多可复用的weex文件,这时候可以封装成weex组件。我们可以直接创建一个名为foo.we的文件,<foo>就是组件名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- foo.we -->
<template>
  <container style="flex-direction: row;">
    <image src=""></image>
    <text></text>
  </container>
</template>
<script>
  module.exports = {
    data: {
      title: null,
      image: null
    }
  }
</script> 

foo.we的也包含<template><style><script>,定义好了后,直接用<foo>标签即可, 注意这里bar.wefoo.we是在同目录下哦,如下:

1
2
3
4
<!-- bar.we -->
<template>
  <foo title="..." image="..."></foo>
</template> 

找节点

weex中,可以通过在特定的节点上设置 id 属性,以此来唯一标识该节点。然后可以用this.$el(id)来找到该节点,以scrollToElement()为例,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
  <container>
    <text id="top">Top</text>
    <container style="height: 10000; background-color: #999999;">
    </container>
    <text onclick="back2Top">Back to Top</text>
  </container>
</template>
<script>
  var dom = require('@weex-module/dom');
  module.exports = {
    methods: {
      back2Top: function () {
        var top = this.$el('top')
        dom.scrollToElement(top, { offset: 10 })
      }
    }
  }
</script> 

组件通信

子组件可以使用this.$dispatch([String type], [Object detail])方法传递消息给父组件。
第一个参数定义消息类型,第二个参数为消息对象。如果父组件中的任何子组件使用$on([String type], [Function callback])注册监听事件,则回调执行第一个参数,参数中的detail属性是消息数据。

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
<we-element name="foo">
  <template>
    <div>
      <image src="" onclick="test"></image>
      <text></text>
    </div>
  </template>
  <script>
    module.exports = {
      data: {
        title: '',
        imageUrl: ''
      },
      methods: {
        test: function () {
          this.$dispatch('notify', {a: 1})
        }
      }
    }
  </script>
</we-element>
<template>
  <foo title="..." image-url="..."></foo>
</template>
<script>
  module.exports = {
    created: function () {
      this.$on('notify', function(e) {
        //  when <foo> image tag  be clicked ,the function will be executing.
        // e.detail is  `{a: 1}`
      })
    }
  }
</script>

页面配置和页面数据

你可以在另外的<script>中写一些 配置和数据的实例,添加到 top-level weex 组件中。
* 配置实例中可以申明一些meta信息 比如SDK/Client版本。支持降级到H5 渲染方式。未来还将支持更多的扩展。 * 数据实例中可以设置外部数据替换掉默认top-level组件数据。 这些都使weex文件更具扩展和可配置,让其更容易的在其他工具和服务中工作,比如CMS系统。

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
<!-- definition of sub components -->
<element name="sub-component-a">...</element>
<element name="sub-component-b">...</element>
<element name="sub-component-c">...</element>
<!-- definition of top-level component -->
<template>...</template>
<style>...</style>
<script>
  module.exports = {
    data: function () {return {x: 1, y: 2}}
  }
</script>
<!-- instance config and data -->
<script type="config">
  downgrade: {
    ios: {
      os: '9', // all of 9.x.x
      app: '~5.3.2',
      framework: '^1.3', // all of 1.3.x
      deviceModel: ['AAAA', 'BBBB']
    },
    android: {
      os: '*', // all of version
      app: '^5',
      framework: '',
      deviceModel: ''
    }
  }
</script>
<script type="data">
  {y: 200}
</script>