微信小程式開發手記之八:一個小程式上線後的總結(下)
今天,說一下專案開發中遇到的一些問題,和一些效果。如果大家遇到了一些效果不好實現的,也可以給我留言,移動猿不怕嘗試。
網路請求該怎麼寫
這個似乎不是個問題,但其實是的,先來看一個請求的程式碼。
wx.request({
url: 'https://test.wisely.com/index.html?latitude=36.8962&longitude=132.5730',
data: {},
method: 'GET',
success: function(res){
// success
},
fail: function(res) {
// fail
},
complete: function(res) {
// complete
}
})
直接將地址和引數都拼接起來,賦給url,行不行?可以。但這麼寫不規範,正確地寫法應該是下面這樣
wx.request({
url: 'https://test.wisely.com/index.html',
data: {
latitude:36.8962,
longitude:132.5730
},
method: 'GET',
success: function(res){
// success
},
fail: function (res) {
// fail
},
complete: function(res) {
// complete
}
})
第二種書寫方式,將get請求的引數,放在data中,url中只保留地址,這樣的好處顯而易見,當url+引數很長時,並且引數都是變數,將引數寫在data中,非常容易修改。
相信我,真的很容易修改!
點選列表元件的item,跳轉到另一個頁面
這個似乎是個很傻的問題,用navigator標籤啊,或者用wx.navigateTo方法啊,但是,在專案中,怎麼實現呢?navigator標籤該怎麼用,wx.navigateTo方法該怎麼寫?
先來看下要實現的效果
先是一個列表頁,然後點選item,跳轉到另一個頁面,並且將item中的資料傳遞給了第2個頁面。
好,我們先來看列表頁
<view wx:for="{{list}}">
<navigator url="../wiselyer/wisely?text={{item}}">
<text>{{item}}</text>
</navigator>
</view>
js中的變數不在給出。
注意看navigator標籤中的url,它的後面是拼接了一個text變數的,並且值為所點選的item的資料。
我們來看下第2個頁面
<text>{{text}}</text>
Page({
data:{
text:"",
},
onLoad:function(options){
var text = options.text
this.setData({
text:text
})
}
}
在js方法中,onLoad中有引數options,通過它,可以獲取到前一頁面傳遞過來的引數,引數名就是navigator標籤中寫的。
so easy!!
那麼問題來了,navigator標籤的寫法會了,wx.navigateTo該怎麼寫?
簡單,繫結點選事件啊!
將列表頁的wxml改改,如下
<view wx:for="{{list}}">
<text bindtap="itemClick" data-item="{{item}}"{{item}}</text>
</view>
Page({
data:{
list:[
"aa",
"bb",
"cc"
]
},
itemClick:function(args){
var item = args.currentTarget.dataset.item
wx.navigateTo({
url: '../wiselyer/wisely?text='+item,
success: function(res){
// success
},
fail: function(res) {
// fail
},
complete: function(res) {
// complete
}
})
}
})
第2個頁面不用動,執行效果是一模一樣的。至於從wxml中向js中傳值沒搞懂的,看一下前面一篇文章。
顯示預設圖片
比如說一個輪播圖,結果沒獲取到圖片,那也不能留著一片空白,是不,需要顯示一張預設圖片,預設圖片該怎麼顯示呢?
好辦,看下面
<view class="container">
<!--顯示預設圖片-->
<image wx:if="{{url.length == 0}}" src="../../images/index_bg.png"></image>
<image wx:else src="{{url}}"></image>
</view>
Page({
data:{
url:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1494250838736&di=49c4ea7869bc39ca26ceccdf978ed493&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F13%2F56%2F99%2F88f58PICuBh_1024.jpg"
},
})
當url的長度為0時,顯示預設圖片,不為0時,顯示url對應的圖片。
文字顯示一行,多出的文字顯示省略號
先看下效果圖
<view class="container">
<!--省略為...-->
<view class="demo" style="background-color:#f2f2f2;width:400rpx;height:100rpx;">
<text class="text">ababcabcdabcdeabcdefabcdefg</text>
<text>bbbbb</text>
</view>
<!--省略為...-->
<view class="demo_2" style="background-color:#d2d2d2;width:400rpx;height:100rpx;">
<text class="text">ababcabcdabcdeabcdefabcdefg</text>
</view>
</view>
.demo{
display: flex;
justify-content: space-between;
}
.demo_2{
display: flex;
flex-direction: column;
}
.text{
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
在寫的時候,效果一直出不來,後來發現,在wxss中的class為demo_2,在wxml中寫成了demo-2,所以不對
控制文字顯示的行數
國際慣例,先看張圖
來看佈局
<view class="container">
<!--限制顯示行數為3行,超出顯示...-->
<view class="demo_2" style="background-color:#a2a2a2;width:400rpx;height:200rpx;">
<text class="text_3">{{content}}</text>
</view>
<!--限制顯示行數為5行,其實內容只有4行的情況-->
<view class="demo_2" style="background-color:#828282;width:400rpx;height:200rpx;">
<text class="text_5">{{content}}</text>
</view>
</view>
.demo_2{
display: flex;
flex-direction: column;
}
.text_3{
display: -webkit-box ;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp:3;
}
.text_5{
display: -webkit-box ;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp:5;
}
Page({
data:{
content:"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
}
})
陣列拼接技巧
<view class="container">
<button type="primary" bindtap="click">點選拼接字串</button>
<view wx:for="{{list}}">
<text>{{item}}</text>
</view>
</view>
Page({
data:{
list:[
"aa"
]
},
click:function(){
var list = [
"bb"
]
var l = this.data.list
for(var i=0;i<list.length;i++){
var item = list[i]
l.push(item)
}
this.setData({
list:l
})
}
})
點選按鈕後呼叫click方法,拼接陣列,我之前一直用的是push方法,但後來發現,還有更好的方法concat方法,如下
Page({
data:{
list:[
"aa"
]
},
click:function(){
var list = [
"bb"
]
var that = this
this.setData({
list:that.data.list.concat(list)
})
}
})
雖然這個技巧大家可能都知道,但我之前真的不知道啊….
app.js中獲取經緯度的問題
在我們的專案中,很多網路介面的訪問都需要傳入經緯度,所以準備在app.js中獲取一次經緯度,然後賦值給變數,這樣就不用每次呼叫獲取經緯度的方法了。
貌似思路沒錯,對不?
但是,真正實現的時候有問題,不管將訪問介面的操作放在onShow方法還是onLoad方法中,都可能在app.js中的經緯度還沒獲取到,就完成了生命週期方法的呼叫,所以,訪問介面就出問題了。
於是,在每次呼叫有關經緯度的介面之前,都會先判斷一樣是否已經獲取到了經緯度(可以通過變數的長度),如果沒有,就再次呼叫獲取經緯度的介面。
獲取經緯度的api是wx.getLocation方法
scroll-view標籤
坑1:scroll-view不顯示
如果你設定了scroll-view標籤,一切看上去都沒問題,但就是不顯示,那麼最大的可能是沒有為scroll-view設定高度(或者設定成了100%),因為,它的預設高度為0,不設定高度,當然顯示不出來。(貌似有時候不用設定高度也行,原因搞不清了,暫且這麼記錄吧)
坑2:scroll-view標籤設定了bindscrolltolower,實現上拉載入時,資料重複載入。
scroll-view標籤中有屬性bindscrolltolower,當滑動到底部時,就會觸發,我們可以用來實現上拉載入。但是,在實現的時候有一個問題,在上拉的過程中,因為分頁載入也是需要時間的,這就導致可能多次觸發bindscrolltolower對應的方法,所以,我們需要設定一個識別符號,只有當一次分頁載入完成後,才能進行下一次,避免載入到重複資料。
坑3:上拉載入更多時,載入更多之類的文字,要寫在scroll-view標籤內部(記憶模糊了,又不想再驗證…)
關於域名
在正式專案中,域名必須是https協議的。如果你的域名是https協議,但還是在真機上獲取不到介面資料,那麼最大的可能就是域名缺少中間證書,可以在這裡檢測。
另一點,正式專案中,是否可以使用http地址的圖片?答案是可以!
background不顯示問題
如果設定background屬性或者background-image屬性時,使用了本地的圖片,那麼在真機上是不顯示的,所以,儘量避免使用background或background-image來設定圖片,如果必須使用的話,那麼需要將圖片放在伺服器上,通過網路路徑來設定。
顯示上拉載入的進度圈
來看一個載入的效果
當初看到要實現這個效果,我是很懵逼的,這怎麼搞,旋轉動畫?後來還是一個前端的哥們兒實現了這個效果,如下
<view class="container">
<view>
<text>正在載入</text>
<view class="weui-loading"></view>
</view>
</view>
.weui-loading {
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
-webkit-animation: weuiLoading 1s steps(12, end) infinite;
animation: weuiLoading 1s steps(12, end) infinite;
background: transparent url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iciIgd2lkdGg9JzEyMHB4JyBoZWlnaHQ9JzEyMHB4JyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJub25lIiBjbGFzcz0iYmsiPjwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjRTlFOUU5JwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoMCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSc0Ni41JyB5PSc0MCcgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHJ4PSc1JyByeT0nNScgZmlsbD0nIzk4OTY5NycKICAgICAgICAgIHRyYW5zZm9ybT0ncm90YXRlKDMwIDUwIDUwKSB0cmFuc2xhdGUoMCAtMzApJz4KICAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0naW5kZWZpbml0ZScvPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyM5Qjk5OUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSg2MCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICAgICAgICAgICAgICAgcmVwZWF0Q291bnQ9J2luZGVmaW5pdGUnLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjQTNBMUEyJwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoOTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNBQkE5QUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCMkIyQjInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxNTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCQUI4QjknCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxODAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDMkMwQzEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyMTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDQkNCQ0InCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEMkQyRDInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEQURBREEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNFMkUyRTInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0Pgo8L3N2Zz4=) no-repeat;
background-size: 100%;
}
挺長的一個長串,不明覺厲,記錄在這裡。
tab效果
效果圖如下
實現如下
<view class="container">
<view class="toptab flex-wrp flex-tab ">
<view class="tobtab {{index==0?'active':''}}" data-current="0" bindtap="switchTab">
距離最近
</view>
<view class="tobtab {{index==1?'active':''}}" data-current="1" bindtap="switchTab">
熱門推薦
</view>
</view>
</view>
<view class="container">
<view class="toptab flex-tab ">
<view class="tobtab {{index==0?'active':''}}" data-current="0" bindtap="switchTab">
距離最近
</view>
<view class="tobtab {{index==1?'active':''}}" data-current="1" bindtap="switchTab">
熱門推薦
</view>
</view>
</view>
.toptab{
width: 100%;
background-color: #fff;
height: 90rpx;
line-height: 90rpx;
font-size: 30rpx;
}
.tobtab.active{
color: #75b74d;
font-weight: bold;
border-bottom: 2px solid #75b74d;
}
.flex-tab{
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: stretch;
}
Page({
data:{
index:0
},
switchTab:function(e){
var i = e.currentTarget.dataset.current
this.setData({
index:i
})
}
})
這是tab的效果,如果tab中為icon+文字,那麼實現起來會複雜一些,大家自行實現。
其它的一些小技巧與備忘
- 抽取模版,尤其是一些列表的模版,一模一樣,抽取出來方便你我他。
- 一些字串的操作,可以搜尋js中的字串操作,曾經一度很茫然,不知道小程式中的字串操作的方法是啥,後來才知道,就是js的字串操作
- 陣列操作的一些方法,其實就是js的陣列操作。
- 本地資源無法通過 css 獲取
background-image:可以使用網路圖片,或者 base64,或者使用標籤,
你要用自己的圖片的話只能先把它放到網上或者自己的伺服器(有外部域名,能訪問)上,用網路地址訪問(PS:這句話來自網路) - 小程式最多開啟5個頁面,所以如果發現一直點選一個頁面點選不開,有可能是已經達到了頁面的上限。
- 從提交稽核到稽核通過,大概花了不到1個工作日時間(第一天下班的時候提交,第二天下午4,5點左右就稽核通過)