Objects with an array as a prototype are not reactive
See original GitHub issueVue.js version
2.0.3
Reproduction Link
https://jsfiddle.net/yMv7y/1860/
Steps to reproduce
- Press the buttons.
What is Expected?
Both counters increment.
What is actually happening?
Very simply, Vue reactivity works for objects that are []
but not objects that have []
as a prototype. This is happening in Vue 2.0.
FancyArray.prototype = [];
function FancyArray() { }
new Vue({
data: {
normalArray: [],
objectWithArrayPrototype: new FancyArray()
},
watch: {
normalArray: function(a) {
console.log("normal array triggered", a);
},
objectWithArrayPrototype: function(a) { // THIS WATCH IS NEVER TRIGGERED
console.log("object with array prototype triggered", a)
}
},
created: function() {
this.normalArray.push("hey!"); // -> prints "normal array triggered, hey!"
this.objectWithArrayPrototype.push("hello again!"); // -> prints nothing
}
}).$mount('#app');
While this problem is easily circumvented by assigning a property in the object to be an array, it would be nice to be able to use objects that have an array as a prototype.
Issue Analytics
- State:
- Created 7 years ago
- Comments:11 (5 by maintainers)
Top Results From Across the Web
Object prototypes - Learn web development | MDN
Prototypes are the mechanism by which JavaScript objects inherit features from one another. In this article, we explain what a prototype is, how ......
Read more >vuejs prototype array not being watched - Stack Overflow
prototype are not reactive like a Vue instance's data properties. I agree that, in most cases, Jeff's method or using Vuex is the...
Read more >Reactivity in Depth - Vue.js
One of Vue's most distinct features is the unobtrusive reactivity system. Models are just plain JavaScript objects. When you modify them, the view...
Read more >Arrays, Objects and Mutations - Medium
Array.prototype.push allows us to push elements to the end of an array. This method does not return a new copy, rather mutates the...
Read more >Disabling Prototype Extensions - Configuration - Ember Guides
Native arrays will no longer implement the functionality needed to observe them. If you disable prototype extension and attempt to use native arrays...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The objects you are creating are in fact array-like objects and not real arrays. Vue only supports native Arrays or arrays that are real, proper sub-class of Array (only available in ES2015+), which can pass the
Array.isArray
check. This is an assumption made in multiple locations of the entire framework, adapting to it involves a lot of complexity for little gain - and is unlikely to be supported.Also - custom array-like objects likely have far worse performance than real arrays, and I personally recommend against that pattern.
I’m working on adding an extension to a library of mine and I ran into this problem as well. My first guess was to also just override
Array.isArray
to useinstanceof
but there were still errors (VueJS replaces the extended Array with a plain array - loosing your original object). I ended up doing something similar to what VueJS already does with arrays - decorate the array functions with new functions that callthis.__ob__.observeArray
when needed as well asthis.__ob__.notify()
(ifthis.__ob__
was defined). My collections trigger events, so this was my solution. It could similarly be applied to anyone else’s extended Array.