微信-小程序開發基礎知識筆記

綁定事件的方法:

1.bindtab和catchtab,catchtab能夠阻止事件冒泡html

<view bindtap='onClick'></view>

<view catchtap='onClick'></view>

2.互斥事件綁定 mut-bindreact

一個 mut-bind 觸發後,若是事件冒泡到其餘節點上,其餘節點上的 mut-bind 綁定函數不會被觸發,但 bind 綁定函數和 catch 綁定函數依舊會被觸發。json

在想要規定冒泡區間時能夠用到。小程序

<view mut-bind:tap='onClick'></view>
在基礎庫版本 2.7.1 以上,可使用 mark 來識別具體觸發事件的 target 節點
<view mark:myMark="last" bindtap="bindViewTap">

<button mark:anotherMark="leaf" bindtap="bindButtonTap">按鈕</button>

</view>

在上述 WXML 中,若是按鈕被點擊,將觸發 bindViewTap 和 bindButtonTap 兩個事件,事件攜帶的 event.mark 將包含 myMark 和 anotherMark 兩項。緩存

Page({

bindViewTap: function(e) {

e.mark.myMark === "last" // true

e.mark.anotherMark === "leaf" // true

}

})

mark 和 dataset 很類似,主要區別在於:app

1.mark能夠冒泡,若是存在同名的 mark ,父節點的 mark 會被子節點覆蓋。xss

2.在自定義組件中接收事件時, mark 不包含自定義組件外的節點的 mark。函數

3.不一樣於 dataset ,節點的 mark 不會作連字符和大小寫轉換。性能

.wxs文件的應用

我的理解 .wxs文件就至關於cocos的prefab。執行起來比js性能要快。可是wxs是一門語言,平行於JavaScript。動畫

wxs基礎語法

有頻繁用戶交互的效果在小程序上表現是比較卡頓的,這時建議使用wxs,爲何?

由於小程序分爲視圖層和邏輯層,好比須要拖動的功能,touchmove事件從視圖層拋到邏輯層,邏輯層通過處理,經過this.setData到視圖層。

1. 一次 touchmove 的響應須要通過 2 次的邏輯層和渲染層的通訊以及一次渲染,通訊的耗時比較大。

2. 此外 setData 渲染也會阻塞其它腳本執行,致使了整個用戶交互的動畫過程會有延遲。

WXS 函數的除了純邏輯的運算,還能夠經過封裝好的ComponentDescriptor 實例來訪問以及設置組件的 class 和樣式,對於交互動畫,設置 style 和 class 很方便。

代碼示例:

var wxsFunction = function(event, ownerInstance) {

var instance = ownerInstance.selectComponent('.classSelector') // 返回組件的實例

instance.setStyle({

"font-size": "14px" // 支持rpx

})

instance.getDataset()

instance.setClass(className)

// ...

return false // 不往上冒泡,至關於調用了同時調用了stopPropagation和preventDefault

}
自定義組件

上邊在分析複雜交互時咱們知道,頻繁的調用this.setData會使頁面卡頓,甚至致使小程序僵死。那麼不想寫或者說不會寫wxs的開發者該怎麼辦呢?

此時能夠經過將頁面的 setData 改成 自定義組件 中的 setData 來提高性能。

緣由:自定義組件中的setData不會進行深複製。(深複製會在這個值被組件間傳遞時才發生)

自定義組件的規範

1.在組件wxss中不該使用ID選擇器、屬性選擇器和標籤名選擇器,就只使用class選擇器準沒錯。

2.在自定義組件的 js 文件中,須要使用 Component() 來註冊組件。

3.使用已註冊的自定義組件前,首先要在頁面的 json 文件中進行引用聲明。

4.自定義組件和頁面所在項目根目錄名不能以「wx-」爲前綴,不然會報錯。

5.<slot></slot>至關於react的this.props.children。

<!-- component-tag-name組件 -->

<view class="wrapper">

<view>這裏是組件的內部節點</view>

<slot></slot>

</view>
<!-- 引用組件的頁面模板 -->

<view>

<component-tag-name>

<!-- 這部份內容將被放置在組件 <slot> 的位置上 -->

<view>這裏是插入到組件slot中的內容</view>

</component-tag-name>

</view>

6.默認狀況下,一個組件的wxml中只能有一個slot。須要使用多slot時,能夠在組件js中聲明啓用。

Component({

options: {

multipleSlots: true // 在組件定義時的選項中啓用多slot支持

},

properties: { /\* ... \*/ },

methods: { /\* ... \*/ }

})

此時,能夠在這個組件的wxml中使用多個slot,以不一樣的 name 來區分。

<!-- 組件模板 -->

<view class="wrapper">

<slot name="before"></slot>

<view>這裏是組件的內部細節</view>

<slot name="after"></slot>

</view>

使用時,用 slot 屬性來將節點插入到不一樣的slot上。

<!-- 引用組件的頁面模板 -->

<view>

<component-tag-name>

<!-- 這部份內容將被放置在組件 <slot name="before"> 的位置上 -->

<view slot="before">這裏是插入到組件slot name="before"中的內容</view>

<!-- 這部份內容將被放置在組件 <slot name="after"> 的位置上 -->

<view slot="after">這裏是插入到組件slot name="after"中的內容</view>

</component-tag-name>

</view>

7.設置自定義組件的捕獲和冒泡機制須要使用 triggerEvent 方法。

20191118201734.jpg

// 組件 my-component.js

Component({

methods: {

onTap: function(){

this.triggerEvent('customevent', {}, { bubbles: true, composed: true })

}

}

})
組件中的behaviors

我的理解:多個頁面可能會共用一個功能,這個功能抽象後稱爲組件。

多個組件共用一個方法或者多個方法,這類方法的集合稱爲behaviors。就tm理解成高階組件就完了。

組件間關係relations

官方說:有時須要實現這樣的組件:

<custom-ul>

<custom-li> item 1 </custom-li>

<custom-li> item 2 </custom-li>

</custom-ul>

說custom-ul 和 custom-li 都是自定義組件,它們有相互間的關係,相互間的通訊每每比較複雜。具體怎麼個複雜須要單獨拎出來一個ralations屬性來處理,咱也不知道。

使用方法:

// path/to/custom-ul.js

Component({

relations: {

'./custom-li': {

type: 'child', // 關聯的目標節點應爲子節點

linked: function(target) {

// 每次有custom-li被插入時執行,target是該節點實例對象,觸發在該節點attached生命週期以後

},

linkChanged: function(target) {

// 每次有custom-li被移動後執行,target是該節點實例對象,觸發在該節點moved生命週期以後

},

unlinked: function(target) {

// 每次有custom-li被移除時執行,target是該節點實例對象,觸發在該節點detached生命週期以後

}

}

},
// path/to/custom-li.js

Component({

relations: {

'./custom-ul': {

type: 'parent', // 關聯的目標節點應爲父節點

linked: function(target) {

// 每次被插入到custom-ul時執行,target是custom-ul節點實例對象,觸發在attached生命週期以後

},

linkChanged: function(target) {

// 每次被移動後執行,target是custom-ul節點實例對象,觸發在moved生命週期以後

},

unlinked: function(target) {

// 每次被移除時執行,target是custom-ul節點實例對象,觸發在detached生命週期以後

}

}

}

})

注意:必須在兩個組件定義中都加入relations定義,不然不會生效。

還有一種狀況,若是你兩個自定義組件都用了相同的behaviors,你可使用這個behavior來代替組件路徑做爲關聯的目標節點。

// path/to/custom-form.js

var customFormControls = require('./custom-form-controls')

Component({

relations: {

'customFormControls': {

type: 'descendant', // 關聯的目標節點應爲子孫節點

target: customFormControls

}

}

})

20191119114731.jpg

組件中的observers

官方定義他叫數據監聽器,呵呵。

使用方法:

Component({

attached: function() {

this.setData({

numberA: 1,

numberB: 2,

})

},

observers: {

'numberA, numberB': function(numberA, numberB) {

// 在 numberA 或者 numberB 被設置時,執行這個函數

this.setData({

sum: numberA + numberB

})

}

}

})

若是須要監聽全部子數據字段的變化,可使用通配符

Component({

observers: {

'some.field.**': function(field) {

// 使用 setData 設置 this.data.some.field 自己或其下任何子數據字段時觸發

// (除此之外,使用 setData 設置 this.data.some 也會觸發)

field === this.data.some.field

},

},

attached: function() {

// 這樣會觸發上面的 observer

this.setData({

'some.field': { /* ... */ }

})

// 這樣也會觸發上面的 observer

this.setData({

'some.field.xxx': { /* ... */ }

})

// 這樣仍是會觸發上面的 observer

this.setData({

'some': { /* ... */ }

})

}

})

特別地,僅使用通配符 能夠監聽所有 setData 。**

純數據字段

就是局部變量,不參與渲染,也不會傳遞。

官方說這樣聲明後再用能提升性能,要不我纔不用。

使用方式:

Component({

options: {

pureDataPattern: /^_/ // 指定全部 _ 開頭的數據字段爲純數據字段

},

data: {

a: true, // 普通數據字段

_b: true, // 純數據字段

},

methods: {

myMethod() {

this.data._b // 純數據字段能夠在 this.data 中獲取

this.setData({

c: true, // 普通數據字段

_d: true, // 純數據字段

})

}

}

})
抽象節點

又一個新名詞,呵呵呵。

說白了就是有一個父容器組件A,由於條件不一樣有可能A中會渲染組件B,也可能渲染組件C。舉個例子,當頁面須要單選和多選組件的時候,方法1是按條件引用兩個封裝好的組件(<單選/>,</多選>),方法2是你也能夠只引用一個組件<啦啦啦/>,只不過這個<啦啦啦/>組件去幫你按需渲染<單選/>或者<多選/>。

須要在父容器組件A的.json文件聲明:

{

"componentGenerics": {

"selectable": true

}

}

在使用組件時,必須指定父組件具體是渲染哪一個子組件:

<啦啦啦 generic:selectable="單選" />

<啦啦啦 generic:selectable="多選" />

在頁面的.json文件<啦啦啦/>,<單選/>,<多選/>都要引用。代碼

//page下頁面的.json文件中

{

"usingComponents": {

"啦啦啦": "path/*/*",

"多選": "*/checkbox",

"單選": "*/radio"

}

}

固然,你也能夠在容器組件.json中指定默認用哪一個組件:

{

"componentGenerics": {

"selectable": {

"default": "*/checkbox"// 多選

}

}

}
計算屬性

今天真是開眼了,學到了這麼多新詞彙。。

( 計算屬性的做用):是爲了解決HTML代碼中複雜的js代碼(HTML代碼中能夠嵌套js代碼),把複雜的js代碼經過計算屬性來解決

這是計算屬性的應用??? 聽着詞這麼厲害幹這事真是大才小用了。

計算屬性會使用緩存機制,若是這個數據的值沒有改變,則計算屬性將不會調用方法

這點應該是它實際有價值的地方。

實現原理很簡單,就是對已有的 setData 進行二次封裝,在每次 setData 的時候計算出 computed 裏各字段的值,這期間能夠增長緩存機制,屬性值沒有變化的複用。

自定義組件拓展

在react中想拓展一個組件怎麼辦,會用高階組件。

小程序中,天然是使用behaviors。

// behavior.js

module.exports = Behavior({

definitionFilter(defFields) {

defFields.data.from = 'behavior'

},

})

// component.js

Component({

data: {

from: 'component'

},

behaviors: [require('behavior.js')],

ready() {

console.log(this.data.from) // 此處會發現輸出 behavior 而不是 component

}

})

Behavior() 構造器提供了新的定義段 definitionFilter ,用於支持自定義組件擴展。

相關文章
相關標籤/搜索