Skip to content

Deprecate v-repeat in favor of v-for #1200

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

Closed
yyx990803 opened this issue Aug 24, 2015 · 27 comments
Closed

Deprecate v-repeat in favor of v-for #1200

yyx990803 opened this issue Aug 24, 2015 · 27 comments
Milestone

Comments

@yyx990803
Copy link
Member

I am working on a new version of v-repeat, which is significantly more performant than the current version, but introduces a few breaking differences in terms of scoping. In order to keep backwards compatibility in the 1.0 migration, this new version will be introduced as v-for so that the original v-repeat can be left intact.

Current status: all tests passed. You can test v-for in the current 1.0.0-alpha branch.

Difference between v-for and v-repeat

Required alias

Alias is required when using v-for, and the item in items syntax is preferred. It reads more naturally:

<li v-for="item in items"></li>

This also means the $value meta property will no longer be used. $index and $key are still available. You can also still refer to the parent scope index in nested loops as $parent.$index.

No more anonymous child VMs

Previously, v-repeat creates an actual child VM instance with inherit: true for every repeated block. This is no longer the case with v-for: each repeated block in v-for is now a real partially compiled fragment, with a lightweight intermediate "scope". This greatly reduces the overhead and as a result you should see significant performance improvement for both initial rendering (up to 100% for non-component loops) and re-rendering with track-by (up to 50%, as tested in dbmonster).

This also means:

  1. Using an extra <template> repeat no longer creates the overhead of a child instance.
  2. v-ref would not work on v-for if the repeated block is not a component, because there are no longer anonymous child instances created in that case.

Component Scoping

Now this is the part that is the most different. Previously when you use a component with v-repeat, you get somewhat weird scoping:

<!-- can't use $index here -->
<comp v-repeat="item in list"></comp>

In the above example, item and $index are automatically available inside the component, but not in the parent template. If you do want to use $index in the parent template, you have to create a <template> to wrap the repeat. In addition, this requires the component implementation to be aware that it is v-repeat specific, because the external data is not received via the standard props interface.

With v-for, you get the expected scoping:

<!-- using 1.0.0 binding syntax -->
<comp
  v-for="item in list"
  bind-id="$index"
  bind-data="item">
</comp>

And you need to explicitly pass external data into the component as props. This makes your component implementation no longer v-repeat specific and less magical.

@yyx990803 yyx990803 added this to the 1.0.0-alpha milestone Aug 24, 2015
@sdebacker
Copy link

Nice ! How can we install this version via npm ?

@dominiquedutra
Copy link

@sdebacker This is a proposal for 1.0.
@yyx990803 is proposing some changes and people will provide feedback.

@sdebacker
Copy link

Yes but these proposed changes are already pushed to 1.0.0-alpha branch.

@yyx990803
Copy link
Member Author

@sdebacker You can install a branch as npm install yyx990803/vue#1.0.0-alpha. Note the branch is unstable, so use at your own risk.

@sdebacker
Copy link

Thanks but it returns no matches found: yyx990803/vue#1.0.0-alpha

@yyx990803
Copy link
Member Author

@sdebacker what version of npm are you using?

@sdebacker
Copy link

I just upgrade npm to 2.12.1 via homebrew, perhaps I need 2.14 ?

@yyx990803
Copy link
Member Author

weird... I just tried it and it works... maybe a typo? ;)

@thelinuxlich
Copy link

+1 great proposal

@kazupon
Copy link
Member

kazupon commented Aug 24, 2015

+1

5 similar comments
@davidkhess
Copy link

+1

@Pandahisham
Copy link

+1

@pespantelis
Copy link

👍

@OEvgeny
Copy link

OEvgeny commented Aug 25, 2015

👍

@ChristopherDosin
Copy link

+1

@azamat-sharapov
Copy link

Component Scoping

So, this: <comp v-for="item in list" id="{{$index}}" data="{{item}}"></comp> is still compiled on parent's scope, except $index, $key and item being on v-for's scope?

@yyx990803
Copy link
Member Author

Implemented in alpha branch.

@sdebacker
Copy link

@yyx990803 I switched from zsh to bash and I can now run npm install yyx990803/vue#1.0.0-alpha

@mattymil
Copy link

So if I am interpreting this correctly, deprecation of v-repeat in lieu of the v-for will create true partials as opposed to vms. Within the standard use case, will we experience any loss of functionality when passing this object back to event handlers?

@yyx990803
Copy link
Member Author

@mattymil I've yet to see a use case where the anonymous child vm is necessary. In most cases you pass the item of item in items into an event handler, which is the data object from the repeated Array.

@mattymil
Copy link

mattymil commented Sep 7, 2015

ok interesting. Thanks

On Sep 5, 2015, at 3:16 PM, Adam Patarino [email protected] wrote:

So in practice, with dynamic components, when passing data to children we currently do something like this:



And with this new spec it would more like this?




Reply to this email directly or view it on GitHub https://github.com/yyx990803/vue/issues/1200#issuecomment-137987605.

@jonathanpmartins
Copy link

+1

@furybean
Copy link

So by the doc in rc.vuejs.org, this syntax is not support in 1.0.0?

<li v-for="items"></li>

@simplesmiler
Copy link
Member

@furybean it's not supported, you have to use v-for="item in items".

@furybean
Copy link

@simplesmiler Thanks.

@blocka
Copy link

blocka commented Dec 26, 2015

A little late to the party but...
Not sure if this was a "feature" of v-repeat but using the alias syntax allowed you to store data on the VM, such as application (component) state. For example, if you wanted to turn on editing mode for an item in your list you could do: $data.$('editing',true) and you wouldn't have to dilute your object.

Since v-for is no longer using a VM, I'm assuming this is no longer possible. Is there a clean workaround? Or maybe I'm not understanding the change (I have actually not moved over to v1.x yet, so I haven't had a chance to experiment, but I am looking at a current code base and trying to evaluate the pain involved).

@caoliangsong
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests