小順序自定義組件開闢範例
一個小順序組件由4個文件構成,分別是wxml
、wxss
、json
、js
,本範例只關注組件的js
,別的自行檢察官方文檔。
在自定義組件的 js
文件中,需要運用 Component()
來註冊組件,Component是一個組織器,可用於定義組件,挪用Component組織器時能夠指定組件的屬性、數據、要領等。
Component
的變量能夠分為以下2種範例:
properties
:組件外部經由歷程組件屬性的體式格局傳入內部的數據。- 可用於wxml襯着
不能做會修正數據的運算操縱,假如必需要修正數據,能夠先把數據賦值給組件的
data
,比方:this.data.a = this.properties.a
,再去做運算操縱,有以下兩種狀況:- 假如
this.properties.a
的數據是基本數據範例,則直接賦值 - 假如
this.properties.a
的數據是援用數據範例,則需要深拷貝一個新的數據以後,再賦值
- 假如
data
:組件內部聲明的數據- 重要用於wxml襯着
- 能夠做任何的運算符操縱
Component
的函數能夠分為以下幾種範例:
-
life-cycle-function
:組件性命周期函數 -
event-function
:在組件的methods
下自定義的事宜相應函數,與wxml的事宜綁定一一對應 -
commen-function
:在組件的methods
下自定義的大眾函數,供life-cycle-function
與event-function
挪用 -
request-function
:在組件的methods
下自定義的異步要求數據的函數
在現實的代碼中,我們應用解釋把變量和函數分為以上定義的幾種範例。
下面以小順序的語音音訊組件為例:
文件途徑:components/voice-message
<view class="voice-message {{(type === 'comment') ? 'comment' : ''}}" catchtap="togglePlay">
<!-- 省略別的代碼 -->
</view>
import { isCorrectVal } from '../../utils/index';
const app = getApp();
Component({
properties: {
// work:功課的語音 comment:批評的語音
type: {
type: String,
value: 'work'
},
// 語音的地點
voiceUrl: {
type: String,
value: ''
},
// 音頻的長度
voiceLength: {
type: Number,
value: 0
}
},
data: {
unsubscribe: function() {},
model: {
loading: false,
render: false,
id: 0,
voiceLength: 0,
innerAudioContext: null,
playing: false,
trumpetStatus: [false, false, true],
btnLength: '0'
}
},
/**
* life-cycle-function
* @description 初始化組件
*/
attached: function() {
this.data.unsubscribe = app.soundScheduler.subscribe(
'beforePlay',
() => {
this.data.model.innerAudioContext.stop();
}
);
if (!isCorrectVal(this.properties.voiceUrl)) {
throw new Error('音頻地點毛病');
}
/* 盤算音頻按鈕長度 */
let base = 40; // 10s內基本長度
let step = 20; // 每10s增添的長度
let stepNum = 0;
let length = 40; // 按鈕初始長度
if (this.properties.type === 'comment') {
base = 30;
step = 15;
length = 30;
}
if (this.properties.voiceLength > 10) {
stepNum = Math.ceil((this.properties.voiceLength - 10) / 10);
}
length = base + step * stepNum;
this.setData({
'model.btnLength': length,
'model.voiceLength':
this.properties.voiceLength >= 2
? this.properties.voiceLength
: 2
});
this.data.model.innerAudioContext = wx.createInnerAudioContext();
this.data.model.innerAudioContext.obeyMuteSwitch = false;
this.data.model.innerAudioContext.src = this.properties.voiceUrl;
this.data.model.innerAudioContext.onPlay(() => {
this.onPlay();
});
this.data.model.innerAudioContext.onStop(res => {
this.onStop();
});
this.data.model.innerAudioContext.onEnded(res => {
this.onStop();
});
this.data.model.innerAudioContext.onError(res => {
this.onError(res);
});
},
methods: {
/**
* event-function
* @description 切換音頻播放狀況(播放/住手)
*/
togglePlay: function() {
if (this.data.model.loading) return;
if (this.data.model.playing) {
this.data.model.innerAudioContext.stop();
} else {
this.setData(
{
'model.loading': true
},
() => {
app.soundScheduler.dispatch('beforePlay');
app.videoContext.pause();
this.data.model.innerAudioContext.play();
setTimeout(() => {
if (this.data.model.loading) {
this.setData({
'model.loading': false
});
}
}, 3000);
}
);
}
},
/**
* common-function
* @description 音頻最先播放觸發時的處置懲罰函數
*/
onPlay: function() {
this.setData(
{
'model.loading': false
},
() => {
this.running();
}
);
},
/**
* common-function
* @description 音頻住手播放或許播放結束時的處置懲罰函數
*/
onStop: function() {
this.stop();
},
/**
* common-function
* @description 音頻播放毛病時的處置懲罰函數
*/
onError: function(res) {
console.log(res);
this.setData(
{
'model.loading': false
},
() => {
this.stop();
}
);
},
/**
* common-function
* @description 啟動音頻小喇叭動畫
*/
running: function() {
let vm = this;
vm.data.model.playing = true;
let num = 1;
let idx = 1;
let timer = null;
function animation() {
if (!vm.data.model.playing) {
clearTimeout(timer);
vm.setData({
'model.trumpetStatus': [false, false, true]
});
return;
}
switch (idx) {
case 1:
vm.setData({
'model.trumpetStatus': [true, false, false]
});
break;
case 2:
vm.setData({
'model.trumpetStatus': [false, true, false]
});
break;
case 3:
vm.setData({
'model.trumpetStatus': [false, false, true]
});
break;
}
++idx;
if (idx === 4) {
idx = 1;
}
++num;
timer = setTimeout(animation, 600);
}
timer = setTimeout(animation, 600);
},
/**
* common-function
* @description 住手音頻小喇叭動畫
*/
stop: function() {
this.data.model.playing = false;
}
},
/**
* life-cycle-function
* @description 卸載組件
*/
detached: function() {
this.data.model.innerAudioContext.stop();
this.data.unsubscribe();
},
});
假如你已看完了代碼,那末對這個組件的 代碼實行歷程 是不是內心已有數?
這個組件的代碼實行歷程是如許的:
1. 在性命周期鈎子函數attached中初始化組件
2. 組件掛載並襯着完成,抵達可相應用戶操縱的狀況(這個步驟由小順序自動實行,無需寫分外的代碼)
3. 相應用戶操縱
- 用戶點擊語音音訊,假如語音沒在播放,則播放語音
- 用戶點擊語音音訊,假如語音正在播放,則住手播放
4. 卸載組件
假如內心還沒數,那把除了life-cycle-function
和events-function
的以外的代碼都疏忽掉,再看看組件性命周期鈎子函數和用戶交互事宜相應函數的代碼與解釋呢?