用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

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

Rolan 2019-11-22 00:41

綁定事件的方法:1.bindtab和catchtab,catchtab可以阻止事件冒泡 view bindtap='onClick'/view view catchtap='onClick'/view 2.互斥事件綁定 mut-bind一個 mut-bind 觸發后,如果事件冒泡到其他節點上,其他節點上 ...

綁定事件的方法:

1.bindtab和catchtab,catchtab可以阻止事件冒泡


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

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

2.互斥事件綁定 mut-bind

一個 mut-bind 觸發后,如果事件冒泡到其他節點上,其他節點上的 mut-bind 綁定函數不會被觸發,但 bind 綁定函數和 catch 綁定函數依舊會被觸發。

在想要規定冒泡區間時可以用到。


<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 很相似,主要區別在于:

1.mark可以冒泡,如果存在同名的 mark ,父節點的 mark 會被子節點覆蓋。

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 方法。


// 組件 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

}

}

})

組件中的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 ,用于支持自定義組件擴展。

鮮花
鮮花
雞蛋
雞蛋
分享至 : QQ空間
收藏
原作者: yuezhongbao 來自: segmentfault
致青春APP 盈策略 球探篮球比分即时比分 久联优配 申万宏源配资 七星彩 配资利息一般是多少 达慧投资 金福配资 美国股票指数道琼斯 股票配资平台哪个安全c贵丰配资 即时网球比分直播 竞彩足球即时指数 河南22选5 任选9场 北单比分开奖赔率查询 球探体育比分老版本