Weex-語法筆記 一

數據綁定javascript

Weex使用 mustache 的語法 ({{...}}) 來對 <template> 中的模板和 <script> 裏的數據進行綁定. 一旦數據額模板綁定了, 數據上的修改會實時的在模板內容中生效。html

 

樣式: style classjava

組件的樣式可以經過style特性進行綁定:node

<template>android

  <div>ios

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

  </div>github

</template>瀏覽器

 

<script>weex

  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 }

相關文章
相關標籤/搜索