微信小程序behavior實(shí)現(xiàn)多繼承,observer,導(dǎo)航欄,日期,禁用,棧溢出【詩書畫唱】
目錄:
例子1:把寫死的期刊號和當(dāng)前日期寫成活的,寫成可實(shí)時更新日期等等

給epsoide聲明一個期刊號index屬性,而日期的內(nèi)容不必依賴父子組件傳值,因?yàn)槿掌谑枪灿玫牟糠?/span>
為什么要聲明期刊號index為String?因?yàn)槲覀円M(jìn)行判斷,如果期刊號小于10,就要在數(shù)字前面加個0
只要組件的屬性的值改變,就會觸發(fā)observer對應(yīng)的函數(shù)(下面的圖示中一開始index是空值,后面index變成8的值,所以會觸發(fā)observer對應(yīng)的函數(shù))
observer
如果你做了讓數(shù)據(jù)變化的邏輯處理,想界面實(shí)時更新數(shù)據(jù),可以使用this.setData{_XXX:YYY}之類的方法
一些要調(diào)用的變量,如果是要從別的地方傳值獲取就寫properties里面,如果是直接獲取,沒必要從別的地方傳值獲取,就寫data中就可以。
對于字符串的變量,和properties中可以聲明type為String不一樣,在data中不可以聲明為String,而是按照下圖的設(shè)置來設(shè)置初始值為空字符串
常常查看微信小程序官網(wǎng)的API文檔,同時方法等等是會更新的,有些方法可能會變,比如生命周期函數(shù),所以要常常查看最新的API文檔等等,如果不知道代碼寫哪里,很多時候可以寫生命周期函數(shù)里面
例子2:實(shí)現(xiàn)導(dǎo)航欄

下面的給組件定義的屬性賦值是和properties搭配使用,來達(dá)到傳值的效果的
之后的話,我就是給導(dǎo)航欄設(shè)置樣式,進(jìn)行彈性盒子布局
例子3:實(shí)現(xiàn)導(dǎo)航欄的切換圖片效果,左翻頁和右翻頁分別在第一頁和最后一頁的綁定了事件的用于切換的圖標(biāo)(圖片)變灰色,其余情況都是黑色,實(shí)現(xiàn)禁用效果

下面是給導(dǎo)航欄navi組件的左翻頁和右翻頁的圖標(biāo)綁定事件
用控制臺打印語句測試,綁定的事件是否有效
例子4:為“切換期刊的同時,期刊界面變成對應(yīng)的內(nèi)容(實(shí)現(xiàn)music,movie,sentence組件)的功能”做準(zhǔn)備,behavior實(shí)現(xiàn)多繼承,通過調(diào)用behavior,讓很多組件都擁有behavior中的屬性,減少聲明屬性的代碼

Behavior(行為)實(shí)現(xiàn)多繼承,Behavior可以實(shí)現(xiàn)類似于接口的效果,可以讓很多組件都有通過調(diào)用聲明了屬性的Behavior相關(guān)的文件,來讓很多組件擁有Behavior相關(guān)的文件中聲明了的屬性,可以減少聲明屬性的代碼
例子5:實(shí)現(xiàn)例子1到例子4效果的代碼
Q&A:個人做項(xiàng)目時遇到的問題和我是如何解決遇到的問題的
Q:如何解決stack棧溢出等的問題
講義

例子1:把寫死的期刊號和當(dāng)前日期寫成活的,寫成可實(shí)時更新日期等等

給epsoide聲明一個期刊號index屬性,而日期的內(nèi)容不必依賴父子組件傳值,因?yàn)槿掌谑枪灿玫牟糠?/p>

為什么要聲明期刊號index為String?因?yàn)槲覀円M(jìn)行判斷,如果期刊號小于10,就要在數(shù)字前面加個0

只要組件的屬性的值改變,就會觸發(fā)observer對應(yīng)的函數(shù)(下面的圖示中一開始index是空值,后面index變成8的值,所以會觸發(fā)observer對應(yīng)的函數(shù))

observer

如果你做了讓數(shù)據(jù)變化的邏輯處理,想界面實(shí)時更新數(shù)據(jù),可以使用this.setData{_XXX:YYY}之類的方法

一些要調(diào)用的變量,如果是要從別的地方傳值獲取就寫properties里面,如果是直接獲取,沒必要從別的地方傳值獲取,就寫data中就可以。
對于字符串的變量,和properties中可以聲明type為String不一樣,在data中不可以聲明為String,而是按照下圖的設(shè)置來設(shè)置初始值為空字符串

常常查看微信小程序官網(wǎng)的API文檔,同時方法等等是會更新的,有些方法可能會變,比如生命周期函數(shù),所以要常常查看最新的API文檔等等,如果不知道代碼寫哪里,很多時候可以寫生命周期函數(shù)里面







例子2:實(shí)現(xiàn)導(dǎo)航欄


下面的給組件定義的屬性賦值是和properties搭配使用,來達(dá)到傳值的效果的

之后的話,我就是給導(dǎo)航欄設(shè)置樣式,進(jìn)行彈性盒子布局

例子3:實(shí)現(xiàn)導(dǎo)航欄的切換圖片效果,左翻頁和右翻頁分別在第一頁和最后一頁的綁定了事件的用于切換的圖標(biāo)(圖片)變灰色,其余情況都是黑色,實(shí)現(xiàn)禁用效果

進(jìn)行判斷的邏輯

下面的isFirst是cmpNavi(即為cmp-navi組件,即為navi組件)中的屬性,下面賦值的過程是不可以寫死的,我這里只是暫時寫死,測試其效果是否有用

下面是給導(dǎo)航欄navi組件的左翻頁和右翻頁的圖標(biāo)綁定事件

用控制臺打印語句測試,綁定的事件是否有效


下面的話綁定了自定義事件



例子4:為“切換期刊的同時,期刊界面變成對應(yīng)的內(nèi)容(實(shí)現(xiàn)music,movie,sentence組件)的功能”做準(zhǔn)備,behavior實(shí)現(xiàn)多繼承,通過調(diào)用behavior,讓很多組件都擁有behavior中的屬性,減少聲明屬性的代碼


加上切換期刊號的后臺代碼

準(zhǔn)備好素材


Behavior(行為)實(shí)現(xiàn)多繼承,Behavior可以實(shí)現(xiàn)類似于接口的效果,可以讓很多組件都有通過調(diào)用聲明了屬性的Behavior相關(guān)的文件,來讓很多組件擁有Behavior相關(guān)的文件中聲明了的屬性,可以減少聲明屬性的代碼





behavior

例子5:實(shí)現(xiàn)例子1到例子4效果的代碼




//?components/classic/movie/index.js
import?classicBeh?from?'../classic_beh.js'
Component({
??behaviors:?[classicBeh],
??/**
???*?組件的屬性列表
???*/
??properties:?{
????//被behaviors:?[classicBeh]取代的部分?START
????//?content:String,
????//?img:String,
?????//被behaviors:?[classicBeh]取代的部分?END
??},
??/**
???*?組件的初始數(shù)據(jù)
???*/
??data:?{
????icon:?'./images/movie@tag.png'
??},
??/**
???*?組件的方法列表
???*/
??methods:?{
??}
})







//?components/epsoide/index.js
Component({
??/**
???*?組件的屬性列表
???*/
??properties:?{
????//關(guān)于日期和期刊部分?START
????index:?{
??????type:?String,
??????//index屬性被修改了就會觸發(fā)這個函數(shù)
??????observer:?function(newVal){
????????//newVal修改后的值
????????//oldVal修改前的值
????????let?i?=?newVal?<?10???'0'?+?newVal?:?newVal
????????this.setData({
??????????_index:?i
????????})
??????}
????}
????//關(guān)于日期和期刊部分?END
??},?
??/**
???*?組件的初始數(shù)據(jù)
???*/
??data:?{
????//關(guān)于日期和期刊部分?START
????_index:?'',
????year:?'',
????month:?'',
????cmonths:?['一月','二月','三月','四月','五月','六月',
????'七月','八月','九月','十月','十一月','十二月']
??},
??lifetimes:?{
????attached(){
??????let?now?=?new?Date()
??????this.setData({
????????month:?this.data.cmonths[now.getMonth()],
????????year:?now.getFullYear()
??????})
????}
??},
???//關(guān)于日期和期刊部分?END
??/**
???*?組件的方法列表
???*/
??methods:?{
??}
})



/*?components/epsoide/index.wxss?*/
.container?{
??display:?inline-flex;
??height:?60rpx;
??flex-direction:?row;
}
.plain?{
??font-size:?32rpx;
}
.index?{
??font-size:?60rpx;
??line-height:?60rpx;
??font-weight:?800;
??margin-right:?14rpx;
}
.index-container?{
??display:?flex;
??flex-direction:?row;
??align-items:?baseline;
}
.date-container?{
??display:?flex;
??flex-direction:?column;
??margin-top:?6rpx;
}
.month?{
??font-size:?24rpx;
??line-height:?24rpx;
}
.year?{
??font-size:?20rpx;
}
.line?{
??height:?44rpx;
??border-left:?1px?solid?black;
??margin-right:?14rpx;
}


//?components/like/index.js
Component({
??/**
???*?組件的屬性列表
???*/
??properties:?{
????//如果不聲明變量數(shù)據(jù)類型,那么數(shù)據(jù)的內(nèi)容可能無法在別的文件中調(diào)用
????count:?Number,
????like:?Boolean,
????//自己寫的代碼?START
????//?bookImage:String
????//自己寫的代碼?END
??},
??/**
???*?組件的初始數(shù)據(jù)
???*/
??data:?{
????yesSrc:?'/components/like/images/like.png',
????noSrc:?'/components/like/images/like@dis.png',
??},
??/**
???*?組件的方法列表
???*/
??methods:?{
????onLike(){
??????let?count?=?this.properties.count
??????let?like?=?this.properties.like
//自己寫的代碼?START
//?let?bookImage=?this.properties.image
//自己寫的代碼?END
??????count?=?like???count?-?1?:?count?+?1
??????//更新組件的狀態(tài)
??????this.setData({
????????count,
????????like:?!like,
????????//自己寫的代碼?START
????????//?bookImage:bookImage
????????//自己寫的代碼?END
??????})
//關(guān)于數(shù)據(jù)庫和頁面的點(diǎn)贊數(shù)同步更新的部分?START
?//觸發(fā)綁定在like組件上的自定義事件
??????//1、需要觸發(fā)的自定義事件的名字
??????//2、自定義事件需要傳遞的數(shù)據(jù)對象
??????//3、配置事件的屬性
??????this.triggerEvent('myLike',{
????????state:?this.properties.like???'like'?:?'cancel',
????????nums:?this.properties.count
??????},{})
//關(guān)于數(shù)據(jù)庫和頁面的點(diǎn)贊數(shù)同步更新的部分?END
????}
??}
})


//?components/navi/index.js
Component({
??/**
???*?組件的屬性列表
???*/
??properties:?{
????title:?String,
????isFirst:?Boolean,//是否是第一期
????isLatest:?Boolean,//是否是最后一期
??},
??/**
???*?組件的初始數(shù)據(jù)
???*/
??data:?{
????disLeftSrc:?'images/triangle.dis@left.png',
????leftSrc:?'images/triangle@left.png',
????disRightSrc:?'images/triangle.dis@right.png',
????rightSrc:?'images/triangle@right.png'
??},
??/**
???*?組件的方法列表
???*/
??methods:?{
????onLeft(){
??????if(!this.properties.isLatest)?{
????????//觸發(fā)navi組件的自定義事件myLeft
????????this.triggerEvent('myLeft',{},{})
??????}?????
????},
????onRight(){
??????if(!this.properties.isFirst)?{
????????this.triggerEvent('myRight',{},{})
??????}?????
????}
??}
})


<!--components/navi/index.wxml-->
<view?class="container">
??<image?class="icon"?src="{{isLatest???disLeftSrc?:?leftSrc}}"?bind:tap="onLeft"/>
??<text?class="title">{{title}}</text>
??<image?class="icon"?src="{{isFirst???disRightSrc?:?rightSrc}}"?bind:tap="onRight"/>
</view>

/*?components/navi/index.wxss?*/
.container?{
??width:?600rpx;
??height:?80rpx;
??display:?inline-flex;
??background-color:?#f7f7f7;
??border-radius:?2rpx;
??flex-direction:?row;
??justify-content:?space-between;
??align-items:?center;
}
.icon?{
??height:?80rpx;
??width:?80rpx;
}
.title?{
??font-size:?28rpx;
}

//導(dǎo)航欄的左翻頁和右翻頁部分?START
??onNext(){
????console.log('獲取下一期的期刊數(shù)據(jù)')
??},
??onPrev(){
????console.log('獲取上一期的期刊數(shù)據(jù)')
??},
//導(dǎo)航欄的左翻頁和右翻頁部分?END

"cmp-navi":"/components/navi"

<!--pages/classic/index.wxml-->
<view?class="container">
????<view?class="header">
????????<cmp-epsoide?class="epsoide"?index="{{classicData.index}}"></cmp-epsoide>
????????<!--?下面的話就是調(diào)用了點(diǎn)贊的組件:?-->?????
????????<cmp-like?count="{{classicData.fav_nums}}"?like="{{classicData.like_status}}"?bind:myLike="onLike"></cmp-like>
????</view>
????<cmp-movie?content="{{classicData.content}}"?img="{{classicData.image}}"></cmp-movie>
????<cmp-navi?class="navi"?title="{{classicData.title}}"?isFirst="{{false}}"?isLatest="{{true}}"?bind:myLeft="onNext"
????????bind:myRight="onPrev"></cmp-navi>
</view>


/*?pages/classic/index.wxss?*/
.container{
????width:?100%;
????display:?flex;
????flex-direction:?column;
????align-items:?center;
??}
??.header?{
????width:?100%;
????display:?flex;
????flex-direction:?row;
????height:?100rpx;
????align-items:?center;
????justify-content:?space-between;
????border-top:?1px?solid?#f5f5f5;
????border-bottom:?1px?solid?#f5f5f5;
??}
??.epsoide?{
????margin-left:?20rpx;
????margin-top:?4rpx;
??}
??.like?{
????margin-top:?6rpx;
??}
??.navi?{
????position:?absolute;
????bottom:?40rpx;
??}




Q&A:個人做項(xiàng)目時遇到的問題和我是如何解決遇到的問題的
Q:如何解決stack棧溢出等的問題

A:



講義
準(zhǔn)備:后臺代碼處理
一、創(chuàng)建新項(xiàng)目和頁面
二、app.json配置導(dǎo)航欄
三、定義和使用點(diǎn)贊組件
"四、classic在生命周期函數(shù)中請求后臺數(shù)據(jù)
設(shè)置-項(xiàng)目設(shè)置-勾選不校驗(yàn)..."
五、封裝Http工具類。
六、將classic頁面的數(shù)據(jù)傳遞到like組件中(父組件傳數(shù)據(jù)到子組件)
七、實(shí)現(xiàn)movie組件
八、like組件傳遞數(shù)據(jù)到classic頁面(子傳父實(shí)現(xiàn)自定義事件)
"九、epsoide組件(組件的生命周期函數(shù)以及data和properties定義數(shù)據(jù)的區(qū)別)
data和properties會被合并成同一個對象,如果有同名屬性,會使用properties中定義的屬性
期刊號補(bǔ)零(observer函數(shù))"
"十、初步完成導(dǎo)航組件
獲取數(shù)據(jù):title,isFirst和isLatest
自定義導(dǎo)航事件onLeft,onRight
禁用左翻頁和右翻頁"
十一、初步實(shí)現(xiàn)music組件和essay組件
十二、提取組件的公共部分(組件的行為Behavior實(shí)現(xiàn)多繼承)
"十三、初步實(shí)現(xiàn)期刊切換前一期效果(后臺getClassic實(shí)現(xiàn))
classic頁面的onPrev"
"十四、根據(jù)index判斷是第一期還是最后一期
classicModel中的isFirst和isLatest方法,緩存(Storage)最新期刊號_setLatest方法"
"十五、實(shí)現(xiàn)期刊切換后一期效果
classic頁面的onNext
onPrev和onNext整合"
