create by jsliang on 2018-9-17 17:58:56
Recently revised in 2018-10-6 11:02:06
?Hello 小伙伴們,如果覺(jué)得本文還不錯(cuò),記得給個(gè) star , 你們的 star 是我學(xué)習(xí)的動(dòng)力!GitHub 地址
寫在前面
?微信小程序新手實(shí)踐記錄:
?工作量: PSD 18 張 (導(dǎo)出的 JPG 30 張)
?耗時(shí):12 個(gè)工作日
?總結(jié): 理性上,需要 3 周工作日(工作 15 天)搞定,前后端對(duì)接口另計(jì)。實(shí)際上,12 個(gè)工作日可以搞定所有頁(yè)面,但是應(yīng)該往前鋪 1.5D 熟悉框架,往后鋪 1.5D 整理代碼。當(dāng)然每個(gè)人的耗時(shí)可能不同,可根據(jù)個(gè)人實(shí)際情況進(jìn)行調(diào)整。
?這里有微信小程序開發(fā)中遇到的所有坑,以及在填坑過(guò)程中的一些個(gè)人經(jīng)驗(yàn)。jsliang 利用這篇教程存儲(chǔ)一些常用的微信小程序開發(fā)技巧,方便查找。它可能教不了你什么,但至少能省下你百度的功夫。
?請(qǐng)結(jié)合 《目錄》 和 《返回目錄》 來(lái)進(jìn)行跳轉(zhuǎn),獲得更好的閱讀體驗(yàn)。
?本文技術(shù)支持:Ansen江
?注1:由于更新頻繁,有時(shí)候平臺(tái)上的文章版本可能沒(méi)有圖片或者鏈接無(wú)效,獲取最新資料請(qǐng)前往 GitHub:地址
?注2:如果小伙伴使用的是手機(jī)版打開,那么推薦小伙伴使用電腦打開,因?yàn)楦髌脚_(tái)的手機(jī)端大都不支持頁(yè)內(nèi)跳轉(zhuǎn),看起來(lái)比較費(fèi)勁。
一 目錄
?目前已有 38 個(gè)坑。
請(qǐng)各位按目錄檢索時(shí)注意:
3.1、3.2、3.3…… 等二級(jí)目錄對(duì)應(yīng)著一個(gè)大部分。
3.1.1、3.1.2…… 等三級(jí)目錄將該二級(jí)目錄這個(gè)大塊詳細(xì)拆分成諸多小坑,方便查看。
二 前言
?返回目錄
?微信小程序的開發(fā)教程,或許寫出來(lái)是非常受歡迎的。
?但是:
- 第一,微信小程序是國(guó)內(nèi)的,有中文文檔,雖然它的文檔說(shuō)明有點(diǎn)坑,但好歹有文檔,閱讀理解對(duì)小伙伴們來(lái)說(shuō)不是問(wèn)題。
- 第二, jsliang 的文筆并沒(méi)有想象中的那么好,想想如果我?guī)銈冏吡艘槐樾〕绦蜷_發(fā),然后你們以為是一條平坦路,結(jié)果碰到一堆坑坑洼洼,咋辦?最后的鍋,會(huì)不會(huì)到我背啊,可怕!
?所以,在這里, jsliang 結(jié)合 “日常躺坑” ,先為你解決小程序的 100 個(gè)坑!雖然現(xiàn)在可能還不夠,但是第一天我就碰到 4/5 個(gè)了,我想我可以幫你們躺完 100 個(gè)的?。。?br>
?現(xiàn)在的微信開發(fā)者工具顯示的開發(fā)版本是:"libVersion": "2.0.4"
?如果你開發(fā)的版本已經(jīng)解決了這個(gè) bug ,或者你覺(jué)得這個(gè) bug 還有其他解決方法,或者你覺(jué)得這個(gè)玩意還有其他 bug ,請(qǐng)告訴我,我會(huì)補(bǔ)充到這篇文檔上,順帶記上您的大名,謝謝!
?QQ: 1741020489
三 填坑實(shí)戰(zhàn)
?返回目錄
? 這里的坑:
- 有的來(lái)源于微信自帶的開發(fā)文檔:小程序開發(fā)文檔。在文檔中,你會(huì)發(fā)現(xiàn)很多的樂(lè)趣!畢竟,你不知道什么時(shí)候中文成為了你的語(yǔ)言障礙~
- 有的是開發(fā)中遇到的,然后結(jié)合大量的百度結(jié)果,進(jìn)行的有效性總結(jié)。
?希望小伙伴在百度中或者無(wú)意看到這篇文章,請(qǐng)熟練使用瀏覽器的 Ctrl + F,查找需要的問(wèn)題答案。
3.1 swiper 輪播圖
?返回目錄
本組件目前已有 5 個(gè)坑,有興趣的小伙伴可以詳看。
? 代碼來(lái)源于該地址:微信組件 swiper 。
?為方便小伙伴查看,下面貼出原版代碼:
demo.wxml
<swiper indicator-dots="{{indicatorDots}}"
autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{imgUrls}}">
<swiper-item>
<image src="{{item}}" class="slide-image" width="355" height="150"/>
</swiper-item>
</block>
</swiper>
<button bindtap="changeIndicatorDots"> indicator-dots </button>
<button bindtap="changeAutoplay"> autoplay </button>
<slider bindchange="intervalChange" show-value min="500" max="2000"/> interval
<slider bindchange="durationChange" show-value min="1000" max="10000"/> duration
demo.js
Page({
data: {
imgUrls: [
'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
],
indicatorDots: false,
autoplay: false,
interval: 5000,
duration: 1000
},
changeIndicatorDots: function(e) {
this.setData({
indicatorDots: !this.data.indicatorDots
})
},
changeAutoplay: function(e) {
this.setData({
autoplay: !this.data.autoplay
})
},
intervalChange: function(e) {
this.setData({
interval: e.detail.value
})
},
durationChange: function(e) {
this.setData({
duration: e.detail.value
})
}
})
?好的,上面就是微信官方文檔的演示代碼,如果你跟著演示代碼走了一遍碰到疑問(wèn)的話,看看這里我挖的土是不是能填好你的坑:
3.1.1 行內(nèi)樣式無(wú)效
?返回目錄
?demo.wxml 中出現(xiàn)的 <image src="{{item}}" class="slide-image" width="355" height="150"/> 這行, width 和 height 的行內(nèi)屬性是忽悠老百姓的,它并沒(méi)卵用 !我們需要在 slide-image 這個(gè) class 類中修改 width 和 height。簡(jiǎn)而言之,行內(nèi)樣式都是騙人的,乖,我們還是去 demo.wxss 寫樣式吧~
3.1.2 圖片樣式修改不了
?返回目錄
?在任何出現(xiàn)圖片的地方(包括但不限于輪播圖),如果你發(fā)現(xiàn)不僅行內(nèi)寫法無(wú)效之外,還發(fā)現(xiàn)單純地給圖片加 class,去 *.wxss 寫樣式也無(wú)效的話。那么,我建議小伙伴最好采用樣式加重法,即 .image-wrap .image 這種寫法格式,來(lái)確保圖片樣式能進(jìn)行修改。詳細(xì)用法可看下文。
3.1.3 swiper 屬性值設(shè)置
?返回目錄
?swiper 屬性值。官方文檔說(shuō)明:
[圖片上傳失敗]
?雖然,它的屬性名和屬性值是這么說(shuō)的。但是,用的時(shí)候,首先你需要在 demo.wxml 中的 swiper 綁定這個(gè)屬性名,然后在 demo.js 中設(shè)置其屬性值。值得注意的是,它的綁定值,稍微不同于 Vue, 需要設(shè)置 {{}} 形式。如果文字描述你看得不是很清楚,可以參照下面的代碼進(jìn)行理解。
3.1.4 輪播圖圖片跳轉(zhuǎn)
?返回目錄
?關(guān)于輪播圖的地址跳轉(zhuǎn),在微信小程序的官網(wǎng)是沒(méi)用提及的,也是 jsliang 去百度查看了下,才知道怎么設(shè)置(可能是我一開始就挑戰(zhàn)的難度太高了么 -_-|| ),在下面 jsliang 貼出來(lái)代碼~想知道怎么解決的可以去看看:首先,在 data 中設(shè)置 link ;然后,設(shè)置 navigator 導(dǎo)航遍歷 item.link 。
3.1.5 wx:key
?返回目錄
?關(guān)于 wx:key , wx:key 的作用是:當(dāng)數(shù)據(jù)改變觸發(fā)渲染層重新渲染的時(shí)候,會(huì)校正帶有 key 的組件,框架會(huì)確保他們被重新排序,而不是重新創(chuàng)建,以確保使組件保持自身的狀態(tài),并且提高列表渲染時(shí)的效率。但是,在其 swiper 中,小程序本身是沒(méi)有寫的,所以它會(huì)帶有 warning ,這里也是個(gè)小坑, jsliang 也是百度了下也知道這件事:點(diǎn)我了解。
3.1.6 實(shí)戰(zhàn)代碼
?返回目錄
?下面給出這 5 個(gè)坑的解決代碼,如有不對(duì),盡情指出:
index.wxml
<view class="carousel">
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" indicator-color="#707071" indicator-active-color="#fff" circular="true">
<!-- wx:key : 提高列表渲染效率 -->
<block wx:for="{{imgUrls}}" wx:key="{{item.index}}">
<swiper-item>
<navigator url="{{item.link}}" hover-class="navigator-hover">
<image src="{{item.url}}" class="slide-image" />
</navigator>
</swiper-item>
</block>
</swiper>
</view>
index.wxss
.carousel .slide-image {
width: 100%;
height: 420rpx;
}
index.js
Page({
data: {
imgUrls: [
{
link: '../index/index',
url: 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
},
{
link: '../demo/demo',
url: 'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
},
{
link: '../logs/logs',
url: 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg'
}
],
indicatorDots: true,
autoplay: true,
interval: 5000,
duration: 1000
}
})
3.2 tabBar 與 switchTab
?返回目錄
本組件目前已有 3 個(gè)坑,有興趣的小伙伴可以詳看。
?tabBar :底部菜單欄,需要在 app.json 中設(shè)置。使用方法:見下文。
?navigator :導(dǎo)航切換。使用方法:地址
?switchTab :控制 tabBar 的切換。使用方法:地址
3.2.1 底部導(dǎo)航跳轉(zhuǎn)
?返回目錄
?在這里,我們講下 tabBar 的坑,如果你在 app.json 中設(shè)置了 tabBar :
app.json
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首頁(yè)",
"iconPath": "./public/index_tabBar1_nor.png",
"selectedIconPath": "./public/index_tabBar1.png"
}, {
"pagePath": "pages/demo/demo",
"text": "發(fā)現(xiàn)",
"iconPath": "./public/index_tabBar2_nor.png",
"selectedIconPath": "./public/index_tabBar2.png"
}, {
"pagePath": "pages/logs/logs",
"text": "我的",
"iconPath": "./public/index_tabBar3_nor.png",
"selectedIconPath": "./public/index_tabBar3.png"
}]
}
?那么,我們就需要通過(guò)設(shè)置 switchTab 來(lái)控制底部導(dǎo)航的跳轉(zhuǎn),而不能通過(guò) navigator 來(lái)跳轉(zhuǎn):
demo.wxml
<view>
<button bindtap="linkTo">Hello</button>
</view>
demo.js
linkTo: function () {
wx.switchTab({
url: '../index/index'
});
},
3.2.2 自定義底部導(dǎo)航
?返回目錄
?那么問(wèn)題又來(lái)了,當(dāng)我們切換到子頁(yè)面的時(shí)候,我們發(fā)現(xiàn) tabBar 這個(gè)底部導(dǎo)航欄不見了,然后問(wèn)了下 Ansen江 ,他說(shuō)之前是整個(gè)小程序都有的,有些頁(yè)面還要想方設(shè)法去隱藏。
?但是現(xiàn)在嘛……它沒(méi)了!沒(méi)了?。。?!在微信小程序的文檔沒(méi)看到有喚起底部導(dǎo)航條的方法,難道我要做一個(gè)導(dǎo)航條了么 -_-||
?回答是:yes!
?所以,下面給出該底部導(dǎo)航條 tabBar 的實(shí)現(xiàn)情況和代碼片段:
[圖片上傳失敗]
注:圖片寬高均為 54rpx
*.wxml
<view class="nav">
<view class="nav-home" bindtap="goHome">
<image src="../../public/index_productDetail_icon_home.png"></image>
<text>首頁(yè)</text>
</view>
<view class="nav-service">
<image src="../../public/index_productDetail_icon_service.png"></image>
<text>在線咨詢</text>
</view>
<view class="nav-phone" bindtap="callWaiter">
<image src="../../public/index_productDetail_icon_phone.png"></image>
<text>電話咨詢</text>
</view>
<navigator url="../indexPurchaseProduct/indexPurchaseProduct">
<view class="nav-buy">
<text>立即訂購(gòu)</text>
</view>
</navigator>
</view>
*.wxss
.nav {
display: flex;
justify-content: space-around;
font-size: 20rpx;
border: 1px solid #ccc;
position: fixed;
bottom: 0;
background: #fff;
}
.nav view {
display: flex;
flex-direction: column;
align-items: center;
}
.nav image {
width: 54rpx;
height: 54rpx;
}
.nav text {
margin-top: 7rpx;
}
.nav-home {
border-right: 1px solid #ccc;
width: 130rpx;
padding-top: 5rpx;
}
.nav-service {
border-right: 1px solid #ccc;
width: 130rpx;
padding-top: 5rpx;
}
.nav-phone {
width: 130rpx;
padding-top: 5rpx;
}
.nav-buy {
background: #eb333e;
color: #fff;
width: 360rpx;
height: 98rpx;
line-height: 80rpx;
font-size: 34rpx;
}
*.js
callWaiter: function(res) {
wx.makePhoneCall({
phoneNumber: '13264862250',
success: function(res) {
console.log("撥打成功");
console.log(res);
},
fail: function(res) {
console.log("撥打失敗");
console.log(res);
},
complete: function(res) {
console.log("撥打完成");
console.log(res);
}
})
},
goHome: function() {
wx.switchTab({
url: '../index/index'
})
},
3.2.3 自定義組件
?返回目錄
?在最近的工作中,又發(fā)現(xiàn)一個(gè)小問(wèn)題:
[圖片上傳失敗]
?像這個(gè)導(dǎo)航條,它需要根據(jù)頁(yè)面所在的模塊,動(dòng)態(tài)地展示不同位置的狀態(tài)為活躍,而且它是需要在多個(gè)頁(yè)面重復(fù)出現(xiàn)的,如果每個(gè)頁(yè)面我都要復(fù)制粘貼一遍,到時(shí)候要修改起來(lái)的時(shí)候,麻煩不說(shuō),最重要的是,它可能影響我前端的性能了,能不能直接將其封裝起來(lái)呢?
?自定義組件:鏈接
?是的,發(fā)現(xiàn)在小程序文檔中是存在這個(gè)東西的。當(dāng)然,至于過(guò)程中我百度了幾篇文章來(lái)輔助寫出下面的代碼,你猜?
?子組件寫法
navBar.wxml
<!-- 底部導(dǎo)航條 -->
<view class="navBar">
<view class="navBar-home" bindtap='goHome'>
<image wx:if="{{homeActive}}" src="../../public/index_tabBar1.png"></image>
<image wx:if="{{!homeActive}}" src="../../public/index_tabBar1_nor.png"></image>
<text>首頁(yè)</text>
</view>
<view class="navBar-explore" bindtap='goExplore'>
<image wx:if="{{exploreActive}}" src="../../public/index_tabBar2.png"></image>
<image wx:if="{{!exploreActive}}" src="../../public/index_tabBar2_nor.png"></image>
<text>發(fā)現(xiàn)</text>
</view>
<view class="navBar-user" bindtap='goUser'>
<image wx:if="{{userActive}}" src="../../public/index_tabBar3.png"></image>
<image wx:if="{{!userActive}}" src="../../public/index_tabBar3_nor.png"></image>
<text>我的</text>
</view>
</view>
navBar.wxss
/* 底部導(dǎo)航條 */
.navBar {
width: 100%;
padding: 18rpx 0;
border-top: 1rpx solid #cccccc;
display: flex;
justify-content: space-around;
position: fixed;
bottom: 0;
background: #fff;
}
.navBar image {
width: 55rpx;
height: 55rpx;
}
.navBar view {
display: flex;
flex-direction: column;
align-items: center;
font-size: 20rpx;
color: #999999;
}
.navBar-user text {
color: #d0a763;
}
navBar.js
// pages/componentNavBar/navBar.js
Component({
/**
* 組件的屬性列表
*/
properties: {
homeActive: {
type: Boolean,
value: false
},
exploreActive: {
type: Boolean,
value: false
},
userActive: {
type: Boolean,
value: false
}
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
},
/**
* 組件的方法列表
*/
methods: {
// 返回首頁(yè)
goHome: function (e) {
wx.switchTab({
url: '../index/index',
})
},
// 返回發(fā)現(xiàn)頁(yè)
goExplore: function (e) {
wx.switchTab({
url: '../explore/explore',
})
},
// 返回我的頁(yè)面
goUser: function (e) {
wx.switchTab({
url: '../user/user',
})
},
showCode: function(e) {
console.log(e);
let that = this;
console.log(that.data);
}
}
})
navBar.json
{
"component": true,
"usingComponents": {}
}
?然后,在父組件的使用,只需要:
*.wxml
<view>
<navBar userActive="{{userActive}}"></navBar>
</view>
*.json
{
"usingComponents": {
"navBar": "../componentNavBar/navBar"
}
}
*.js
data: {
userActive: true
},
?怎樣?這就是自定義組件的寫法,是不是覺(jué)得特好用涅,一次寫完,終身受用。
3.3 px、rem 與 rpx
?返回目錄
本節(jié)目前已有1個(gè)坑,有興趣的小伙伴可以詳看。
?在微信中,它自帶了一套屬于自己的單位:rpx , rpx 不同于之前我們認(rèn)識(shí)的 px 、 rem 、 em ,如果你的設(shè)計(jì)稿是 750 px 的,那么很容易的, 1px = 1rpx ,但是,如果設(shè)計(jì)稿不是 750 px ,那么將造成一個(gè) bug ,至于這個(gè) bug 如何解決……
?-_-|| 誰(shuí)知道呢……要不先把UI設(shè)計(jì)師宰了?
?知識(shí)補(bǔ)充:關(guān)于 rpx 。
3.4 微信 web 開發(fā)者工具
?返回目錄
本節(jié)目前已有 2 個(gè)坑,有興趣的小伙伴可以詳看。
3.4.1 無(wú)法輸入中文
?返回目錄
?如果你在開發(fā)過(guò)程中,發(fā)現(xiàn)只能寫英文了,而中文無(wú)法輸入了,千萬(wàn)別急,也別怪輸入法出 bug 了,你只需要:重啟開發(fā)工具。
3.4.2 無(wú)法滑動(dòng)滾輪
?返回目錄
?如果你某時(shí)刻,突然發(fā)現(xiàn)你沒(méi)法滾動(dòng)代碼進(jìn)行查看,而是需要拖動(dòng)滾動(dòng)條才行,請(qǐng)別怪你的鼠標(biāo),你可以去瀏覽器打開一篇文章看看,enm...你的鼠標(biāo)還是好的~所以,請(qǐng):重啟開發(fā)工具。
3.5 組件與 API
?返回目錄
本節(jié)目前已有 2 個(gè)坑,有興趣的小伙伴可以詳看。
3.5.1 概念混淆:組件 VS API
?返回目錄
?首先,科普下 組件 與 API 是什么:
- 組件:對(duì)數(shù)據(jù)和方法的封裝,使用組件可以實(shí)現(xiàn)拖放式編程、快速的屬性處理以及真正的面向?qū)ο蟮脑O(shè)計(jì)【百度百科】。那么,可以理解為:開發(fā)中常用的一些部件,我們都可以封裝起來(lái),然后在需要的時(shí)候拿來(lái)用,即為組件。
- API:預(yù)先定義的函數(shù),提供應(yīng)用程序與開發(fā)人員無(wú)需訪問(wèn)源碼,基于某軟件或硬件得以訪問(wèn)一組例程的能力【百度百科】。就是說(shuō)已經(jīng)寫好的一些
Function或者后端接口,前端直接調(diào)用就行了。
?但是,在微信小程序官方文檔中,組件與API,拆分地有點(diǎn)不科學(xué)。
?例如:輪播圖與底部導(dǎo)航條
- 一個(gè)在組件中,一個(gè)在 API 中;
- 一個(gè)在
wxml、wxss、js中要設(shè)置對(duì)應(yīng)的參數(shù),一個(gè)只需要在app.json中設(shè)置就行。
?可能微信小程序考慮到底部導(dǎo)航條不應(yīng)該有太大的變化(例如讓你修改太多樣式或者 js ),所以將導(dǎo)航條內(nèi)嵌至源碼中了。
?但是,這可能導(dǎo)致什么重要影響嗎?是的,如果底部導(dǎo)航條需要進(jìn)行修改呢?例如:3.2.3 自定義組件。這樣的情況下,我們的開發(fā)時(shí)間就有所增加了。
3.5.2 API 查詢不到對(duì)應(yīng)的方法
?返回目錄
?如果小伙伴你經(jīng)常有去看微信小程序官方文檔的話,那么你一定會(huì)有一件事需要吐槽,那就是:
?明明上次我見到過(guò)某個(gè) API 實(shí)現(xiàn)了我需要做的功能,但是改天我回去查找的時(shí)候,它卻提示我沒(méi)有這個(gè)玩意,這是什么鬼?!
?是的,跟我們 3.13 黑科技:<modal> 這一章中講到的 <modal> 這個(gè)黑科技一樣,有時(shí)候官方文檔也不是萬(wàn)能的,它總會(huì)有這樣那樣的毛病,導(dǎo)致我們找不到需要的東西,只能去百度了 -_-||
3.6 flex 布局
?返回目錄
本節(jié)目前已有 3 個(gè)坑,有興趣的小伙伴可以詳看。
?Flex布局又稱彈性布局,在小程序開發(fā)中比較適用。但是由于 jsliang 之前沒(méi)怎么用過(guò) Flex 布局,所以在這里咱們特意去踩下坑,充實(shí)下自己。【小程序開發(fā)之頁(yè)面布局】【阮一峰-Flex 布局教程】
?在我們布局頁(yè)面的時(shí)候,最好看看 阮一峰 的教程,平時(shí)遇到布局的問(wèn)題的時(shí)候,我都習(xí)慣去上面 阮一峰 的文章看看:
3.6.1 基礎(chǔ)概念
?返回目錄
?基礎(chǔ)概念:地址
<!-- 設(shè)置 flex 布局 -->
display: flex;
<!--
1、決定主軸的方向
row - (默認(rèn))水平方向,起點(diǎn)在左端
row-reverse - 水平方向,起點(diǎn)在右端
column - 垂直方向,起點(diǎn)在上沿
column-reverse - 垂直方向,起點(diǎn)在下沿
-->
flex-direction: row | row-reverse | column | column-reverse;
<!--
2、一條軸線(一行)排不下時(shí)如何解決
nowrap - (默認(rèn))不換行
warp - 換行,第一行在上方
wrap-reverse - 換行,第一行在下方
-->
flex-wrap: nowrap | wrap | wrap-reverse;
<!--
3、flex-flow = flex-direction + flex-wrap。即 flex-flow 是這兩個(gè)屬性的合集
row nowrap - (默認(rèn))水平方向,起點(diǎn)在左端,不換行
-->
flex-flow: <flex-direction> || <flex-wrap>;
<!--
4、justify-content 定義項(xiàng)目在主軸上的對(duì)齊方式
flex-start - 左邊對(duì)齊
flex-end - 右邊對(duì)齊
center - 居中對(duì)齊
space-between - 兩端對(duì)齊,空格在中間
space-around - 空格環(huán)繞
-->
justify-content: flex-start | flex-end | center | space-between | space-around;
<!--
5、align-items 定義項(xiàng)目在交叉軸上如何對(duì)齊
flex-start - 頂部對(duì)齊,即文字圖片等頂部同一條線上
flex-end - 底部對(duì)其,即文字圖片等底部在同一條線上
center - 中間對(duì)其,即文字圖片不管多高,都拿它們的中間放在同一條線上
stretch - 將文字圖片充滿整個(gè)容器的高度,強(qiáng)制統(tǒng)一
baseline - 將每項(xiàng)的第一行文字做統(tǒng)一在一條線上對(duì)齊
-->
align-items: flex-start | flex-end | center | stretch | baseline;
<!--
6、align-content 定義多根軸線的對(duì)齊方式。如果只有一根軸線(只有一行),該屬性不起作用
flex-start - 這幾行頂部對(duì)齊
flex-end - 這幾行底部對(duì)齊
center - 這幾行居中對(duì)齊
stretch - 這幾行進(jìn)行擴(kuò)展或者縮放,從而填滿容器高
space-between - 這幾行中間使用空格進(jìn)行填充
space-around - 這幾行兩邊及中間進(jìn)行填充
-->
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
3.6.2 左右布局
?返回目錄
?實(shí)現(xiàn)效果如下:
[圖片上傳失敗]
?如圖,這是我們要實(shí)現(xiàn)的左右布局效果。那么,在微信小程序要怎么做呢?
*.wxml
<view class="top-recommended-headlines">
<view class="top-recommended-headlines-left">
<text>熱門推薦</text>
</view>
<view>
<image src="../../public/index_top_recommended_headlines.png"></image>
</view>
<view class="top-recommended-headlines-right">
<navigator url="../indexProduct/indexProduct">查看全部 ></navigator>
</view>
</view>
*.wxss
.top-recommended-headlines {
display: flex;
align-items: flex-end;
height: 31rpx;
line-height: 31rpx;
margin-bottom: 10rpx;
}
.top-recommended-headlines-left text {
font-size: 32rpx;
font-weight: bold;
}
.top-recommended-headlines image {
width: 366rpx;
height: 31rpx;
margin-left: 10rpx;
}
.top-recommended-headlines-right navigator {
font-size: 26rpx;
color: #a9a9a9;
margin-left: 50rpx;
}
3.6.3 混合布局
?返回目錄
?實(shí)現(xiàn)效果如下:
[圖片上傳失敗]
?如圖,這是我們要實(shí)現(xiàn)的左右布局效果。那么,在微信小程序要怎么做呢?
*.wxml
<view class="weui-tab__content-item3" wx:for="{{tabs3Content}}" wx:key="{{item.index}}">
<navigator url="../indexProductArticle/indexProductArticle">
<view class="weui-tab__content-item3-question">
<image src="../../public/index_productDetail_icon_question.png"></image>
<text>{{item.title}}</text>
</view>
<view class="weui-tab__content-item3-answer">
<image src="../../public/index_productDetail_icon_answer.png"></image>
<text>{{item.content}}</text>
</view>
<view class="weui-tab__content-item3-detail">
<text class="weui-tab__content-item3-detail-datatime">{{item.datatime}}</text>
<text class="weui-tab__content-item3-detail-reader">{{item.reader}}閱讀</text>
<text class="weui-tab__content-item3-detail-label">#{{item.label}}#</text>
</view>
</navigator>
<view class="weui-tab__content-item3-gap">
<image src="../../public/index_productDetail_gap.png"></image>
</view>
</view>
*.wxss
.weui-tab__content-item3 {
padding-left: 30rpx;
padding-right: 30rpx;
margin-top: -10rpx;
margin-bottom: 10rpx;
}
.weui-tab__content-item3:first-child {
padding: 40rpx 30rpx 0;
}
.weui-tab__content-item3-question image {
width: 30rpx;
height: 30rpx;
}
.weui-tab__content-item3-question text {
font-size: 30rpx;
line-height: 46rpx;
font-weight: bold;
color: #333;
margin-left: 10rpx;
}
.weui-tab__content-item3-answer image {
width: 30rpx;
height: 30rpx;
}
.weui-tab__content-item3-answer text {
font-size: 26rpx;
line-height: 42rpx;
color: #a9a9a9;
margin-left: 10rpx;
}
.weui-tab__content-item3-detail {
display: flex;
justify-content: space-between;
font-size: 26rpx;
color: #a9a9a9;
}
.weui-tab__content-item3-detail-label {
color: #d0a763;
}
.weui-tab__content-item3-gap image {
width: 100%;
height: 30rpx;
}
*.js
tabs3Content: [
{
title: '員工發(fā)明創(chuàng)造是否屬于職務(wù)發(fā)明的認(rèn)證標(biāo)準(zhǔn)?',
content: '隨著企業(yè)對(duì)知識(shí)產(chǎn)權(quán)在企業(yè)發(fā)展中核心競(jìng)爭(zhēng)力的認(rèn)識(shí)力提高,企業(yè)保護(hù)自身知識(shí)產(chǎn)權(quán)的意識(shí)不斷增強(qiáng),使其技術(shù)得......',
datatime: '2018-03-05',
reader: '2081',
label: '知識(shí)產(chǎn)權(quán)'
}
]
3.7 background-image 套用本地圖片無(wú)效
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?在小程序中,如果你使用 wxss,你是可以發(fā)現(xiàn)有 background-image 的提示的。但是,如果你設(shè)置它的背景圖是本地圖片,你會(huì)發(fā)現(xiàn),它是不生效的。
?解決方案:
- 在使用背景圖片的時(shí)候用網(wǎng)絡(luò)圖片,就是用外鏈的形式,比如你將這張圖片放到你的服務(wù)器,如:
https://xxxx/xxx.jpg; - 將背景圖片使用編碼base64進(jìn)行轉(zhuǎn)換,可以在這個(gè)網(wǎng)址進(jìn)行 點(diǎn)我前往 轉(zhuǎn)換,如:background-image: url("轉(zhuǎn)換后得到的編碼文本"),如果多次使用的話可以將該值設(shè)置為全局變量,再在js文件進(jìn)行引用即可。
- 使用
image組件 +position定位而不是使用background-image。
3.8 <block> 與 <view>
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?兩者的區(qū)別是,<view> 是一個(gè)組件,會(huì)在頁(yè)面上做渲染;<block> 不是一個(gè)組件,它僅僅是一個(gè)包裝元素,只接受控制屬性,不會(huì)在頁(yè)面中做任何渲染。
?所以,如果你僅僅是需要包裹,而不是渲染一個(gè)層,可以使用 <block> 提升性能。
3.9 搜索框
?返回目錄
本節(jié)目前已有 2 個(gè)坑,有興趣的小伙伴可以詳看。
3.9.1 margin-top 無(wú)法上浮
?返回目錄
?首先,我們要實(shí)現(xiàn)的效果是:
[圖片上傳失敗]
?然后, jsliang 的想法是:
*.wxml
<view class="search">
<input class="search-product-input" bindinput="bindKeyInput" auto-focus maxlength='10'></input>
<label class="search-placeholder">
<image class="search-placeholder-icon" src="../../public/index_indexProduct_icon_search.png"></image>
<text class="search-placeholder-text">搜索產(chǎn)品</text>
</label>
<view></view>
</view>
*.wxss
.search {
height: 100rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
position: relative;
}
.search-product-input {
background: #f5f5f5;
width: 650rpx;
height: 65rpx;
border-radius: 30rpx;
font-size: 30rpx;
padding-left: 20rpx;
}
.search-placeholder {
font-size: 26rpx;
text-align: center;
margin-top: -65rpx;
z-index: 2;
}
.search-placeholder-icon {
width: 24rpx;
height: 24rpx;
}
.search-placeholder-text {
margin-left: 10rpx;
}
?你注意到了嗎?在 *.wxml 中, jsliang 設(shè)置了個(gè)空的 <view> ,如果你把這個(gè) <view> 去掉,你會(huì)驚奇地發(fā)現(xiàn),它……下來(lái)了……
[圖片上傳失敗]
?好吧,可能有其他的實(shí)現(xiàn)方式,但是如果你下次使用這種方式,注意上面這個(gè)坑~
3.9.2 改造 WeUI 搜索框
?返回目錄
?回頭看了下 WeUI 的實(shí)現(xiàn)方式,發(fā)現(xiàn)跟我的思路是挺像的,關(guān)于 input 的實(shí)現(xiàn)方式,現(xiàn)在依據(jù) WeUI ,成功實(shí)現(xiàn)了輸入框:
[圖片上傳失敗]
?源碼奉上:
*.wxml
<!-- 搜索框 -->
<view class="search">
<view class="weui-search-bar">
<view class="weui-search-bar__form {{inputShowed ? 'form-border' : ''}}">
<view class="weui-search-bar__box">
<icon class="weui-icon-search_in-box" type="search" size="14"></icon>
<input type="text" class="weui-search-bar__input" placeholder="搜索" value="{{inputVal}}" focus="{{inputShowed}}" bindinput="inputTyping" />
<view class="weui-icon-clear" wx:if="{{inputVal.length > 0}}" bindtap="clearInput">
<icon type="clear" size="14"></icon>
</view>
</view>
<label class="weui-search-bar__label" hidden="{{inputShowed}}" bindtap="showInput">
<icon class="weui-icon-search" type="search" size="14"></icon>
<view class="weui-search-bar__text">搜索</view>
</label>
</view>
<view wx:if="{{inputVal.length <= 0}}" class="weui-search-bar__cancel-btn" hidden="{{!inputShowed}}" bindtap="hideInput">取消</view>
<view wx:if="{{inputVal.length > 0}}" class="weui-search-bar__submit-btn" hidden="{{!inputShowed}}" bindtap="searchInput">搜索</view>
</view>
</view>
*.js
Page({
data: {
inputShowed: false,
inputVal: ""
},
showInput: function () {
this.setData({
inputShowed: true
});
},
hideInput: function () {
this.setData({
inputVal: "",
inputShowed: false
});
},
clearInput: function () {
this.setData({
inputVal: ""
});
},
inputTyping: function (e) {
this.setData({
inputVal: e.detail.value
});
}
})
*.wxss
.search {
height: 100rpx;
padding: 18rpx 30rpx;
}
.weui-search-bar {
padding: 0;
background-color: #fff;
border-top: none;
border-bottom: none;
height: 64rpx;
}
.weui-search-bar__form {
border: none;
}
.form-border {
border: 1rpx solid #f5f5f5;
background: #f5f5f5;
}
.weui-search-bar__label {
background: #f5f5f5;
border-radius: 30rpx;
}
.weui-search-bar__cancel-btn {
font-size: 26rpx;
background: rgb(8, 202, 186);
color: #fff;
padding: 2rpx 20rpx 0 20rpx;
border-radius: 10rpx;
}
.weui-search-bar__submit-btn {
font-size: 26rpx;
background: rgb(8, 200, 248);
color: #fff;
padding: 10rpx 20rpx 0 20rpx;
border-radius: 10rpx;
}
3.10 微信小程序分享
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?官方文檔:地址
?在這里,提醒廣大小伙伴注意了,注意了,注意了!重要的事說(shuō)三遍。
?當(dāng)你新建 page 的時(shí)候,微信 web 開發(fā)者工具會(huì)自動(dòng)幫你添加分享事件:
/**
* 用戶點(diǎn)擊右上角分享
*/
onShareAppMessage: function (res) {
}
?所以,如果你在前面定義了,它會(huì)在最下面偷偷幫你清空,然后你就覺(jué)得無(wú)法自定義分享事件……
?是的,jsliang 打死都不承認(rèn)這是我自己的鍋,新手注意!新手注意?。⌒率肿⒁猓。?!
3.11 border-box 設(shè)置
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?熟知盒模型的小伙伴應(yīng)該知道,盒模型有兩種計(jì)算方式:
- box-sizing: border-box;
- box-sizing: content-box;
?在 border-box 中,整個(gè) view 的寬、高,包括 margin、padding、border。
?而在 content-box 中,整個(gè) view 的寬、高,則不包括上面元素。
[圖片上傳失敗]
?如上圖,如果一個(gè) view ,你的代碼如下:
view {
box-sizing: border-box;
margin: 10rpx;
width: 100rpx;
height: 100rpx;
padding: 10rpx;
}
?那么,你的整個(gè)寬高還是 100rpx。
?但是,如果你的代碼如下:
view {
box-sizing: content-box;
margin: 10rpx;
width: 100rpx;
height: 100rpx;
padding: 10rpx;
}
?那么,你的整個(gè)盒子寬高是 120rpx。
?如果你在設(shè)計(jì)頁(yè)面中,發(fā)現(xiàn)內(nèi)容區(qū)被撐爆了,那么,請(qǐng)檢查下現(xiàn)在的 border-box 是什么。
3.12 自定義選項(xiàng)卡
?返回目錄
本節(jié)目前已有 6 個(gè)坑,有興趣的小伙伴可以詳看。
3.12.1 WeUI 選項(xiàng)卡
?返回目錄
?使用 WeUI 的導(dǎo)航條,首先需要引用 WeUI 的 CSS 樣式:地址
?下載 weui.wxss 并在 app.wxss 中引用即可
app.wxss
/* 引用WeUI */
@import 'weui.wxss';
?然后,我們直接往頁(yè)面加入它的選項(xiàng)卡并根據(jù)項(xiàng)目需求修改其樣式:
*.wxml
<view class="tab">
<view class="weui-tab">
<view class="weui-navbar">
<block wx:for="{{tabs}}" wx:key="*this">
<view id="{{index}}" class="weui-navbar__item {{activeIndex == index ? 'weui-bar__item_on' : ''}}" bindtap="tabClick">
<view class="weui-navbar__title">{{item}}</view>
</view>
</block>
<view class="weui-navbar__slider" style="left: {{sliderLeft}}px; transform: translateX({{sliderOffset}}px); -webkit-transform: translateX({{sliderOffset}}px);"></view>
</view>
<view class="weui-tab__panel">
<!-- 全部 -->
<view class="weui-tab__content" hidden="{{activeIndex != 0}}">
<view class="weui-tab__content-item1">
<text>全部</text>
</view>
</view>
<!-- 已付款 -->
<view class="weui-tab__content" hidden="{{activeIndex != 1}}">
<view class="weui-tab__content-item2">
<text>已付款</text>
</view>
</view>
<!-- 待付款 -->
<view class="weui-tab__content" hidden="{{activeIndex != 2}}">
<view class="weui-tab__content-item3">
<text>待付款</text>
</view>
</view>
</view>
</view>
</view>
*.wxss
.tab {
font-size: 26rpx;
}
.tab image {
width: 173rpx;
height: 29rpx;
}
.weui-navbar {
border-top: 1rpx solid #efefef;
border-bottom: 1rpx solid #efefef;
}
.weui-navbar__slider {
background: #d0a763;
width: 4em;
}
.weui-navbar__item.weui-bar__item_on {
color: #d0a763;
}
.weui-tab__content {
margin-bottom: 100rpx;
}
*.js
var sliderWidth = 52; // 需要設(shè)置slider的寬度,用于計(jì)算中間位置
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
// 選項(xiàng)卡導(dǎo)航
tabs: ["全部", "已付款", "待付款"],
activeIndex: 1,
sliderOffset: 0,
sliderLeft: 0,
},
// 選項(xiàng)卡切換
tabClick: function (e) {
this.setData({
sliderOffset: e.currentTarget.offsetLeft,
activeIndex: e.currentTarget.id
});
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面加載
*/
onLoad: function (options) {
// 計(jì)算搜索框活躍條
var that = this;
wx.getSystemInfo({
success: function (res) {
that.setData({
sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2,
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
}
})
3.12.2 自定義選項(xiàng)卡效果與實(shí)現(xiàn)
?返回目錄
?自定義選項(xiàng)卡的代碼實(shí)現(xiàn):
?實(shí)現(xiàn)效果圖如下:
[圖片上傳失敗]
?實(shí)現(xiàn)代碼如下:
*.wxml
<view>
<view class="weui-tab__nav">
<text wx:for="{{tabs2Nav}}" wx:key="item.index" class="{{item.state == 1 ? 'weui-tab__nav-active' : ''}}" bindtap="tabs2NavClick" data-labelId="{{item.id}}">{{item.label}}</text>
</view>
<view class="weui-tab__content-item2" wx:for="{{tabs2Content}}" wx:key="{{item.index}}">
<view class="weui-tab__content-item-descritpion">
<view class="{{item.type == 1 ? 'weui-tab__content-item-icon-type' : 'hide'}}">
<image src="../../public/index_productDetail_icon_word.png"></image>
</view>
<view class="{{item.type == 2 ? 'weui-tab__content-item-icon-type' : 'hide'}}">
<image src="../../public/index_productDetail_icon_excel.png"></image>
</view>
<view class="{{item.type == 3 ? 'weui-tab__content-item-icon-type' : 'hide'}}">
<image src="../../public/index_productDetail_icon_ppt.png"></image>
</view>
<view class="{{item.type == 4 ? 'weui-tab__content-item-icon-type' : 'hide'}}">
<image src="../../public/index_productDetail_icon_pdf.png"></image>
</view>
<view class="weui-tab__content-item-descritpion-content">
<text class="weui-tab__content-item-descritpion-content-title">{{item.title}}</text>
<view class="weui-tab__content-item-descritpion-content-datatime">
<text class="weui-tab__content-item-descritpion-content-datatime1">發(fā)布時(shí)間:{{item.datatime}}</text>
<text class="{{item.effectiveTime ? 'weui-tab__content-item-descritpion-content-datatime2' : 'hide'}}">生效時(shí)間:{{item.effectiveTime}}</text>
</view>
</view>
</view>
<view class="weui-tab__content-item-download-state" bindtap='downloadFile' data-url="{{item.url}}">
<image src="../../public/index_productDetail_icon_undown.png"></image>
</view>
</view>
</view>
*.wxss
.weui-tab__nav {
background: #f5f5f5;
border: 1rpx 0rpx solid #e6e6e6;
height: 90rpx;
padding: 17rpx 41rpx;
display: flex;
justify-content: space-between;
}
.weui-tab__nav text {
border-radius: 56rpx;
height: 56rpx;
line-height: 56rpx;
padding: 15rpx 23rpx;
font-size: 26rpx;
font-weight: bold;
}
.weui-tab__nav-active {
color: #fefefe;
background: #d0a763;
}
.weui-tab__content-item2 {
display: flex;
justify-content: space-between;
padding: 25rpx 30rpx;
}
.weui-tab__content-item-descritpion {
display: flex;
justify-content: space-between;
}
.weui-tab__content-item-descritpion image {
width: 60rpx;
height: 70rpx;
}
.hide {
display: none;
}
.weui-tab__content-item-descritpion-content {
margin-left: 26rpx;
}
.weui-tab__content-item-descritpion-content-title {
font-size: 28rpx;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.weui-tab__content-item-descritpion-content-datatime {
font-size: 22rpx;
color: #bbb;
}
.weui-tab__content-item-descritpion-content-datatime1 {
margin-right: 35rpx;
}
.weui-tab__content-item-download-state image {
width: 64rpx;
height: 64rpx;
}
*.js
data: {
tabs2Nav: [
{
id: '1',
label: '法律大全',
state: 1
},
{
id: '2',
label: '合同模板',
state: 0
},
{
id: '3',
label: '民事',
state: 0
},
{
id: '4',
label: '行政',
state: 0
},
{
id: '5',
label: '執(zhí)行',
state: 0
}
],
tabs2Content: [
{
title: '中華人名共和國(guó)民用航空法(2015年...).doc',
url: 'https://wxmcard.imusic.cn/testfordocdownload.doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
},
{
title: '原生申訴表格.xls',
url: 'https://wxmcard.imusic.cn/testfordocdownload.doc',
datatime: '2018-01-26',
type: '2'
},
{
title: '法律常識(shí)大匯集及范例.ppt',
url: 'https://wxmcard.imusic.cn/testforpptdownload.pptx',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '3'
},
{
title: '事業(yè)單位法律基礎(chǔ)知識(shí)總結(jié).pdf',
url: 'https://wxmcard.imusic.cn/testforpdfdownload.pdf',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '4'
}
],
// 選項(xiàng)卡第二屏分組
tabs2Content1: [
{
title: '中華人名共和國(guó)民用航空法(2015年...).doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
},
{
title: '原生申訴表格.xls',
datatime: '2018-01-26',
type: '2'
},
{
title: '法律常識(shí)大匯集及范例.ppt',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '3'
},
{
title: '事業(yè)單位法律基礎(chǔ)知識(shí)總結(jié).pdf',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '4'
}
],
tabs2Content2: [
{
title: '合同模板.doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
}
],
tabs2Content3: [
{
title: '民事合同模板.doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
}
],
tabs2Content4: [
{
title: '行政合同模板.doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
}
],
tabs2Content5: [
{
title: '執(zhí)行合同模板.doc',
datatime: '2018-01-26',
effectiveTime: '2018-01-26',
type: '1'
}
]
},
// 選項(xiàng)卡2切換
tabs2NavClick: function(e) {
var that = this;
console.log("完整的數(shù)據(jù)是:");
console.log(that.data.tabs2Nav);
console.log("點(diǎn)擊的標(biāo)簽是:");
console.log(e.currentTarget.dataset.labelid);
var newTabs2Content;
console.log("正在經(jīng)歷的標(biāo)簽是:");
for(var i=0; i<that.data.tabs2Nav.length; i++) {
console.log(that.data.tabs2Nav[i].id);
that.data.tabs2Nav[i].state = 0;
if (that.data.tabs2Nav[i].id == e.currentTarget.dataset.labelid) {
that.data.tabs2Nav[i].state = 1;
console.log("將改變的標(biāo)簽是:");
console.log(that.data.tabs2Nav[i]);
// 改變內(nèi)容
var changeContentName = "tabs2Content" + (i + 1);
if (changeContentName == "tabs2Content1") {
console.log(that.data.tabs2Content1);
newTabs2Content = that.data.tabs2Content1;
} else if (changeContentName == "tabs2Content2") {
newTabs2Content = that.data.tabs2Content2;
} else if (changeContentName == "tabs2Content3") {
newTabs2Content = that.data.tabs2Content3;
} else if (changeContentName == "tabs2Content4") {
newTabs2Content = that.data.tabs2Content4;
} else {
newTabs2Content = that.data.tabs2Content5;
}
console.log("希望轉(zhuǎn)換內(nèi)容到:");
console.log(changeContentName);
}
}
this.setData({
tabs2Nav: that.data.tabs2Nav,
tabs2Content: newTabs2Content
})
},
3.12.3 綁定事件如何傳遞數(shù)據(jù)
?返回目錄
?綁定事件如何傳遞數(shù)據(jù):
?如果學(xué)過(guò) Vue 的同學(xué),應(yīng)該知道 Vue 的數(shù)據(jù)傳遞形式是: @click='tabs2NavClick(item.id)'
?那么,在微信小程序中,你千萬(wàn)記得,綁定時(shí)間的傳遞參數(shù)的方式不是這樣子的,而是:
<text wx:for="{{tabs2Nav}}" wx:key="item.index" bindtap="tabs2NavClick" data-labelId="{{item.id}}">{{item.label}}</text>
?通過(guò) data-*="{{item}}" 的形式傳遞的~然后你需要在 js 中,通過(guò) e.currentTarget.dataset.labelid 來(lái)獲取。
3.12.4 不允許駝峰
?返回目錄
?然后,注意了,這里還有個(gè)小 bug。在代碼中,我們使用的是 data-labelId="{{item.id}}",而獲取數(shù)據(jù)的時(shí)候,我們獲取的是 labelid,是的,駝峰不見了~
?參考鏈接:鏈接
3.12.5 獲取 data 數(shù)據(jù)
?返回目錄
?如何在方法中獲取 data 中定義的數(shù)據(jù):
?如果我想在選項(xiàng)卡切換的方法 tabs2NavClick 中獲取 data 里面的數(shù)據(jù),那么我應(yīng)該怎么做呢?
?是的,通過(guò):
tabs2NavClick: function(e) {
var that = this;
console.log(that.data.tabs2Nav);
}
?這種形式,我們就可以獲取到 data 中的數(shù)據(jù)。
?參考鏈接:鏈接
3.12.6 實(shí)現(xiàn)文字省略
?返回目錄
?如何實(shí)現(xiàn)文字省略:
?加入你有一段文本,你想讓頁(yè)面根據(jù)自身寬度,自動(dòng)省略多余長(zhǎng)度,那么,我們可以設(shè)置下面的 css 代碼,從而實(shí)現(xiàn)文字省略效果(不使用 js 的原因,是因?yàn)?js 沒(méi)有 css 那么靈活)
text {
overflow:hidden;
text-overflow:ellipsis;
display:-webkit-box;
-webkit-line-clamp:1;
-webkit-box-orient:vertical;
}
?參考鏈接:鏈接
3.13 黑科技:<modal>
?返回目錄
本節(jié)目前已有 2 個(gè)坑,有興趣的小伙伴可以詳看。
3.13.1 被遺棄的 <modal>
?返回目錄
?一個(gè)坑就是一個(gè)故事。
?故事都有四元素:時(shí)間,地點(diǎn),人物,事情。
?前三個(gè)自不必說(shuō),我們直接講事情經(jīng)過(guò):我們項(xiàng)目的負(fù)責(zé)人需要一個(gè)留言彈窗,然后里面有個(gè)文本框可以填信息,最后點(diǎn)擊【留言】按鈕將數(shù)據(jù)傳到后端,點(diǎn)擊【取消】按鈕關(guān)閉彈窗。
?需求是不是很簡(jiǎn)單~既然微信小程序有自己的官方文檔。那么,怎么方便怎么來(lái)吧,于是 jsliang 在微信小程序中搜索關(guān)鍵字 彈窗:
[圖片上傳失敗]
?看了下搜索記錄,最匹配的就是上面這個(gè)了。enm...好像沒(méi)看到放文本框的?先試試:
[圖片上傳失敗]
?額(⊙o⊙)…
[圖片上傳失敗]
?不好意思打擾了,我去百度看看:鏈接
?咦~ 它這里好像有個(gè) <modal> 標(biāo)簽?Ctrl+C、Ctrl+V 試試先~
[圖片上傳失敗]
?Duang~~~這不就是我要的效果么,挖槽,黑科技?于是 jsliang 去小程序那里搜了下 modal ……enm...蜜汁尷尬,好像只有上面的 wx.showModal() 方法……于是 jsliang 滿頭黑線……好嘛,黑科技黑科技?。。?br>
?下面貼出實(shí)現(xiàn)代碼:
*.wxml
<text class="article-message-board-head-addMessage" bindtap="modalinput">寫留言</text>
*.js
Page({
data: {
// 彈窗
hiddenmodalput: true, //可以通過(guò)hidden是否掩藏彈出框的屬性,來(lái)指定那個(gè)彈出框
},
//點(diǎn)擊按鈕指定的hiddenmodalput彈出框
modalinput: function () {
this.setData({
hiddenmodalput: !this.data.hiddenmodalput
})
},
//取消按鈕
cancel: function () {
this.setData({
hiddenmodalput: true
});
},
//確認(rèn)
confirm: function () {
wx.showToast({
title: '留言成功!',
})
this.setData({
hiddenmodalput: true
})
}
})
?好的,上面就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的可填寫文本的彈窗了。
3.13.2 四種彈窗寫法
?返回目錄
?作為一枚職業(yè)填坑人,怎么能滿足于上面的兩種彈窗形式呢!于是,使用百度大法又找到了一篇填坑文:鏈接
?所以,總結(jié)下就有了四種彈窗寫法:
| 類型 | 說(shuō)明 | 地址 |
|---|---|---|
| 模態(tài)彈窗 | 模態(tài)彈窗就是上面的第一種彈窗,它可以給你選擇【取消】或者【確定】 | 鏈接 |
| <modal> | <modal>是上面的第二種彈窗,可以提供用戶填寫 | 鏈接 |
| 消息彈窗 | 消息彈窗就是操作成功或者操作失敗的那一刻,系統(tǒng)的提示彈窗,無(wú)需用戶操作,可設(shè)定幾秒自動(dòng)關(guān)閉 | 鏈接 |
| 操作菜單 | 操作菜單類似于彈出的下拉菜單,提供你選擇其中某項(xiàng)或者【取消】 | 鏈接 |
?在這里,就講完了微信小程序的四種彈窗形式了。如果你改樣式改的煩啊煩的,可能你需要封裝一個(gè)屬于自己的彈窗?嘿嘿,說(shuō)不定你的產(chǎn)品經(jīng)理會(huì)有興趣讓你開發(fā)一個(gè) beautiful 彈窗的~
?這坑我不填,我沒(méi)碰到~碰到了再說(shuō)!在這里預(yù)留下這個(gè)坑,哈哈。
3.14 小程序解析 HTML
?返回目錄
本節(jié)目前已有 5 個(gè)坑,有興趣的小伙伴可以詳看。
3.14.1 解析 HTML 的三種方法
?返回目錄
?在小程序的文章處理中,文章的主體內(nèi)容,一般來(lái)說(shuō),后端會(huì)采用富文本的形式存儲(chǔ)數(shù)據(jù)到數(shù)據(jù)庫(kù)。就是說(shuō),你要在 view 中展示 html 變遷。但是,你知道的,小程序不采用瀏覽器的那一套,所以,你可能需要兜圈子了:鏈接
?在上面這篇文章中,講述了三種解析富文本的方法:
- wxParse 解析富文本
- rich-text 解析富文本
- web-view 解析富文本
3.14.2 wxParse
?返回目錄
?在百度大法的渲染下,jsliang 采用了 wxParse。
?Github 的 wxParse 地址:鏈接
?使用方法很簡(jiǎn)單,照著它 GitHub 地址去擼就是了。然而,坑不是那么容易填的 o(╥﹏╥)o
?( bug1 )wxParse 在其神秘源碼中,會(huì)將你的 html+css 樣式弄亂,例如:px 要轉(zhuǎn)成 rpx,才能在小程序中正常顯示,如果你不處理……enm...你試試~
?( bug2 )然后,如果你突然發(fā)現(xiàn),內(nèi)容無(wú)法顯示,那么,恭喜你又觸發(fā)了 bug,這個(gè)是 wxParse 代碼的一個(gè) bug,在一些特殊的手機(jī)里面,在 wxparse/html2json.js 中的第 112 和 119行,都有一個(gè) console.dir() 這個(gè)函數(shù)的使用,它使你的內(nèi)容不能正常顯示了。把這個(gè)函數(shù)注釋掉,內(nèi)容就可以正常顯示出來(lái)了。
if (name == 'class') {
// console.dir(value); // 112 行
// value = value.join("")
node.classStr = value;
}
// has multi attibutes
// make it array of attribute
if (name == 'style') {
// console.dir(value); // 119行
// value = value.join("")
node.styleStr = value;
}
?( bug3 )如果你需要引用圖片,那么,你會(huì)發(fā)現(xiàn)引用不成功。這是因?yàn)椋覀冊(cè)诰W(wǎng)頁(yè)后臺(tái)編輯器里面上傳的圖片,是采用相對(duì)路徑的,上傳成絕對(duì)網(wǎng)絡(luò)地址路徑之后,換成域名,就沒(méi)法很好的展示了。所以最好的方法,就是修改 html2json.js 這個(gè)文件,讓 wxParse 自動(dòng)添加域名前綴:地址
?綜上,jsliang 氣得差口吐白沫了……換換換!有空要換成其他兩種方式才行?。?!
3.14.3 rich-text
?返回目錄
?jsliang 還未使用過(guò) rich-text,這里先預(yù)留個(gè)坑。如果小伙伴們?cè)陂_發(fā) rich-text 過(guò)程中碰到過(guò)各種坑,可以跟 jsliang 提一下,我會(huì)寫進(jìn)這章節(jié),順帶在章節(jié)尾寫上你的大名,辛苦了~
3.14.4 web-view
?返回目錄
?jsliang 還未使用過(guò) web-view,這里先預(yù)留個(gè)坑。如果小伙伴們?cè)陂_發(fā) web-view 過(guò)程中碰到過(guò)各種坑,可以跟 jsliang 提一下,我會(huì)寫進(jìn)這章節(jié),順帶在章節(jié)尾寫上你的大名,辛苦了~
3.15 詭異的 open-type
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?在小程序中,它有一些自定義的方法,例如 open-type ,是需要 <button> 來(lái)承接的。
?所以,如果你寫好了一個(gè) view,里面有很好看的樣式了,你本來(lái)打算用 bindtap 來(lái)搞事情的。但是,突然接到信息,需要外套一層 <button open-type="***"> ,然后發(fā)現(xiàn),樣式需要重新跳過(guò)……
?enm...加油不哭,重新寫過(guò)樣式吧~
3.16 <button>去樣式及其內(nèi)嵌<image>
?返回目錄
本節(jié)目前已有 1 個(gè)坑,有興趣的小伙伴可以詳看。
?就像上一章所說(shuō)的,有時(shí)候,迫不得已,我們必須在 <button> 中內(nèi)嵌個(gè) <image> 或者 <text> 之類的,那么,一般怎么做呢?
?現(xiàn)在,假設(shè)我有一個(gè) 42*40 的圖片,我來(lái)試試調(diào)下它的樣式:
*.wxml
<button open-type='share'>
<image src="../../public/explore_activityDetail_icon_share.png"></image>
</button>
*.wxss
.activity-user-action button {
width: 42rpx;
height: 80rpx;
margin: 0;
padding: 0;
margin-top: -21rpx;
background: #fff;
}
.activity-user-action button::after {
border: none;
}
.activity-user-action image:last-child {
width: 42rpx;
height: 40rpx;
}
?如上,我們需要設(shè)置這個(gè)按鈕的高度是圖片高度的 2 倍,然后還需要設(shè)置 margin-top 的高度為圖片高度的 1/2(注意 margin 與 margin-top 的順序,如果你不知道順序的重要性,推薦你使用 margin: -21rpx 0 0 0),同時(shí) margin、padding、background、border 需要清空。
3.17 下拉刷新和上拉加載
?返回目錄
本節(jié)目前已有 2 個(gè)坑,有興趣的小伙伴可以詳看。
?在瀏覽器中,有 F5 刷新,有鼠標(biāo)滾輪滑動(dòng)加載。
?那么,換到微信小程序,又是怎樣子的呢?
?是的,這就要說(shuō)說(shuō)用戶下拉動(dòng)作和上拉觸底了:
?下拉事件在小程序文檔的解釋:鏈接
/**
* 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
*/
onPullDownRefresh: function () {
},
?上拉觸底在小程序文檔的解釋:鏈接
/**
* 頁(yè)面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
?這兩個(gè)事件,都是在你新建 page 的時(shí)候,會(huì)自動(dòng)添加的,小伙伴們注意下,免得前面寫了,被后面的覆蓋了哦~