Better solution
A better solution would be to use an external library to generate a hashcode from the value of your object and use that as an id. i.e. object-hash
An example using object-hash
const hash = objectHash; // this should be the import i.e. require('object-hash');
new Vue({
el: '#app',
template: `
<div>
<p v-for="item in itemsWithHash" :key="item.key">
{{item.name}} {{item.lastname}}<br>key: {{ item.key }}
</p>
</div>
`,
data: () => ({
items: [
{ name: 'john', lastname: 'doe' },
{ name: 'bob', lastname: 'smith' },
{ name: 'alice', lastname: 'james' }
]
}),
computed: {
itemsWithHash() {
return this.items.map(i => ({ ...i, key: hash(i) }));
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/object_hash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
OK Solution
You can use the index
of the iteration as a key, but keep in mind that this will not trigger changes on the view if you update the item by index. (Vue uses the key to detect changes, so it wont re-render the template if the key is not updated)
<div v-for="(item, i) in items" :key="i">
// some content.
</div>
Note the example below where mutating the items directly by index does not update the view but prints the change to the console:
new Vue({
el: '#app',
template: `
<div>
<p v-for="(item, index) in items" :key="index">
{{item.name}} {{item.lastname}}<br>index: {{ index }}
<button @click="changeForMary(index)"> Replace with Mary Smith</button>
</p>
</div>
`,
data: () => ({
items: [
{ name: 'john', lastname: 'doe' },
{ name: 'bob', lastname: 'smith' },
{ name: 'alice', lastname: 'james' }
]
}),
methods: {
changeForMary(index){
this.items[index] = { name: 'mary', lastname: 'smith' };
console.log(`index ${index} changed to ${JSON.stringify(this.items[index], null, '\t')}`);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/object_hash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
<el v-for="(item, key) in items" :key="key" />
. Do note this will fail to produce expected results when you actually care about elements order. For example, if you reorder them, it won't trigger an update (unless you use unique keys that are bound to an actualitem
property). – Crosspurpose