Vue 收到了一个组件,它是一个响应式对象

Posted

技术标签:

【中文标题】Vue 收到了一个组件,它是一个响应式对象【英文标题】:Vue received a Component which was made a reactive object 【发布时间】:2021-09-21 21:21:27 【问题描述】:

我需要解决的问题:我正在写一个基于VueJS3的小vue-app。

我有很多不同的侧边栏,我需要防止同时打开多个侧边栏的情况。

为了存档我正在关注this article。

现在我遇到了一个问题:

Vue 收到了一个组件,该组件被制成了一个反应性对象。这可能会导致不必要的性能开销,应通过使用markRaw 标记组件或使用shallowRef 而不是ref 来避免。 (6)

这是我的代码:

SlideOvers.vue

<template>
    <component :is="component" :component="component" v-if="open"/>
</template>
<script>

export default 
    name: 'SlideOvers',
    computed: 
        component() 
            return this.$store.state.slideovers.sidebarComponent
        ,
        open () 
            return this.$store.state.slideovers.sidebarOpen
        ,
    ,

</script>

UserSlideOver.vue

<template>
    <div>test</div>
</template>
<script>

export default 
    name: 'UserSlideOver',
    components: ,
    computed: 
        open () 
            return this.$store.state.slideovers.sidebarOpen
        ,
        component () 
            return this.$store.state.slideovers.sidebarComponent
        
    ,

</script>

slideovers.js (vuex-store)

import * as types from '../mutation-types'

const state = 
    sidebarOpen: false,
    sidebarComponent: null


const getters = 
    sidebarOpen: state => state.sidebarOpen,
    sidebarComponent: state => state.sidebarComponent


const actions = 
    toggleSidebar (commit, state, component) 
        commit (types.TOGGLE_SIDEBAR)
        commit (types.SET_SIDEBAR_COMPONENT, component)
    ,
    closeSidebar (commit, state, component) 
        commit (types.CLOSE_SIDEBAR)
        commit (types.SET_SIDEBAR_COMPONENT, component)
    


const mutations = 
    [types.TOGGLE_SIDEBAR] (state) 
        state.sidebarOpen = !state.sidebarOpen
    ,

    [types.CLOSE_SIDEBAR] (state) 
        state.sidebarOpen = false
    ,

    [types.SET_SIDEBAR_COMPONENT] (state, component) 
        state.sidebarComponent = component
    


export default 
    state,
    getters,
    actions,
    mutations

App.vue

<template>
    <SlideOvers/>
    <router-view ref="routerView"/>
</template>

<script>
import SlideOvers from "./SlideOvers";

export default 
    name: 'app',
    components: SlideOvers,
;
</script>

这就是我尝试切换一个幻灯片的方式:

<template>
  <router-link
      v-slot=" href, navigate "
      to="/">
    <a :href="href"
       @click="$store.dispatch ('toggleSidebar', userslideover)">
        Test
    </a>
  </router-link>
</template>
<script>
import defineAsyncComponent from "vue";

export default 
  components: 
  ,
  data() 
    return 
      userslideover: defineAsyncComponent(() =>
          import('../../UserSlideOver')
      ),
    ;
  ,
;
</script>

【问题讨论】:

【参考方案1】:

按照警告的建议,在usersslideover 的值上使用markRaw 来解决警告:

export default 
  data() 
    return 
      userslideover: markRaw(defineAsyncComponent(() => import('../../UserSlideOver.vue') )),
    
  

demo

【讨论】:

以上是关于Vue 收到了一个组件,它是一个响应式对象的主要内容,如果未能解决你的问题,请参考以下文章

Vue 3 使用异步 json 设置响应式获取

Vue3和Vue2响应式的区别

浅析vue响应式原理

vue2响应式原理总结

深入Vue的响应式原理

vue数组和对象响应式杂谈