解決Vue不能檢測數(shù)組或?qū)ο笞儎拥膯栴}
來看一個實例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
<style>
li:hover {
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrap">
<ul>
<li v-for="item,index in items" v-on:click="handle(index)">
<span>{{item.name}}</span>
<span>{{numbers[index]}}</span>
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: ".wrap",
data: {
numbers: [],
items: [
{name: 'jjj'},
{name: 'kkk'},
{name: 'lll'},
]
},
methods: {
handle: function (index) {
// WHY: 更新數(shù)據(jù),view層未渲染,但通過console這個數(shù)組可以發(fā)現(xiàn)數(shù)據(jù)確實更新了
if (typeof(this.numbers[index]) === "undefined" ) {
// 注:下面這么設(shè)置是可以的。例如
// var arr = [];
// arr[3]=3;
// console.log(arr) //[empty × 3, 3]
this.numbers[index] = 1;
// this.numbers.splice(index,0,1) //用splice方法能同步顯示,但得不到想要的效果
} else {
this.numbers[index]++;
// this.numbers.splice(index,1,this.numbers[index]++)
}
// console.log(this.numbers)
}
}
});
</script>
</body>
</html>
想實現(xiàn)的效果是點擊 li 看 vm.nymbers[index] 是否存在,不存在設(shè)置為1,存在的話加1。
點擊之后數(shù)字并沒有在view層更新,而通過console打印發(fā)現(xiàn)數(shù)據(jù)更新了,只是view層沒有及時的檢測到。
再看一個改動之后的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
<style>
li:hover {
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrap">
<ul>
<li v-for="item,index in items" v-on:click="handle(index)">
<span>{{item.name}}</span>
<!--<span>{{numbers[index]}}</span>-->
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: ".wrap",
data: {
// numbers: [],
items: [
{name: 'jjj'},
{name: 'kkk'},
{name: 'lll'},
]
},
methods: {
handle: function (index) {
// 不是數(shù)組,這里更新數(shù)據(jù)就可以直接在view層渲染
this.items[index].name += " success";
// console.log(this.numbers)
}
}
});
</script>
</body>
</html>
可以看到這里的view層能及時得到更新,但是到了數(shù)組哪里為什么就不可以了呢?
來看Vue2.0官方的文檔說明:
由于 JavaScript 的限制,Vue 不能檢測以下變動的數(shù)組:
當(dāng)你利用索引直接設(shè)置一個項時,例如:vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長度時,例如:vm.items.length = newLength
為了解決第一類問題,以下兩種方式都可以實現(xiàn)和 vm.items[indexOfItem] = newValue 相同的效果,同時也將觸發(fā)狀態(tài)更新:
// Vue.set Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice example1.items.splice(indexOfItem, 1, newValue)
你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名。
還是由于 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 現(xiàn)在是響應(yīng)式的
vm.b = 2
// `vm.b` 不是響應(yīng)式的
對于已經(jīng)創(chuàng)建的實例,Vue 不能動態(tài)添加根級別的響應(yīng)式屬性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套對象添加響應(yīng)式屬性。例如,對于:
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
有時你可能需要為已有對象賦予多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應(yīng)該用兩個對象的屬性創(chuàng)建一個新的對象。所以,如果你想添加新的響應(yīng)式屬性,不要像這樣:
Object.assign(this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
應(yīng)該這樣做:
this.userProfile = Object.assign({}, this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
因此,上面例子應(yīng)該改為:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
<style>
li:hover {
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrap">
<ul>
<li v-for="item,index in items" v-on:click="handle(index)">
<span>{{item.name}}</span>
<span>{{numbers[index]}}</span>
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: ".wrap",
data: {
numbers: [],
items: [
{name: 'jjj'},
{name: 'kkk'},
{name: 'lll'},
]
},
methods: {
handle: function (index) {
if (typeof(this.numbers[index]) === "undefined" ) {
this.$set(this.numbers, index, 1); //(arr,index,newvalue)
} else {
this.$set(this.numbers, index, ++this.numbers[index]);
}
}
}
});
</script>
</body>
</html>
搞定!
1.17補充-------------------------------
如何理解“對于已經(jīng)創(chuàng)建的實例,Vue 不能動態(tài)添加根級別的響應(yīng)式屬性”?
例如:
var vm=new Vue({
el:'#test',
data:{
//data中已經(jīng)存在info根屬性
info:{
name:'小明'
}
}
});
//給info添加一個性別屬性
Vue.set(vm.info,'sex','男');
上面是正確做法,下面的做法的話就會報錯了:
Vue.set(vm.data,'sex','男')
實際上,不能直接在data上增加屬性,但可以在data里的對象上增加屬性。
實際上vm.data是undefined。
以上這篇解決Vue不能檢測數(shù)組或?qū)ο笞儎拥膯栴}就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue 判斷兩個時間插件結(jié)束時間必選大于開始時間的代碼
這篇文章主要介紹了vue 判斷兩個時間插件結(jié)束時間必選大于開始時間的代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
淺談VUE防抖與節(jié)流的最佳解決方案(函數(shù)式組件)
這篇文章主要介紹了淺談VUE防抖與節(jié)流的最佳解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Vue動態(tài)權(quán)限登錄實現(xiàn)(基于路由與角色)
很多應(yīng)用都會需要對不同的用戶進行權(quán)限控制,本文主要介紹了Vue動態(tài)權(quán)限登錄實現(xiàn)(基于路由與角色),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
一文詳細(xì)聊聊vue3的defineProps、defineEmits和defineExpose
vue3官方文檔defineProps和defineEmits都是只能在scriptsetup中使用的編譯器宏,下面這篇文章主要給大家介紹了關(guān)于vue3的defineProps、defineEmits和defineExpose的相關(guān)資料,需要的朋友可以參考下2023-02-02

