This is the 10th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
If you are already familiar with Vue, you will be familiar with the V-for directive as well. If you’ve used any of the other front-end frameworks, they also provide ways to loop data tags through HTML templates. Today’s article helps us understand why the key attribute is so important for V-for.
When I first started writing Vue, I rarely wrote the key property because it was not required, and it didn’t report errors or delay data rendering. But when ESLint rules require a key in a project, I use the index index as the key and proceed with development, as follows:
<h1 v-for="(item, index) in list" :key="index">{{ item.title }}</h1>
Copy the code
The term interpretation
So why do we need a key in our V-for loop?
This is because Vue can use keys to see what is changing in an array or object. V-for defaults to tracking changes by index index, so my use of index as an index above was redundant, although it solved the ESLint error. By tracking the Index index, Vue watches for changes in the order of items in the list and modifies each item in place when the order changes. The Vue documentation states that “this default pattern is efficient,” but also points out that it is not suitable for all situations.
As the Vue documentation states, we want to use unique ids for each element whenever possible so that Vue can more accurately track changes to items in the array and update component state, and be able to reuse and reorder existing components without having to re-render the entire loop.
For example
Now let’s use an example to illustrate the importance of the key attribute.
Suppose we have a list of books, and then we have a book-detail component that displays the name of the book, and a buy button, and then we loop through the book-detail component
The book-detail component code is as follows:
<div class="book">
<h1>{{ book.title }}</h1>
<div v-if="isCheckedOut" class="label">Buy now</div>
</div>
Copy the code
Component displays the title of the book and whether the book is available for purchase.
The JavaScript part of the component:
export default {
name: 'Book'.props: ['book'].data() {
return {
isCheckedOut: null}},mounted() {
this.checkBookStatus(this.book.id);
},
methods: {
checkBookStatus() {
axios.get(`/book-status/The ${this.book.id}`)
.then(res= > {
this.isCheckedOut = res.data.isCheckedOut; })}}}Copy the code
We pass in the information for the book through props, and then suppose we need to call the interface separately to check the status of the book and whether it can be purchased.
Then loop out the list of books:
<book-detail v-for="(book, index) in books" :key="index" :book="book"></book-detail>
Copy the code
Codepen. IO/cmdfas-the-…
This doesn’t look like a problem, and it doesn’t look like a problem on the page. And that’s the end of it? no
Suppose the user can add a new book to the system and ask to be added to the top of the list, not the bottom. If you add it to the bottom, there is no problem because the index is still the new value. If you add it to the top of the list, the index added to the top element will be the same as the index of the first book, which is 0, and so on. Only the index of the last book will be the new index.
Can you see what the problem might be here? If Vue does not properly trace the first index to the new index, the component will never be remounted, so checkBookStatus will never update the state of the book; instead, isCheckedOut will be the value of the previous book.
The easiest way to solve this problem is to set a unique key. I’ll use book.id as the key, and Vue will be able to properly track the changes and add the new component to the top and reorder the rest.
<book-detail v-for="(book, index) in books" :key="book.id" :book="book"></book-detail>
Copy the code
conclusion
Knowing how this works, we can choose to use V-for and key depending on the scenario. If we just insert data to the end of the array, or if it’s just a simple list, we don’t have any problems using indexes, because without sorting, Vue can correctly trace the new index. This is a good way to handle it (and the default way Vue uses it).
However, be sure to use a unique ID when you have the component’s own state in the component with props, or when you change the list in a way that doesn’t just add content at the end.
Also, for more useful information about use in V-for, I recommend checking out the official Vue documentation.