Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v-for to support Array-like objects #5893

Closed
privatenumber opened this issue Jun 16, 2017 · 19 comments
Closed

v-for to support Array-like objects #5893

privatenumber opened this issue Jun 16, 2017 · 19 comments

Comments

@privatenumber
Copy link
Contributor

What problem does this feature solve?

Allow iterating over smart Arrays that extend/inherit the Array (instance of the Array) or something like arguments (not an instance of the Array).

What does the proposed API look like?

No change in API

@yyx990803
Copy link
Member

yyx990803 commented Jun 16, 2017

I don't think we can support arbitrary Array-like objects - the line between a actual "object" vs. "array-like" is blurry. We will stick to Array.isArray in this case. But we can and should support Array subclasses.

Also - since subclassing Array is a ES6+ feature, we will likely implement this when we re-implement the reactivity system with Proxies.

@nickmessing
Copy link
Member

Offtopic: @yyx990803, I've seen in some discussion that you didn't want to switch to proxies for reactivity because it creates a new object instead of editing the initial one, what has changed?

@privatenumber
Copy link
Contributor Author

@yyx990803 Sounds good. Thanks.

BTW, all that seems to be necessary to qualify interpreting an object as an array (logging it with square brackets) in V8 seems to be a numerical index and a function in splice: ({ length: 0, splice(){} })

@nickmessing
Copy link
Member

As an alternative we could use iterator protocol which works with way more iterable structures than just array and array-likes (Map, Set, Iterator)

@yyx990803
Copy link
Member

yyx990803 commented Jun 16, 2017

@nickmessing that difference is still there so it will introduce some breaking changes, also the browser compatibility constraints means we will only do it for v3.

@nickmessing
Copy link
Member

OFFTOPIC: @yyx990803, if that is already a plan maybe it's a nice idea to have a v3 discussion issue about possible breaking/browser compatibility changes?

@yyx990803
Copy link
Member

@nickmessing currently the only planned change in v3 is the reactivity system and browser compatibility (dropping IE for only evergreen browsers). The breaking changes would be minimal (only in terms of observed object equality) and the API will remain the same.

@nickmessing
Copy link
Member

nickmessing commented Jun 16, 2017

@yyx990803, what about using v-for for Map and Set? I've seen people asking that once in a while. If support of old browsers is gone then Symbol.iterator with for of is available everywhere.

P.S. that solves this issue too

@yyx990803
Copy link
Member

@nickmessing yup, those will also be supported in v3.

@privatenumber
Copy link
Contributor Author

Just to clarify, I don't believe subclassing the Array is a ES6+ feature. What if I just inherit it ES5 style?

function Collection () {
     Array.apply(this);
}

Collection.prototype = Object.create(Array.prototype);

Object.assign(Collection.prototype, {
   ...methods
});

@yyx990803
Copy link
Member

That's not true subclassing - see this for more details. Only ES6+ supports something like class Collection extends Array {}.

@mitar
Copy link
Contributor

mitar commented Jul 9, 2017

What about support for objects defining iteration protocols? So instead of relaying on inheritance, we could check if an object defines an iterator and then use that to iterate? This would probably not break backwards compatibility and could be done already now.

@nickmessing
Copy link
Member

@mitar, as @yyx990803 said few comments ago, v-for will be using Symbol.iterator in v3 when we drop support for old browsers. Actual implementation works differently and I don't think it's a good idea to support "new" iteration while we support IE9+.

@mitar
Copy link
Contributor

mitar commented Jul 9, 2017

Just for reference, this is how I implemented support for iterators in Meteor's Vue fork. I do not see it breaking anything if it would be already implemented in v2, but this is your call.

@nickmessing
Copy link
Member

@mitar, why not for of?

That's Evan's call and looks like he decided that to be a part of v3, from my point of view if we support IE9+ we should not have code that will work only in newer browsers.

@mitar
Copy link
Contributor

mitar commented Jul 10, 2017

Hm, good question. I don't know if existing Vue code uses for of, so I just didn't want to use it myself.

@mrliptontea
Copy link

Iteration protocol does not ensure that iterator can be rewound (like generators), which means it will break when render function is called again. Also, array-likes generally don't simply read values from memory but do some extra work which shouldn't be repeated on each render.

That being said I don't think you would need to be able to iterate through array-like or custom object directly. Instead, you need array representation of underlying values (e. g. in a computed property), which will always be a native Array. Or possibly other built-in iterable, when they're supported.

@mitar
Copy link
Contributor

mitar commented Jul 17, 2017

Iteration protocol does not ensure that iterator can be rewound (like generators)

But you can obtain a new iterator object when you want to iterate again?

const iterator = arrayLike[Symbol.iterator]();

And then you iterate. And you can call this as many times as you want. The same happens if you do not manually obtain an iterator, but use JS syntax.

@yyx990803
Copy link
Member

Closing (lack of actionable items before v3)

ashtonmeuser pushed a commit to ashtonmeuser/vue-cloudwatch-dashboard that referenced this issue Oct 10, 2018
Honestly don't know why Array subclass worked before. Refer to vuejs/vue#4049, vuejs/vue#6943, vuejs/vue#5893.
ashtonmeuser added a commit to ashtonmeuser/vue-cloudwatch-dashboard that referenced this issue Oct 10, 2018
Honestly don't know why Array subclass worked before. Refer to vuejs/vue#4049, vuejs/vue#6943, vuejs/vue#5893.
happyman125 added a commit to happyman125/Vue_Dashboard that referenced this issue Jan 28, 2020
Honestly don't know why Array subclass worked before. Refer to vuejs/vue#4049, vuejs/vue#6943, vuejs/vue#5893.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants