This article mainly introduces relevant information about list rendering, and shares it for your reference and learning. Let’s take a look at the detailed introduction below:
v-for
A list can be rendered based on an array using the v-for directive. This directive uses a special syntax, the form is item in items, items is the data array, and item is the alias for the current array element:
Example:
<ul > <li v-for="item in items"> {{ }} </li> </ul>
var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
In the v-for block we have full access to the properties within the scope of the parent component, and there is also a special variable $index, which, as you guessed, is the index of the current array element:
<ul > <li v-for="item in items"> {{ parentMessage }} - {{ $index }} - {{ }} </li> </ul>
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
Alternatively, you can specify an alias for the index (if v-for is used for an object, you can specify an alias for the object's key):
<div v-for="(index, item) in items"> {{ index }} {{ }} </div>
Starting from 1.0.17, you can use the of delimiter, which is closer to the JavaScript traverser syntax:
<div v-for="item of items"></div>
template v-for
Similar to template v-if, you can also use v-for on the <template> tag to render a block with multiple elements. For example:
<ul> <template v-for="item in items"> <li>{{ }}</li> <li class="divider"></li> </template> </ul>
Array change detection
Variation method
The variant methods of the observed array are wrapped, so they can trigger view updates.
The methods to be packaged are:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
You can open the browser's console and use these methods to modify the items array in the above example. For example:({ message: 'Baz' })
。
Replace array
The mutation method, as shown in the name, modified the original array. In contrast, there are non-mutation methods, such asfilter()
, concat()
andslice()
, does not modify the original array but returns a new array. When using non-mutated methods, you can directly replace the old array with the new array:
= (function (item) { return (/Foo/) })
Maybe you think this will lead to depreciating the existing DOM and re-rendering the entire list - luckily not. Implementing some heuristic algorithms to maximize the multiplexing of DOM elements, so replacing an array with another array is a very efficient operation.
track-by
Sometimes it is necessary to replace an array with a completely new object, such as an object created through an API call. Because v-for determines the degree of reusing existing scoped and DOM elements by default by the characteristics of the data object, this can result in re-rendering of the entire list. However, if each object has a unique ID attribute, you can use the track-by feature to give a prompt, so that existing instances can be reused as much as possible.
For example, assume that the data is:
{ items: [ { _uid: '88f869d', ... }, { _uid: '7496c10', ... } ] }
Then you can give a prompt like this:
<div v-for="item in items" track-by="_uid"> <!-- content --> </div>
Then when replacing the array items, if an inclusion is encountered_uid: '88f869d'
new object, it knows that it can reuse the scope of this existing object with the DOM element.
track-by $index
If there is no unique key for tracking, you can usetrack-by="$index"
, it forces v-for to enter the in-situ update mode: the fragment will not be moved, but will simply refresh with the new value of the corresponding index. This pattern can also handle duplicate values in the data array.
This makes data replacement very efficient, but it also costs a certain price. Because the DOM node no longer maps the order of array elements to change, the temporary state (such as the value of the <input> element) and the private state of the component cannot be synchronized. Therefore, if the v-for block contains a <input> element or child component, be careful to usetrack-by="$index"
question
Due to JavaScript limitations, the following array changes cannot be detected:
1. Set elements directly with indexes, such as[0] = {};
2. Modify the length of the data, such as = 0
。
To solve the problem (1), the observation array was extended, adding a$set()
method:
// Same as `[0] = ...`, but can trigger view update.$set(0, { childMsg: 'Changed!'})
As for question (2), just replace items with an empty array.
Apart from$set()
, also added to the observation array$remove()
Method, used to find and delete elements from the target array, internally it callssplice()
. Therefore, there is no need to:
var index = (item) if (index !== -1) { (index, 1) }
Just use this:
.$remove(item)
Object v-for
You can also use v-for to traverse objects. In addition to $index, another special variable, $key, can be accessed within the scope.
<ul class="demo"> <li v-for="value in object"> {{ $key }} : {{ value }} </li> </ul>
new Vue({ el: '#repeat-object', data: { object: { FirstName: 'John', LastName: 'Doe', Age: 30 } } })
You can also provide an alias for the object's key:
<div v-for="(key, val) in object"> {{ key }} {{ val }} </div>
When traversing the object, it is pressed()
traversal of the result, but it cannot be guaranteed that its results are consistent under different JavaScript engines.
Value range v-for
v-for can also receive an integer, at which point it will repeat the template several times.
<div> <span v-for="n in 10">{{ n }} </span> </div>
Show filtered/sorted results
Sometimes we want to display filtered/sorted arrays without actually modifying or resetting the original data. There are two ways:
1. Create a computed property to return the filtered/sorted array;
2. Use built-in filterBy and orderBy.
Computational properties have better control and are more flexible because it is full-featured JavaScript. But filters are usually more convenient, see the API for details.
Summarize
The above is the entire content of this article. I hope the content of this article will be of some help to your study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.