背景
簡單做個冒泡排序的效果,vue數(shù)據(jù)交換過后視圖不刷新
解決方案總結(jié)
序號 | 方法 | 備注 |
---|---|---|
1 | 對數(shù)據(jù)進(jìn)行拆裝箱 | 相當(dāng)于直接更新數(shù)據(jù) |
2 | Vue.set(target, key, value) | vue提供的方法簡潔明了 |
3 | 對item進(jìn)行組件封裝使用watch監(jiān)聽 | 針對于內(nèi)容復(fù)雜的個人推薦 |
栗子??
<template>
<div class="bubbling">
<div class="report">
<div class="item"
v-for="(itm, inx) in arr"
:key="inx"
:tip="itm"
:style="{height: itm+'px'}"></div>
</div>
</div>
</template>
<script>
import Vue from 'Vue'
export default {
name: 'bubbling',
data () {
return {
arr: []
}
},
mounted () {
this.buildArray()
},
methods: {
buildArray () {
for (let i = 0; i < 10; i++) {
this.arr.push(parseInt(Math.random() * 90 + 10))
}
this.beginSort()
},
beginSort () {
let step = 1
for (let i = 0; i < this.arr.length; i++) {
for (let j = 0; j < this.arr.length; j++) {
step++
setTimeout(() => {
if (this.arr[i] < this.arr[j]) {
let temp = this.arr[i]
/** 方案1 拆裝箱
* this.arr[i] = this.arr[j]
* this.arr[j] = temp
* this.arr = JSON.parse(JSON.stringify(this.arr))
*/
// 方案2 vue.set
Vue.set(this.arr, i, this.arr[j])
this.$set(this.arr, j, temp)
}
}, step * 200)
}
}
}
}
}
</script>
<style lang="scss" scoped>
.bubbling {
.report {
margin: 100px auto;
display: flex;
height: 150px;
width: 460px;
border-left: 1px solid #666;
border-bottom: 1px solid #666;
align-items: flex-end;
.item {
width: 40px;
height: 100px;
background: #9ee;
margin-left: 5px;
text-align: center;
position: relative;
transition:all .1s
}
.item::before {
content: attr(tip);
position: absolute;
width: 40px;
height: 20px;
line-height: 20px;
left: 0px;
top: -20px;
text-align: center;
font-size: 14px;
color: #666;
}
}
}
</style>
知識點
能觸發(fā)vue視圖更新的方法
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
無效的
// 直接設(shè)置值
this.arr[index] = value;
根本原因
vue2 是通過defineProperty翔试,進(jìn)行遍歷監(jiān)聽屬性尘颓,所以無法監(jiān)聽到對象的刪除等操作
如下:observe是一個類似的原理實現(xiàn)
const observe = (obj: any) => {
for (const key in obj) {
let val = obj[key]
if (typeof val === 'object' && val != null) {
observe(val)
}
Object.defineProperty(obj, key, {
get () {
console.log(key, '讀取', val)
return val
},
set (nVal) {
if (nVal !== val) {
console.log(key, '更改', nVal)
val = nVal
}
}
})
}
}
const obj = {
id: 1,
name: '關(guān)羽',
age: 22,
equip: {
head: '',
weaponry: '砍柴刀'
}
}
observe(obj)
obj.equip.weaponry = '青龍偃月刀'
console.log(obj.name)