現(xiàn)象
我們先來(lái)看下面的一段代碼(可以丟到dotWe上自己運(yùn)行試試),用v-for產(chǎn)生兩個(gè)div,然后點(diǎn)擊按鈕觸發(fā)其中的一個(gè)div發(fā)生位置變化。
<template>
<div>
<div v-for="(item, index) of list" :key="index" :class="['box', pos[index]]" ></div>
<div class="btn" @click="onBtnClick"></div>
</div>
</template>
<style>
.box {
position: absolute;
left: 200px;
width: 50px;
height: 100px;
background-color: grey;
}
.btn {
top: 300px;
left: 300px;
width: 200px;
height: 150px;
background-color: blue;
}
.top1 {
top: 30px;
}
.top2 {
top: 150px;
}
</style>
<script>
export default {
data () {
return {
list: [1, 1],
pos: ['top1', 'top1']
}
},
methods: {
onBtnClick() {
this.pos[0] = this.pos[0]=='top1'?'top2':'top1'
}
}
}
</script>
試過(guò)之后,你會(huì)發(fā)現(xiàn),點(diǎn)擊按鈕并沒(méi)有任何變化??梢酝ㄟ^(guò)weex的debug工具查看到,其實(shí)div的top已經(jīng)變更為我們?cè)O(shè)置的值了,只是UI上沒(méi)有反應(yīng)出來(lái)。但是,如果改變top值的同時(shí),讓UI上的元素的內(nèi)容發(fā)生變化,比如有文字產(chǎn)生改變,那么UI能按照預(yù)期正常的顯示出來(lái)。
沒(méi)有動(dòng)態(tài)響應(yīng)的原因很簡(jiǎn)單,之前對(duì)vue的理解不夠透徹,忘記了vue對(duì)數(shù)組的動(dòng)態(tài)響應(yīng)前提是使用數(shù)組的push、pop等改變數(shù)組的方法,而直接通過(guò)索引賦值是不能被觀察到的。
解決
- 王道:用this.$set(obj, key, value)方法來(lái)改變數(shù)組元素
- 歪道:用this.$forceUpdate()這個(gè)函數(shù),讓我們可以強(qiáng)制組件進(jìn)行一次刷新。
補(bǔ)充
this.$forceUpdate()也只會(huì)在實(shí)際的style和class有變化的情況下才會(huì)起作用的,假如元素進(jìn)行動(dòng)畫(huà)前,opacity是1,而動(dòng)畫(huà)效果是讓元素的透明度變?yōu)?.5,那么動(dòng)畫(huà)完成后,即使當(dāng)前元素的效果是透明度0.5,但是因?yàn)閯?dòng)畫(huà)并不會(huì)真正改變?cè)貏?dòng)畫(huà)設(shè)置的style和class,所以opacity仍舊是1。
此時(shí),我們?nèi)ピO(shè)置opacity為1,并且this.$forceUpdate()強(qiáng)制更新,因?yàn)閛pacity的值前后并沒(méi)有變化,所以UI并不會(huì)改變。只有設(shè)置opacity為其他值,和之前的值不同,強(qiáng)制更新才能出來(lái)效果。
這點(diǎn)尤為要注意!