使用 ref 的 vue3 性能警告

问题描述 投票:0回答:6

vue 正在抛出此消息:

Vue 接收到一个 Component,该 Component 被设为响应式对象。这个可以 导致不必要的性能开销,应该避免 用

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 }
}

有更好的方法吗?

vue.js vuejs3 vue-composition-api
6个回答
26
投票

首先,我认为您应该在设置中使用

return { 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] 
<component v-for="(form, i) in forms" :key="i" :is="form" />

所以你应该

shallowRef
你的组件在你的
parseData
函数中。我在开始时尝试了
markRaw
,但它使组件没有反应。在这里它完美地工作了。


21
投票

您可以手动浅复制结果

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

10
投票

我也有同样的错误。我用markRaw解决了这个问题。您可以在这里阅读有关内容!

我的代码:

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

2
投票

对我来说,我在

data
部分定义了一个地图。

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

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

数据部分可以进行反应式更新,所以我收到了控制台错误。将地图移动到计算的位置修复了它。

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

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

1
投票

我在显示 SVG 组件时收到此警告;根据我的推断,Vue 显示警告是因为它假设组件是反应性的,并且在某些情况下反应性对象可能很大,导致性能问题。

markRaw
API 告诉 Vue 不要担心组件的反应性,就像这样 -
markRaw(<Your-Component> or regular object)


1
投票

我今天也遇到了这个问题,这是我的解决方案:

setup() {
  const routineLayoutOption = reactive({
    board: {
      component: () => RoutineBoard,
    },
    table: {
      component: () => RoutineTable,
    },
    flow: {
      component: () => RoutineFlow,
    },
  });
}
我将组件变量设置为函数的结果。 在 中,像 compoennt() 一样绑定它

    <component
        :is="routineLayoutOption[currentLayout].component()"
      ></component>

© www.soinside.com 2019 - 2024. All rights reserved.