這兩天終於真正接觸到了uni-app——其實就是一款基於vue的多端融合產品,它可以調用任意平臺的api,以達到“可以順利登陸各平臺”的目的。
寫demo的時候遇到點麻煩:
由於使用了v-if
條件判斷,所以元素展示很“突兀”,定義的transform
根本沒有效果!
解決辦法:
- 改用
v-show
- 使用
$nextTick()
+setTimeout()
方法:
css:
.create-content{
position:fixed;
/* ... */
transition:all .3s;
opacity:0;
transform:scale(0) translateY(200%);
}
.create__show{
opacity:1;
transform:scale(1) translateY(0);
}
index.vue:
<view v-if="active" class="create-content" :class="{'create__show':textShow}">
</view>
js:
methods:{
create(){
this.active=true
this.$nextTick(()=>{
setTimeout(()=>{
this.textShow=true
},50)
})
},
//...
}
$nextTick() 的用法:
Vue 異步執行 DOM 更新。只要觀察到數據變化,Vue 將開啓一個隊列,並緩衝在同一事件循環中發生的所有數據改變。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩衝時去除重複數據對於避免不必要的計算和 DOM 操作上非常重要。然後,在下一個的事件循環“tick”中,Vue 刷新隊列並執行實際 (已去重的) 工作。Vue 在內部嘗試對異步隊列使用原生的
Promise.then
和MessageChannel
,如果執行環境不支持,會採用setTimeout(fn, 0)
代替。
所以,關於這個api的使用,有一下幾點“規定”:
- 在Vue生命週期的created()鉤子函數進行的DOM操作一定要放在
Vue.nextTick()
的回調函數中
在created()
鉤子函數執行的時候DOM 其實並未進行任何渲染,而此時進行DOM操作無異於徒勞,所以此處一定要將DOM操作的js代碼放進Vue.nextTick()
的回調函數中。與之對應的就是mounted()
鉤子函數,因爲該鉤子函數執行時所有的DOM掛載和渲染都已完成,此時在該鉤子函數中進行任何DOM操作都不會有問題 。
- 在數據變化後要執行的某個操作,而這個操作需要使用隨數據改變而改變的DOM結構的時候,這個操作都應該放進
Vue.nextTick()
的回調函數中。
實現一個簡單的 $nextTick() 方法:
let callbacks=[];
let pending=false;
function nextTick(cb){
callbacks.push(cb);
if(!pending){
pending=true;
setTimeout(flushCallbacks,0);
}
}
function flushCallback(){
pending=false;
const pipes=callbacks.slice(0);
callbacks.length=0;
for(let i=0;i<pipes.length;i++){
pipes[i]();
}
}
如何開啓一個uni-app項目:
- 在HBuilderX中,直接點擊“創建項目”->“uni-app項目”即可
- 在其他編譯器如VSCode中,可以藉助【cli工具】(命令行):
vue create -p dcloudio/uni-preset-vue 項目名稱
,回車 選擇“默認模板”即可