数据绑定

Weex使用 mustache 的语法 ({{...}}) 来对 <template> 中的模板和 <script> 里的数据进行绑定. 一旦数据额模板绑定了, 数据上的修改会实时的在模板内容中生效。

样式: style class

组件的样式能够通过style特性进行绑定:

<template>

<div>

<text style="font-size: {{size}}; color: {{color}};">Hello World</text>

</div>

</template>

<script>

module.exports = {

data: {

size: 32,

color: '#ff0000'

}

}

</script>

体验一下

样式也能够通过class特性实现样式绑定,多个 class 名通过空格分隔:

<template>

<div>

<text class="{{size}}">Hello</text>

<text class="title {{status}}">World</text>

</div>

</template>

<style>

.large { font-size: 64; }

.small { font-size: 32; }

.title { font-weight: bold; }

.success { color: #00ff00; }

.error { color: #ff0000; }

</style>

<script>

module.exports = {

data: {

size: 'large',

status: 'success'

}

}

</script>

按下Ctrl+Shift+P调出命令面板输入install 调出 Install Package 选项并回车,然后在列表中选中要安装的插件。按下Ctrl+Shift+P调出命令面板输入install 调出 Install Package 选项并回车,然后在列表中选中要安装的插件。

weex hello.we

weex hello.we --qr

weex debug hello.we

在 Weex 中,您可以通过在特定的子组件上设置 id 特性,以此在该 <template> 内唯一标识这个组件。

Weex 代码由三部分构成:template、style、script,这三个概念之于 Weex 就如 HTML,CSS,JavaScript 之于 Web。

Weex 代码由 <template>、<style>、<script> 三个部分构成。

  • <template>:必须的,使用 HTML 语法描述页面结构,内容由多个标签组成,不同的标签代表不同的组件。
  • <style>:可选的,使用 CSS 语法描述页面的具体展现形式。
  • <script>:可选的,使用 JavaScript 描述页面中的数据和页面的行为,Weex 中的数据定义也在 <script> 中进行。

每个 Weex 页面最顶层的节点,我们称为根节点。下面是目前我们支持的三种根节点:

  • <div>:普通根节点,有确定的尺寸,不可滚动。
  • <scroller>:可滚动根节点,适用于需要全页滚动的场景。
  • <list>:列表根节点,适用于其中包含重复的子元素的列表场景。

目前 Weex 仅支持以上三种根节点。

<script> 描述页面中的数据和页面的行为,代码遵循 JavaScript (ES5) 语法 (目前 iOS 端和浏览器端取决于内置 JavaScript 引擎对 ES 版本的支持情况

上面 <script> 标签中定义了被赋值给 module.exports 的对象,这个对象其实就是一个 ViewModel 选项,

定义组件是通过一组选项来描述一个组件。这组选项总是被赋值给 <script> 标签中的 module.exports 。

module.exports = {

// a set of options here

}

data 选项是一个函数,它返回这个视图模型可监听的数据对象。而 methods 是一个映射,其中包含所有视图模型的方法。

每个 data 或 method 属性将被代理到视图模型实例中。所以,你能通过 this.x 读写数据,或者通过 this.doThis() 调用方法。

events 选项允许你在视图模型被创建时注册自定义事件。然后,它会监听这些类型的事件,并通过函数类型的值处理它们。

Weex 会把一个事件对象作为第一个参数传递给其绑定的事件,这个事件对象在 e.detail 中包含事件数据。

组件定义

定义组件是通过一组选项来描述一个组件。这组选项总是被赋值给 <script> 标签中的 module.exports

data 选项是一个函数,它返回这个视图模型可监听的数据对象。而 methods 是一个映射,其中包含所有视图模型的方法。

events 选项允许你在视图模型被创建时注册自定义事件。然后,它会监听这些类型的事件,并通过函数类型的值处理它们。

生命周期

module.exports = {

data: ...,

methods: ...,

init: function () {

console.log('ViewModel constructor begins')

console.log('在初始化内部变量,并且添加了事件功能后被触发');

},

created: function () {

console.log('Data observation finished')

 console.log('完成数据绑定之后,模板编译之前被触发');

},

ready: function () {

console.log('Virtual DOM finished')

console.log('模板已经编译并且生成了 Virtual DOM 之后被触发');

},

 destroyed: function () {
console.log('在页面被销毁时调用');
},

...

}

Weex 视图模型现在支持生命周期内的钩子函数,这些钩子函数能被写为组件选项:

  • init: 在视图模型的构造函数开始调用时激活;
  • created: 当视图模型监听默认数据,但还未编译模板时激活;
  • ready: 当视图模型监听默认数据并且编译模板生成虚拟DOM后被激活。

init内一般用于初始化一些内部变量,绑定一些自定义事件,这时还没有数据绑定,没有创建vdom,所以不能通过this获取到data和methods,也不能获取vdom的节点

created 完成了数据绑定 ,但还未开始编译模板,可以通过this获取data和methods,但不能获取vdom的节点

ready表示渲染完成 ,从子组件往上触发

destroyed 组件销毁,比如页面跳转,从子组件开始往上触发

注意:当 methodsevents 或生命周期方法作为参数传递给别的函数时,务必确认函数执行时的上下文符合您的预期,例如:

module.exports = {

data: function () {

return {x: 1, y: 2}

},

ready: function () {

// `undefined`

// 因为上下文发生了变化

this.foo(this.bar)

// `1`

// 正确绑定上下文之后可以得到预期的值

this.foo(this.bar.bind(this))

},

methods: {

foo: function (fn) {

return fn()

},

bar: function () {

return this.x

}

}

}

Weex使用 mustache 的语法 ({{...}}) 来对 <template> 中的模板和 <script> 里的数据进行绑定. 一旦数据额模板绑定了, 数据上的修改会实时的在模板内容中生效。

注意事项:datamethodscomputed 中的字段是不能相互重复的,因为它们都会通过组件实例的this 访问到。

事件绑定:on...

以 on... 开头的就是用于绑定事件的特性,特性名中 on 之后的部分就是事件的类型,特性的值就是处理该事件的函数名。函数名外不需要添加 mustache 语法中的大括号。

在 Weex 页面上样式有两种形式:

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

append

append 特性定义了当前组件的子组件:

  1. 以一整棵树的方式一次性添加到视图中 (append="tree"),还是
  2. 每个子组件都产生一次单独的添加到视图的指令 (append="node")

自定义组件

经常我们会发现 Weex 的 <template> 中有很多可复用的部分,这时候我们可以将其封装成上层的自定义组件并重用。例如我们可以直接创建一个名为 foo.we 的文件,<foo> 就是自定义组件的组件名称:

组件嵌套

自定义组件也支持嵌套,如下:

<!-- somepath/foo.we -->

<template>

<div style="flex-direction: row;">

<image src="{{image}}"></image>

<text>{{title}}</text>

</div>

</template>

<script>

module.exports = {

data: {

// These keys must be declared explicitly here

// or data-binding will not work from its parent.

title: null,

image: null

}

}

</script>

<!-- samepath/foo.list.we -->

<template>

<div>

<text>{{description}}</text>

<foo repeat="item in list" title="{{item.text}}" image="{{item.img}}"></foo>

</div>

</template>

<script>

module.exports = {

data: {

description: '',

// This key must be declared explicitly here

// or data-binding will not work from its parent.

list: []

}

}

</script>

<!-- samepath/main.we -->

<template>

<foo-list list="{{list}}"></foo-list>

</template>

<script>

module.exports = {

data: {

list: [

{text: '...', img: '...'},

{text: '...', img: '...'},

{text: '...', img: '...'},

...

]

}

}

</script>

这里的main.we嵌套了<foo-list><foo-list>嵌套了<foo>,同时组件可以正常的配合数据绑定、repeat特性等使用。

更多子组件的定义和书写方式

除了在主文件同目录下创建和被封装组件同名的 we 文件之外,Weex 还支持另外几种子组件的书写方式:

  • 在 <script> 中通过 require 其它目录的 we 文件定义同名组件
  • 在主文件下新增 <element name="xxx"> 标签,name 特性的值为新创建的组件名,其 <element> 内部的内容是定义该组件的代码

比如:

<!-- path-a/main.we -->

<element name="foo">

<text>Foo</text>

</element>

<template>

<div>

<foo></foo>

<bar></bar>

</div>

</template>

<script>

require('path-b/bar.we')

</script>

<!-- path-b/bar.we -->

<template>

<text>Bar</text>

</template>

这样的话,path-a/main.we 最终展示的结果是“Foo”和“Bar”两段文本。

注意事项

  • 组件各自的 <style> 是相互独立的,不会担心不同组件中相同的 class name 相互干扰。
  • 如果自定义组件在父组件中有 id 特性,则可以在父组件上下文中通过 this.$vm(id) 接口来访问该自定义组件的上下文,也可以通过 this.$el(id) 来找到其背后真实的原生组件。更多详见获取子组件信息
  • 自定义组件之间通信的问题可以参考组件间通信
  • 不论通过父组件把数据传递进来还是在当前组件内部对数据发起修改,只有在组件的 data 选项中明确写明的字段才会被正常的监听。

获取自定义子组件的上下文

另外,我们还可以通过this.$vm(id) 方法可以访问自定义子组件的上下文:

另外,我们还可以通过this.$vm(id)方法可以访问自定义子组件的上下文:

<element name="foo">

<template>

<div style="flex-direction: row;">

<text>{{title}}</text>

</div>

</template>

<script>

module.exports = {

data: {

title: null

},

methods: {

setTitle: function (text) {

this.title = text

}

}

}

</script>

</element>

<template>

<div>

<foo id="sub" title="Hello"></foo>

<text onclick="update">Click Me to Update</text>

</div>

</template>

<script>

module.exports = {

methods: {

update: function (e) {

this.$vm('sub').setTitle('Updated')

}

}

}

</script>

获取子组件信息

Weex 中,您可以通过在特定的子组件上设置id特性,以此在该<template>内唯一标识这个组件。

获取子组件

您可以在父组件上下文中使用this.$el(id)来找到该组件,以运用scrollToElement()为例:

<template>

<div>

<text id="goto-top">Top</text>

<div style="height: 10000; "></div>

<text onclick="back2Top">Back to Top</text>

</div>

</template>

<script>

var dom = require('@weex-module/dom')

module.exports = {

methods: {

back2Top: function () {

var el = this.$el('goto-top')

dom.scrollToElement(el, { offset: 10 })

}

}

}

</script>

组件间通信

自定义事件

Weex 支持自定义事件,这里有两个相关的设计:1,监听自定义事件;2,创建自定义事件。

监听自定义事件

每个 Weex 的 ViewModel 都支持 this.$on(type, handler) 和 this.$off(type[, handler]) 的 API。type 是监听的自定义事件类型,handler 是事件处理函数。

当 handler 被触发时,会有一个事件对象 event 作为第一个参数被传入,事件对象的数据格式基于事件机制中提到的事件描述对象。

创建自定义事件

每个 Weex 的 ViewModel 都支持 this.$emit(type, detail) 的 API,可以在当前 ViewModel 中产生一个自定义事件。type 是自定义事件的类型,detail 则是一个对该事件细节补充描述的 JSON 对象,会以 event.detail 的形式出现在处理此事件的函数中。

从子组件向父组件通信

首先父组件要监听特定类型的自定义事件,而子组件可以使用 this._parent 找到父组件,然后再调用 this._parent.$emit(type, detail) 方法,即可实现自下而上的通信。例如:

从父组件向子组件通信

同理,首先子组件要监听特定类型的自定义事件,而父组件可以使用 this.$vm(id) “访问自定义子组件的上下文”,然后再调用 this.$vm(id).$emit(type, detail) 方法,即可实现自上而下的通信。例如:

页面整体配置

在 Weex 中,你可以通过一些特殊的 <script> 进行页面整体配置。

注意事项:这些配置会代表页面整体,所以写在自定义子组件中是无效的,只有写在顶级 ViewModel <sctipt> 中才会生效。

先举个例子:

<!-- 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: { x: 1, y: 2 }

}

</script>

<!-- 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>

<script type="config">

开发者可以在顶级 ViewModel 中加入这样一段 <script>,以 JSON 格式描述页面整体的配置信息。

目前支持的配置信息只有 downgrade:用来从平台、应用等维度描述页面的降级规则。这样设计对于产品迭代最大的帮助是可以在高版本中使用 Weex,而在低版本中使用之前已有的渲染方式,这部分控制降级的细节需要 native 接入的时候进行相应的识别和具体操作。

未来这里会有更多的配置项出现在这里。

<script type="data">

开发者可以在顶级 ViewModel 中加入这样一段 <script>,以 JSON 格式额外配置顶级 ViewModel 的数据,它会覆盖顶级 ViewModel 数据中相应的字段。比如上述例子中,最终的顶级 ViewModel 中的数据为 { x: 1, y: 200 }。

Weex-语法笔记 一的更多相关文章

  1. SQL基础语法笔记教程整理

    PS:本文适用SQL Server2008语法. 一.关系型数据库和SQL 实际上准确的讲,SQL是一门语言,而不是一个数据库. 什么是SQL呢?简而言之,SQL就是维护和使用关系型数据库中的的数据的 ...

  2. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  3. SQL 基础语法笔记教程整理

    最近从图书馆借了本介绍 SQL 的书,打算复习一下基本语法,记录一下笔记,整理一下思路,以备日后复习之用. PS:本文适用 SQL Server2008 语法. 首先,附一个发现的 MySQL 读书笔 ...

  4. [python] Pythonic语法笔记

    Pythonic语法笔记 __new__ 在类实例化之前执行的,也就是在init之前执行,可以为这个类写操作.接受的参数不是self而是cls.只有在new方法里返回类才会执行init操作,需要返回父 ...

  5. SQL Server 常用高级语法笔记

    自从用了EF后很少写sql和存储过程了,今天需要写个比较复杂的报告,翻出了之前的笔记做参考,感觉这个笔记还是很有用的,因此发出来和园友分享. 1.case...end (具体的值)case后面有值,相 ...

  6. C#语言不常用语法笔记

    只看过3天C#语法书,了解个大概,与C++等不同之处,或者看开源遇到一些奇异用法,记录一下,脑子不够用的情况下,还是记笔记靠谱. ==================== 顺便吐槽下,这年头得会各种编 ...

  7. solr使用语法笔记

    http://127.0.0.1:8095/shangbiao_sale/select?sort=id+desc&fq=&wt=json&json.nl=map&q=s ...

  8. Java语法笔记

    目录 知识点 不支持 恶心事 与C#的区别 组件 学习资料 母版页 知识点 类 静态方法,即可以在类上被调用,也可以在实例对象上被调用. Java类 先执行静态构造函数,再执行静态方法或静态字段,所以 ...

  9. Java基本语法笔记

    1. 基本格式: public class HelloWprdApp { public static void main(String[] args) {        // TODO Auto-ge ...

  10. Solr常用查询语法笔记

    1.常用查询 q - 查询字符串,这个是必须的.如果查询所有*:* ,根据指定字段查询(Name:张三 AND Address:北京) fq - (filter query)过虑查询,作用:在q查询符 ...

随机推荐

  1. poj 2485 (kruskal算法)

    /*kruskal算法*/ #include <iostream> //#include <fstream> #include <algorithm> using ...

  2. java输出万年历

    import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class M ...

  3. Elasticsearch中doc_value的认识

    前言:本文的目的是为后续磁盘空间利用优化做铺垫.主要知识点来源于官网文档 一.doc_value是什么 绝大多数的fields在默认情况下是indexed,因此字段数据是可被搜索的.倒排索引中按照一定 ...

  4. Python爬虫小白入门(五)PhatomJS+Selenium第二篇

    一.前言 前文介绍了PhatomJS 和Selenium 的用法,工具准备完毕,我们来看看如何使用它们来改造我们之前写的小爬虫. 我们的目的是模拟页面下拉到底部,然后页面会刷出新的内容,每次会加载10 ...

  5. PHP常用之封装分页工具类

    分页基本上是每个项目都会使用到的,所以呢,把它封装成一个工具类,以后直接调用就可以了(虽然TP框架的灰常强大,但是自己封一个也未尝不可.),这样既省时又省力还赚'工分'. 我封的这个分页工具类还比较完 ...

  6. CSS之纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)

    图形包括基本的矩形.圆形.椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八卦等.当然有一些需要用到CSS3的属性,所以在你打开这篇文章的时候,我希望你用的是firefox或者chrome, ...

  7. 你确实应该学习并使用的 10 个 C# 特性

    1) async / await 使用 async / await 模式,可以在执行代码块操作的时候不会阻塞 UI 或者当前的线程.即使该操作被某些执行动作延迟了(比如一个 web 请求),async ...

  8. 用Canvas,画中国国旗(Canvas基本知识点)

    .getContext("2d")=======>获取绘图接口 //2d .beginPath()========>创建绘图路径开始点 .moveTo(x,y)==== ...

  9. 利用fiddler将本地网页放到某个域下

    注: 1)在学习慕课网课程<搜索框制作>中遇到如题困难,查找资料后解决,做此记录.课程网址http://www.imooc.com/video/263. 2)建议同时去学习慕课网课程< ...

  10. hdu1037

    #include <iostream> #include <cstdio> using namespace std; int main() { int a,b,c; while ...