vue3 performance warning using ref

Viewed 10994

vue is throwing this message:

Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with markRaw or using shallowRef instead of ref.

<template>
      <component v-for="(el, idx) in elements" :key="idx" :data="el" :is="el.component" />
</template>



 setup() {
    const { getters } = useStore()
    const elements = ref([])
    onMounted(() => {
      fetchData().then((response) => {
        elements.value = parseData(response)
      })
    })
    return { parseData }
}

is there a better way to do this?

4 Answers

First, you should return { elements } instead of parseData in your setup i think.


I solved this issue by marking the objects as shallowRef :

import { shallowRef,  ref, computed } from 'vue'
import { EditProfileForm, EditLocationForm, EditPasswordForm} from '@/components/profile/forms'

const profile = shallowRef(EditProfileForm)
const location = shallowRef(EditLocationForm)
const password = shallowRef(EditPasswordForm)

const forms = [profile, location, password] 
<component v-for="(form, i) in forms" :key="i" :is="form" />

So you should shallowRef your components inside your parseData function. I tried markRaw at start, but it made the component non-reactive. Here it works perfectly.

you could manually shallowCopy the result

<component v-for="(el, idx) in elements" :key="idx" :data="el" :is="{...el.component}" />

I had the same error. I solved it with markRaw. You can read about it here!

my code :

import { markRaw } from "vue";
import Component from "./components/Component.vue";
data() {
    return {
      Component: markRaw(Component),
}

For me, I had defined a map in the data section.

<script>
import TheFoo from '@/TheFoo.vue';

export default {
  name: 'MyComponent',
  data: function () {
    return {
      someMap: {
        key: TheFoo
      }
    };
  }
};
</script>

The data section can be updated reactively, so I got the console errors. Moving the map to a computed fixed it.

<script>
import TheFoo from '@/TheFoo.vue';

export default {
  name: 'MyComponent',
  computed: {
    someMap: function () {
      return {
        key: TheFoo
      };
    }
  }
};
</script>
Related