快應用 template模板

2020-08-08 17:26 更新

類似HTML的標簽語言,結合基礎組件、自定義組件、事件,構建出頁面的結構

注意:模板中只能有1個根節(jié)點,如:div;請不要在<template>下存在多個根節(jié)點,也不要使用block作為根節(jié)點

數(shù)據(jù)綁定

<template>

  <text>{{message}}</text>

</template>

<script>

  export default {

    // 頁面級組件的數(shù)據(jù)模型,影響傳入數(shù)據(jù)的覆蓋機制:private內(nèi)定義的屬性不允許被覆蓋

    private: {

      message: 'Hello'

    }

  }

</script>

事件綁定

<template>

  <div>

    <!-- 正常格式 -->

    <text onclick="press"></text>

    <!-- 縮寫 -->

    <text @click="press"></text>

  </div>

</template>

<script>

  export default {

    press(e) {

      this.title = 'Hello'

    }

  }

</script>

事件回調支持的寫法(其中{{}}可以省略):

"fn":fn 為事件回調函數(shù)名(在<script>中有對應的函數(shù)實現(xiàn))

"fn(a,b)":函數(shù)參數(shù)例如 a ,b 可以是常量,或者是在<script>的data中定義的變量(前面不用寫this.)

"a+b":表達式,其中 a , b 數(shù)據(jù)類型與上面相同

回調函數(shù)被調用時,會在參數(shù)列表末尾自動添加一個 evt 參數(shù),通過 evt 參數(shù)訪問回調事件相關上下文數(shù)據(jù)(數(shù)據(jù)內(nèi)容具體參看組件回調事件說明),例如點擊事件的點擊位置 x,y

列表渲染

<template>
    <div class="doc-page">
        <div for="{{list}}" tid="uniqueId">
            <text>{{$idx}}</text>
            <text>{{$item.uniqueId}}</text>
        </div>
    </div>
</template>

<script>
  module.exports = {
    data: {
      list: [{ uniqueId: 1 }, { uniqueId: 2 }]
    }
  }
</script>

for指令根據(jù)源數(shù)據(jù)數(shù)組渲染列表,支持的寫法如下(其中{{}}可以省略):

  • for="{{list}}":list為源數(shù)據(jù)數(shù)組,默認的數(shù)組元素名為$item
  • for="{{value in list}}":value為自定義的數(shù)組元素名,默認的數(shù)組元素索引名為$idx
  • for="{{(index, value) in list}}":index為自定義的數(shù)組元素索引名,value為自定義的數(shù)組元素名

for指令tid屬性用于指定數(shù)組元素的唯一Id,若未指定,默認使用數(shù)組索引($idx)作為唯一Id。tid屬性的作用在于元素節(jié)點重用,優(yōu)化for循環(huán)的重繪效率

示例代碼中,tid="uniqueId"表示使用數(shù)組list的數(shù)組元素$item.uniqueId作為數(shù)組元素的唯一Id

使用tid屬性時應注意:

  • tid屬性指定的數(shù)據(jù)屬性必須存在,否則可能導致運行異常
  • tid屬性指定的數(shù)據(jù)屬性要保證唯一,否則可能導致性能問題
  • tid屬性目前不支持表達式。

條件渲染

分為2種:if/elif/else 和 show。它們的區(qū)別在于:if 為 false 時,組件會從 VDOM 中移除,而 show 僅僅是渲染時不可見,組件依然存在于 VDOM 中;

if/elif/else 節(jié)點必須是相鄰的兄弟節(jié)點,否則無法通過編譯

<template>

  <div>

    <text if="{{display}}">Hello-1</text>

    <text elif="{{display}}">Hello-2</text>

    <text else>Hello-3</text>

  </div>

</template>

<script>

  export default {

    // 頁面級組件的數(shù)據(jù)模型,影響傳入數(shù)據(jù)的覆蓋機制:private內(nèi)定義的屬性不允許被覆蓋

    private: {

      display: false

    }

  }

</script>

show 等同于 visible=none, 主要用于在原生組件上聲明;

show 指令開始支持在自定義組件上進行聲明,當這樣使用時,等同于在該自定義子組件的根節(jié)點上使用 show 指令;

對于之前版本,自定義組件不支持 show 指令的需求,可以通過 props 傳入?yún)?shù),在自己內(nèi)部使用 show 來控制是否可見;

<template>

  <text show="{{visible}}">Hello</text>

</template>

<script>

  export default {

    // 頁面級組件的數(shù)據(jù)模型,影響傳入數(shù)據(jù)的覆蓋機制:private內(nèi)定義的屬性不允許被覆蓋

    private: {

      visible: false

    }

  }

</script>

邏輯控制塊

可以使用<block>實現(xiàn)更為靈活的循環(huán)/條件渲染; 注意<block>目前只支持 for 和 if/elif/else 屬性,如果沒有指定任何屬性,<block>則在構建時被當作“透明”節(jié)點對待,其子節(jié)點被添加到<block>的父節(jié)點上

<template>

  <list>

    <block for="cities">

      <list-item type="city">

        <text>{{$item.name}}</text>

      </list-item>

      <list-item type="spot" for="$item.spots">

        <text>{{$item.address}}</text>

      </list-item>

    </block>

  </list>

</template>

<script>

  export default {

    // 頁面級組件的數(shù)據(jù)模型,影響傳入數(shù)據(jù)的覆蓋機制:private內(nèi)定義的屬性不允許被覆蓋

    private: {

      cities: [

        {

          name: 'beijing',

          spots: [

            {

              address: 'XXX'

            }

          ]

        },

        {

          name: 'shanghai',

          spots: [

            {

              address: 'XXX'

            },

            {

              address: 'XXX'

            }

          ]

        }

      ]

    }

  }

</script>

引入自定義組件

<import name="comp" src="./comp"></import>

<template>

  <div>

    <comp

      prop1="xxxx"

      onevent1="bindParentVmMethod1"

      @event-type1="bindParentVmMethod1"

    ></comp>

  </div>

</template>

如果沒有設置 name 屬性,則默認采用 src 的文件名作為組件名

src 屬性指定組件 ux 文件位置,可以省略 .ux 后綴

注意:

  • 組件名不區(qū)分大小寫,默認統(tǒng)一采用小寫
  • 通過(on|@)event1語法綁定自定義子組件的event1事件,觸發(fā)事件childVm.$emit('event1', { params: '傳遞參數(shù)' })時執(zhí)行父組件的方法:bindParentVmMethod1
  • 標簽上聲明事件名稱采用-連接,不要使用駝峰式,來做響應與方法的關聯(lián),即:使用event-type1表示綁定eventType1事件

插入自定義組件

組件中通過標簽來定義子組件插入位置,例如

組件 com-a 的模板定義為:

<template>
    <div>
      <text>header</text>
      <slot></slot>
      <text>footer</text>
    <div>
</template>

在頁面使用組件 comA ,定義如下:

<import name="comp-a" src="./comp-a"></import>
<template>
    <com-a>
      <text>body</text>
    </com-a>
</template>

則在頁面渲染時,組件 comA 變?yōu)椋?/p>

<div>
  <text>header</text>
  <text>body</text>
  <text>footer</text>
</div>

動態(tài)組件

動態(tài)組件允許開發(fā)者靈活控制模板中要渲染的是哪個自定義組件;

在不支持該功能時,開發(fā)者往往通過if/elif/else指令來解決需求;

如下面代碼所示,通過component邏輯組件與對應的is屬性來判斷運行時到底渲染哪個組件;

<import src="./part1.ux" name="part1"></import>
<import src="./part2.ux" name="part2"></import>
<import src="./part3.ux" name="part3"></import>

<template>
  <div>
    <component is="{{'part' + index}}"></component>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        index: 1
      }
    },
    onReady () {
      // 3秒后渲染其他組件
      setTimeout(() => {
        this.index = 3
      }, 3e3)
    }
  }
</script>

過濾器

在 hap-toolkit 0.4.0 之后,允許自定義過濾器,可用于文本格式化。

過濾器是一個函數(shù),在頁面導出的對象中定義,如下面的 capitalize:

<script>
  export default {
    private: {
      message: 'hello'
    },
    capitalize(value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
</script>

使用過濾器時,應該添加到表達式的尾部,由管道符號指示。 和 vue 過濾器類似,其形式如下:

{{ message | capitalize }}

過濾器函數(shù)接收表達式的值作為第一個參數(shù)。在上述例子中,capitalize 過濾器函數(shù)將會收到 message 的值作為第一個參數(shù)。

過濾器可以串聯(lián):

{{ message | filterA | filterB }}

在這個例子中,filterA 被定義為接收單個參數(shù)的過濾器函數(shù),表達式 message 的值將作為參數(shù)傳入到函數(shù)中。然后繼續(xù)調用同樣被定義為接收單個參數(shù)的過濾器函數(shù) filterB,將 filterA 的結果傳遞到 filterB 中。

過濾器可以接收參數(shù):

{{ message | filterA('arg1', arg2) }}

這里,filterA 被定義為接收三個參數(shù)的過濾器函數(shù)。其中 message 的值作為第一個參數(shù),普通字符串 'arg1' 作為第二個參數(shù),表達式 arg2 的值作為第三個參數(shù)。

完整示例如下:

<template>
  <div>
    <text>{{ message | capitalize }}</text>
  </div>
</template>

<script>
  export default {
    private: {
      message: 'hello'
    },
    capitalize(value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
</script>


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號