Vueは配列やオブジェクトの変動を検出できない問題の解決
5427 ワード
例を見てみましょう.
実現したい効果はliをクリックしてvmを見ることです.nymbers[index]が存在するか、存在しない場合は1、存在する場合は1を加算します.
クリックした後、数字はviewレイヤで更新されず、console印刷でデータが更新されたことが分かったが、viewレイヤはタイムリーに検出されなかった.
もう一つの変更を見てみましょう.
Vue 2を見てみましょう.0公式のドキュメントの説明:
JavaScriptの制限により、Vueは以下の変動する配列を検出できません.インデックスを使用して直接アイテムを設定する場合、たとえば 配列の長さを変更すると、例えば、 第1の問題を解決するために、以下の2つの方法は、
まだ使えます
インスタンスメソッド、グローバルのみ
を選択します.
それともJavaScriptの制限のため、Vueはオブジェクト属性の追加または削除を検出できません:
作成したインスタンスに対して、Vueはルートレベルのレスポンス属性を動的に追加できません.ただし、使用可能
メソッドネストされたオブジェクトに応答プロパティを追加します.たとえば、次のようになります.
既存のオブジェクトに複数の新しいプロパティを割り当てる必要がある場合があります.たとえば、
または
.この場合、2つのオブジェクトのプロパティで新しいオブジェクトを作成する必要があります.新しいレスポンス属性を追加したい場合は、次のようにしないでください.
したがって、上記の例は次のように変更する必要があります.
1.17補足------------------------------------------------------------------------------------------------------------
作成したインスタンスに対して、Vueはルート・レベルのレスポンス・プロパティを動的に追加できません.
例:
上は正しいやり方ですが、下のやり方は間違っています.
実はvm.dataはundefinedです.
vue
-
{{item.name}}
{{numbers[index]}}
var vm = new Vue({
el: ".wrap",
data: {
numbers: [],
items: [
{name: 'jjj'},
{name: 'kkk'},
{name: 'lll'},
]
},
methods: {
handle: function (index) {
// WHY: ,view , console
if (typeof(this.numbers[index]) === "undefined" ) {
// : 。
// 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)
}
}
});
実現したい効果はliをクリックしてvmを見ることです.nymbers[index]が存在するか、存在しない場合は1、存在する場合は1を加算します.
クリックした後、数字はviewレイヤで更新されず、console印刷でデータが更新されたことが分かったが、viewレイヤはタイムリーに検出されなかった.
もう一つの変更を見てみましょう.
vue
-
{{item.name}}
var vm = new Vue({
el: ".wrap",
data: {
// numbers: [],
items: [
{name: 'jjj'},
{name: 'kkk'},
{name: 'lll'},
]
},
methods: {
handle: function (index) {
// , view
this.items[index].name += " success";
// console.log(this.numbers)
}
}
});
はここのviewレイヤがタイムリーに更新されるのを見ることができますが、配列のどこに行けばいいのでしょうか.Vue 2を見てみましょう.0公式のドキュメントの説明:
JavaScriptの制限により、Vueは以下の変動する配列を検出できません.
vm.items[indexOfItem] = newValue
vm.items.length = newLength
vm.items[indexOfItem] = newValue
と同じ効果を達成し、同時に状態更新をトリガすることができる.// 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`
vm.b = 2
// `vm.b`
作成したインスタンスに対して、Vueはルートレベルのレスポンス属性を動的に追加できません.ただし、使用可能
Vue.set(object, key, value)
メソッドネストされたオブジェクトに応答プロパティを追加します.たとえば、次のようになります.
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
既存のオブジェクトに複数の新しいプロパティを割り当てる必要がある場合があります.たとえば、
Object.assign()
または
_.extend()
.この場合、2つのオブジェクトのプロパティで新しいオブジェクトを作成する必要があります.新しいレスポンス属性を追加したい場合は、次のようにしないでください.
Object.assign(this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
は、次のようにする必要があります.this.userProfile = Object.assign({}, this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
したがって、上記の例は次のように変更する必要があります.
vue
-
{{item.name}}
{{numbers[index]}}
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]);
}
}
}
});
できました!1.17補足------------------------------------------------------------------------------------------------------------
作成したインスタンスに対して、Vueはルート・レベルのレスポンス・プロパティを動的に追加できません.
例:
var vm=new Vue({
el:'#test',
data:{
//data info
info:{
name:' '
}
}
});
// info
Vue.set(vm.info,'sex',' ');
上は正しいやり方ですが、下のやり方は間違っています.
Vue.set(vm.data,'sex',' ')
実際には、dataに直接属性を追加することはできませんが、data内のオブジェクトに属性を追加することができます.実はvm.dataはundefinedです.