Subscribe on changes!

v-once inside v-for

avatar
Aug 11th 2021

Version

3.2.1

Reproduction link

SFC Playground

Steps to reproduce

Open the codepen, see that the v-for is displaying one one one rather than one two three.

<template>
  <div id="app">
    <div v-for="item in items" :key="item">
      <div contenteditable  v-once>
        {{ item }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: ['one', 'two', 'three']
    };
  }
};
</script>

What is expected?

I would expect to see a list of

one two three

What is actually happening?

A list of

one one one


Using v-once on the v-for element itself works fine, however when using v-once on an element inside a v-for the first element of the array is rendered out for each iteration of the loop.

I'm using this to stop a contenteditable element updating after initial load. Not massively worried about data sync so it works in my use case.

I can work around it by putting v-once on the v-for element, but for cases where you'd want reactive data showing up alongside data inside the v-once div that may not apply.

Edit

I actually can't use my workaround because I need to be able to remove/add elements to the array. In my mind the v-once should only apply when rendered by the v-for? I could be wrong here though.

avatar
Aug 11th 2021

I'm marking this as a bug but I suspect this is like v-memo: it wasn't supposed to be used on the children of the v-for but on the v-for directly (https://github.com/vuejs/vue-next/issues/4262)