Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vue.js filters in v-for

I was wondering about using filters in vue

I know computed and when i use it but my question is

i used this code to sort fruits array instead of using computed

<li v-for="fruit in fruits.sort() ">{{fruit }}</li>

it run and i got the result correctly

but console notified me for error

[Vue warn]: You may have an infinite update loop in a component render function. 
(found in <MyFilter> at C:\xampp\htdocs\projects\max\___explaning\169_filters_mixins\src\MyFilter.vue)
warn @ VM6599:564
flushSchedulerQueue @ VM6599:2340
(anonymous) @ VM6599:511
nextTickHandler @ VM6599:460

when i removed .sort() the warn disappeared

the question : why this warn appeared and is there any way to add .sort() to v-for array without using computed values

like image 924
Mustafa Agamey Avatar asked Apr 23 '17 18:04

Mustafa Agamey


People also ask

Where do you put Vue filters?

Going off number 2, because VueJS filters are meant for text transformations, they can only be used in two places: mustache interpolations (the curly braces in your template) and in v-bind expressions.

What are the filters in VueJS?

A Filter is a simple JavaScript function which is used to change the output of a data to the browser. Filters in Vue. JS don't change the data directly wherever we store them, it only applies formatting to our data. The data remains the same only the output of a data to a browser is changed.

What is V for in VueJS?

v-for directive is a Vue. js directive used to loop over a data usually an array or object. First, we will create a div element with id as app and let's apply the v-for directive to an element with data. Now we will create this data by initializing a Vue instance with the data attribute containing the value.

What is the shorthand of V on click in VueJS?

Vue has a convenient shorthand for v-on : the @ symbol. For example, @click is functionally equivalent to v-on:click .


1 Answers

You're getting the error because you are creating an infinite loop when calling fruit.sort() in the v-for statement.

fruit.sort() causes the array of be mutated (updated) and when Vue gets notified of this update, it attempts to update the DOM and then evaluate the v-for statement. This again will call fruit.sort() and then trigger an update.

Naive answer:

Instead you could use v-for="fruit in fruits.map(f => f).sort()", although this may become quite heavy if the list is somewhat large. What this does is two things: 1) fruits.map(f => f) creates a new array containing the same values as fruits, and then 2) it sorts the newly created one.

Better answer:

Rather than inlining the copying and sorting inside the template (where it shouldn't be, you could use a method which does the same. You want to put as much logic as possible outside of the templates.

{
    ...Other component properties...

    methods: {
        sorted(arr) {
            // Return a copy of the sorted array
            return arr.map(e => e).sort()
        }
    }

    ...Other component properties...
}

Also better answer:

If you'd been using Vue 1.x, you could have used filters for this (v-for="fruit in fruits | orderBy", but using filters outside of text interpolation ({{ }}) has been removed from Vue 2.x and instead Vue's official migration guide suggests using computed properties for this exact thing.

Now, I'd still suggest not mutating the array inside the computed properties, but instead copy the array first and then sorting it, or perhaps even follow their guide and use lodash's orderBy(...) function for this.

{
    ...Other component properties...

    computed: {
        sortedFruits() {
            // Return a copy of the sorted array
            return this.fruits.map(f => f).sort()
        }
    }

    ...Other component properties...
}

Hope this helps.

Edit: Here's a pen displaying this.

like image 145
kristofferostlund Avatar answered Oct 18 '22 00:10

kristofferostlund