在上一篇內容中主要總結了如何擴充套件小程式中的Page與Component函式,在開發過程中減少包的引入,這一篇則深入總結小程式自定義元件Component函式還有哪些可以進一步擴充套件的地方【demo地址】。
優化點:
- 優化元件定義預設值時宣告的寫法
- 自定義watch函式監聽全部引數變化
編寫小程式自定義元件時 你是否是這樣?
Component({
properties: {
num: {
type: Number,
value: 2
},
name: {
type: String,
value: "abcdef..."
},
test: Object // 即使沒有預設值也要寫上資料型別
},
methods: {
//...
}
})
複製程式碼
Component({
props: {
num: 2,
name: 'abcdef...',
test: {}
},
methods: {
//...
}
})
複製程式碼
開始改造properties:
既然我們已經可以重寫Component函式了,那就有辦法把這個資料【轉換】成我們要的那種結構格式,開啟Init.js Component函式部分
實現的步驟大概是:取到引數內名為props的物件 -> 獲取每一個資料型別 -> 還原成小程式原來的資料格式 -> 重新賦值給properties
// 優化 properties 傳入方式
let originComponent = Component;
Component = (opt) => {
let { props = {} } = opt;
let properties = {};
// 獲取自定義關鍵字【props】中的每一項
Object.keys(props).forEach(item => {
// 重新還原成原有資料格式
properties[item] = {
type: getValueType(props[item]), // 獲取資料格式
value: props[item]
}
});
opt.properties = properties; // 還給properties...
//...
return originComponent(opt)
}
/**
* 獲取資料型別
* @param value
* @returns {*}
*/
function getValueType(value) {
if (typeof value === 'number') return Number;
if (typeof value === 'string') return String;
if (typeof value === 'boolean') return Boolean;
if (value instanceof Object && !value instanceof Array) return Object;
if (value instanceof Array) return Array;
return null;
}
複製程式碼
元件宣告預設資料格式的修改就弄好了,其實這個東西並沒有對開發上起到多麼明顯的優化,無非就是少寫幾個字而已,但是以此demo 還可以擴充套件出更多功能。
監聽元件傳入引數變化
小程式自定義元件的傳入資料上可以宣告observer監聽器屬性,用來監聽資料變化⤵️
Component({
properties: {
num: {
type: Number,
value: 2,
observer (newVal, oldVal, changedPath) {
//...
}
},
},
methods: {
//...
}
})
複製程式碼
其中observer接收的引數分別是newVal[改變的引數]、oldVal[改變之前的引數]、changedPath[具體改變的引數的key]
預設要監聽某個引數的時候,都是需要寫在具體引數的物件內的,並且每個要監聽的資料都要宣告observer函式,通過改造後 可以統一監聽資料變動⤵️
Component({
props: {
num: 2,
name: 'abcdefg....',
},
methods: {
// 自定義新增的監聽方法
$watch(newVal, oldVal, changedPath) {
if (changedPath == 'num' && newVal == 5) {
this.data.name = 'five';
return this.triggerEvent("isFive")
}
//...
}
}
})
複製程式碼
相比每個引數都要監聽 這種寫法可以減少程式碼。
實現$watch:
實現步驟:獲取自定義props物件 -> 還原成properties格式 -> 每一個資料內都新增observer函式 -> 函式在觸發時 呼叫自身$watch函式
// 優化 properties 傳入方式
let originComponent = Component;
Component = (opt) => {
let { props = {} } = opt;
let properties = {};
// 獲取自定義關鍵字【props】中的每一項
Object.keys(props).forEach(item => {
// 重新還原成原有資料格式
properties[item] = {
type: _util.getValueType(props[item]),
value: props[item],
// 每一個資料都新增observer方法監聽
observer: function (newVal, oldVal, changedPath) {
const changeEvent = {
event: item,
newVal, oldVal, changedPath
};
// 傳入屬性可通過元件內定義的$watch方法統一監聽變化
this.$watch && this.$watch(changeEvent);
}
}
});
opt.properties = properties; // 還給properties...
//...
return originComponent(opt)
}
/**
* 獲取資料型別
* @param value
* @returns {*}
*/
function getValueType(value) {
if (typeof value === 'number') return Number;
if (typeof value === 'string') return String;
if (typeof value === 'boolean') return Boolean;
if (value instanceof Object && !value instanceof Array) return Object;
if (value instanceof Array) return Array;
return null;
}
複製程式碼
這樣就可以實現$watch方法啦!【demo地址】