使用 ref 的 vue3 性能警告

cla*_*.io 5 vue.js vuejs3 vue-composition-api

vue 正在抛出此消息:

Vue 收到了一个组件,它是一个响应式对象。这会导致不必要的性能开销,应该通过用markRaw或shallowRef代替 标记组件来避免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 }
}

Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

Ben*_*aud 25

首先,我认为您应该在设置中返回 { elements }而不是 parseData 。


我通过将对象标记为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] 
Run Code Online (Sandbox Code Playgroud)
<component v-for="(form, i) in forms" :key="i" :is="form" />
Run Code Online (Sandbox Code Playgroud)

因此,您应该在 parseData 函数中shallowRef您的组件。我在开始时尝试了 markRaw,但它使组件无反应。在这里它工作得很好。

  • 如果我这样做,则不会渲染任何内容,并且会收到以下警告“组件缺少模板或渲染函数”。如果我不使用shallowRef,组件就会被渲染,但我会收到另一个警告“Vue收到了一个被制成反应式对象的组件”。有任何想法吗? (6认同)

ali*_*ili 21

你可以手动浅复制结果

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

  • 这对我有用,尽管它没有记录并且非常简单...... (2认同)

小智 10

我有同样的错误。我用markRaw解决了这个问题。你可以在这里读到它!

我的代码:

import { markRaw } from "vue";
import Component from "./components/Component.vue";
data() {
    return {
      Component: markRaw(Component),
}
Run Code Online (Sandbox Code Playgroud)