vuejs 递归单文件组件

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

未知的自定义元素:-您是否注册了该组件 正确吗?对于递归组件,请确保提供“名称” 选项。

我有一个包含 TreeList 的侧边栏,其中包含 TreeNode,每个 TreeNode 都包含一个 TreeList。

我读过很多关于其他人遇到此问题的文章。我尝试过一些解决方案,例如为组件指定烤肉串大小写名称。我已经读到这是命名空间的问题,我同意,因为我有一个使用单个文件中的所有组件的示例。当组件位于单独的文件中时,使用 vue CLI 重新加载我的脚本时会发生上述错误。有时,在保存文件时,在没有解释的情况下,错误消失并且递归再次起作用。

然后,当它正常工作时,单击子节点时会出现错误。

无法读取未定义的属性“长度” 在 simpleNormalizeChildren

这与 vue CLI 服务有关吗? 我愿意在全局命名空间中声明这些东西,但我不确定它是如何工作的。

import TreeList from './TreeList.vue'

export default {
    name: 'tree-node',
    components: {
        'tree-list': TreeList
    },

...

import TreeNode from './TreeNode.vue'

export default {
    name: 'tree-list',
    components: {
        'tree-node': TreeNode
    }

...

import TreeList from './TreeList.vue'
import TreeNode from './TreeNode.vue'

export default {
    name: 'Sidebar',
    components: {
        TreeList,
        TreeNode
    }
vue.js vuejs2
3个回答
12
投票

发生这种情况可能是因为 TreeList

TreeNode
组件之间的
循环引用
..

当你仔细观察时,你会发现这些组件实际上 成为渲染树中彼此的后代和祖先 - a 悖论!

要解决此悖论,您可以使用

Vue.component
全局注册您的组件,也可以将其中一个组件的导入推迟到稍后时间(通过将导入移至
beforeCreate
挂钩或使用 async Components 作为演示了这里)..

TreeList.vue

export default {
    name: 'tree-list',
    components: {
        'tree-node': () => import('./TreeNode.vue')
    }
    ...
}

0
投票

在 Vue 3 中,您可以使用异步组件:

export default {
  name: 'tree-list',
  components: {
    'tree-node': defineAsyncComponent(() => import('./TreeNode.vue'))
  }
}

文档:


0
投票

您可以将导入的组件作为数据传递。您甚至可以将它们作为 prop 或传递给 prop 的对象传递。

<!-- TheParent.vue -->
<template>
  <RecursiveComponent
    :nodes="nodes"
    :component="RecursiveComponent"
  />
</template>
<script>
import RecursiveComponent from '@/components/RecursiveComponent.vue';

export default {
  name: 'TheParent',
  components: {
    RecursiveComponent
  },
  data: function () {
    return {
      nodes: {
        a: {
          b: {
            c: 22
          }
        },
        d: 33
      }
    };
  },
  computed: {
    RecursiveComponent: function () {
      return RecursiveComponent;
    }
  }
};
</script>

<!-- RecursiveComponent.vue -->
<template>
  <ul>
    <li v-for="(value, key) in nodes">
      <strong>{{ key }}: </strong>
      <template v-if="typeof(value) !== 'object'">
        {{ nodes[key] }}
      </template>
      <component
        v-else
        :is="component"
        :nodes="value"
        :component="component"
      />
    </li>
  </ul>
</template>
<script>
export default {
  name: 'RecursiveComponent',
  props: {
    nodes: {
      type: Object,
      required: true
    },
    component: {
      type: Object,
      required: true
    }
  }
};
</script>

注:

  • 这在本地运行良好,当您构建生产项目时,但某些在线编辑器(如 CodeSandbox)将难以实时更新递归代码。
  • 该组件存储在
    computed
    部分,可供模板访问。你可以将它存储在
    data
    中,但 Vue 警告它会变得反应式(这不太好)。如果使用
    这个插件
    ,您也可以将其放在constants部分。
import RecursiveComponent from '@/components/RecursiveComponent.vue';

export default {
  name: 'TheParent',
  components: {
    RecursiveComponent
  },
  constants: {
    RecursiveComponent
  },
  data: function () {
    return {
      nodes: {
        a: {
          b: {
            c: 22
          }
        },
        d: 33
      }
    };
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.