1 最近項目需要臨時做一個調查問卷頁面。考慮到性能和複雜度,決定通過使用cdn方式編寫該頁面。
效果如下:
移動端採用vant.ui
遇到的問題:
(1) 通過cdn方式進行開發的時候,引入官網的鏈接。查看network會報302錯誤。
<link rel="stylesheet" href="https://unpkg.com/vant/lib/vant-css/index.css">
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/vant/lib/vant.min.js"></script>
解決的辦法:複製該鏈接,下載到本地,重新鏈接本地地址
(2)引入鏈接也有講究,script標籤最好在寫在body部分dom,而不能寫在head裏。這涉及到生命週期的問題和js引擎解析順序問題。所以正確寫法如下:
<head>
<link href="./css/vant.css""></link>
</head>
<body>
<div id="#app">
<van-row>
<van-col span="12">
<div @click="openDateLayout">起始日期</div>
</van-col>
<div @click="getEndDate">起始日期</div>
</van-row>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script>
<script src="./js/vant.min.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data(){
return{
}
})
</script>
</body>
(3)如果不設置viewport。會出現文本過小的問題。一定要記得設置view-port進行適配
<meta charset="UTF-8" name="viewport" content="width=device-width,initial-scale=1">
--------------------------------------------------------------------------------------------------------------------
pc端則採用了iview的ui組件庫。其中也遇到了一些問題:
效果如下:
問題一: 通過cdn引用組件,比如
<Row>
<Col span="12">選擇日期</Col>
<Col span="12"> <DatePick ></DatePick></Col>
</Row>
這樣是沒有效果的。必須要在前面加上i。所以正確寫法:
<i-row>
<i-col span="4">結束日期</i-col>
<i-col span="20"><date-picker type="date" placeholder="請選擇日期"></date-picker> </i-col>
</i-row>
</i-row>
(2) 通過cdn方式引入方式開發。引入組件的時候會出現字體圖標缺失的情況。比如日期選擇器
data-pick右上角的日期小圖標會無法顯示。
解決辦法:通過github拷貝iview的(dist/styles/)fonts文件夾至當前項目css同級目錄即可顯示
(3)通過vue-cli方式進行開發。在發送請求向後臺傳遞參數的時候,我們序列化參數可以通過qs這個插件。如果是通過cdn方式進行開發。注意這裏是Qs,
示例:
<script src="https://cdn.bootcss.com/qs/6.5.2/qs.js"></script>
<script type="text/javascript">
window.οnlοad=function(){
btn.οnclick=function(){
var data={
mobile:name,
password:pass
}
fetch(url+"/account/login",{
method:'POST',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
body:Qs.stringify(data)
}).then((res)=>{
console.log("res:",res)
return res.json()
}).then(data=>{
console.log("data:",data)
}).catch(err=>{
console.log("err:",err)
})
}
(4)vant-ui 如果使用vant-dialog自定義內容。彈出框會出現內容文本模糊,主要原因是由於vant-ui的dailog
對彈出框進行定位設置的時候採用了transform:translate(-50%,-50%),解決辦法是自定義彈出框,在進行垂直居中的時候
改爲 margin:-50% 0 0 -50%或者其他方式即可
(5)移動端如果內容過長,andriod下滑動正常但是在ios下會出現向下滑動卡頓的現象,解決的辦法就是給容器添加-webkit-overflow-scrolling:touch;
(6)移動端如果內容過長,下滑的時候會出現頁面飄動的情況。解決的辦法就是給列表容器(下滑內容)的父容器添加overflow:hidden;
<div class="project-list">
<div class="project-item" v-for="item in proData">
<div class="title">
<span class="sub">{{item.title}}</span>
</div>
<div class="cont">{{item.cont}}</div>
</div>
</div>
.project-list{padding-bottom: 26px;margin-bottom:20px;-webkit-overflow-scrolling:touch; box-sizing: border-box;height: auto;overflow-y:auto;background: #fff
}
給其父容器project-box設置over-flow以後:
.project-list{background:#f8f8f8;width: 100%;padding-top: 18px;height: 100%; overflow:hidden;}
(6)vant 的tabs組件sticky設置無效?
vant的tabs屬性有一個新的屬性sticky,官方說明是否使用粘性定位佈局。可以達到吸頂的效果。此外還有一個offsetTop屬性。設置改值以後,當滾動條達到這個高度的時候,就會固定在頂部。
但是項目中發現這個屬性設置以後居然無效。最後發現原因在於給當前頁面的結構div設置 了一個class,其中有一個屬性overflow:hidden。然後去掉父級元素的overflow以後發現成功了。後來仔細查了一下相關資料。varnt設置sticky的原理是利用了了css的position新屬性值sticky,但是有幾點需要注意:
生效規則
position:sticky
的生效是有一定的限制的,總結如下:
-
須指定 top, right, bottom 或 left 四個閾值其中之一,纔可使粘性定位生效。否則其行爲與相對定位相同。
- 並且
top
和bottom
同時設置時,top
生效的優先級高,left
和right
同時設置時,left
的優先級高。
- 並且
-
設定爲
position:sticky
元素的任意父節點的 overflow 屬性必須是 visible,否則position:sticky
不會生效。這裏需要解釋一下:- 如果
position:sticky
元素的任意父節點定位設置爲overflow:hidden
,則父容器無法進行滾動,所以position:sticky
元素也不會有滾動然後固定的情況。 - 如果
position:sticky
元素的任意父節點定位設置爲position:relative | absolute | fixed
,則元素相對父元素進行定位,而不會相對 viewprot 定位。
- 如果
-
達到設定的閥值。這個還算好理解,也就是設定了
position:sticky
的元素表現爲relative
還是fixed
是根據元素是否達到設定了的閾值決定的。
關於<van-popup>高度問題:
給popPup組件添加高度官方默認的方式是:<van-popup v-model="show" position="top" :style="{ height: '20%' }" />
通過style設置。疑問要考慮到適配問題。整個項目用到了淘寶彈性佈局方案lib-flexible。它會給整個項目中所有css的px單位自動轉化爲rem。實現適配,但是通過style設置的px單位卻無能爲力。所以官方的實例<van-popup v-model="show" position="top" :style="{ height: '20%' }" />設置高度以後。會發現在iphonex上和iphone6/7/8表現差異很大。其實解決的辦法也很簡單。只要避免通過style暴力設置pup彈出層高度即可。刪除style設置高度的代碼。直接利用組件本身的高度
5 checkbox隱藏的問題
checkbox官方的api有說明:
change | 當綁定值變化時觸發的事件 | 當前組件的值 |
click | 點擊複選框時觸發 |
如果需要做一個類似全選的功能,如圖:
最頂上左側箭頭處。給checkbox按鈕添加點擊事件。結合官方全選和反選的demo,
<van-checkbox v-model="checkAllFlag" checked-color='var(--themeBgColor)' @change='checkAll'>{{supplierCode}}</van-checkbox>
checkAll(){
console.log('this.checkallFlag:',this.checkAllFlag)
this.$refs[this.supplierCode].toggleAll(this.checkAllFlag)
}
會發現全選和反選是界面上的效果和實際邏輯是相反的。也就說選擇全選按鈕。下面的商品是全不選。反正。這時候。我們需要改click事件爲change事件。也就說官方說的“當綁定值變化時觸發的事件“,然後效果正常。
5: 爲什麼vant list組件實現上拉加載--分頁。會出現連續觸發的問題?
我們需要知道幾個上限:
(1)如果後端返回的數據爲一一個空數組。則說明已經沒有數據了。此時我們需要通過list的finished=true表示已經沒有更多了。
(2)每次分頁,我們的數據都會添加到一個數組中,當改數組的長度大於或者等於後端返給我們的total值時,則表示已經加載了全部所有的數據。此時我們需要把finished給設置成true
只需要對這兩個臨界點做finished控制。就能避免load事件的重複請求。
之前代碼如下:
if(this.listData==0||this.listData.length>=total){
this.finished = true;
}else{
this.listData.concat(list)
}
發現沒有問題:
也可以寫成這樣:
this.list=this.list.concat(arr)
if(this.list.length>=total){
this.finished=true
}
6 頁面跳轉與toast彈出的問題:
問題呈現:有一個答題項目。每次答題如果回答正確則進入下一題。
核心邏輯如下
問題就在頁面會跳轉。但是this.$toast({message:"答題成功",type:"success"})無法執行。
個人推測this.$toast底層採用了異步機制。導致this.$router.push({name:"question",query:{pageNum:this.pageNum}})先執行。也就是頁面跳轉在先。而頁面棧的更新導致destoryed生命週期觸發。進而導致this.$toast()無法執行。
修復辦法。讓頁面跳轉在$.toast之後執行。通過setTimeout讓頁面跳轉的邏輯延遲執行,進入事件隊列
正確辦法: