简体   繁体   English

Vuejs:动态递归组件(树状结构)

[英]Vuejs: Dynamic Recursive components (Tree Like Structure)

I am trying to make a custom component that calls the 'list' version of itself.我正在尝试制作一个调用自身“列表”版本的自定义组件。 i keep getting an error我不断收到错误

Unknown custom element: - did you register the component correctly?未知的自定义元素: - 您是否正确注册了组件? For recursive components, make sure to provide the "name" option.对于递归组件,请确保提供“名称”选项。

I have included a name option as you can see below but this doesn't solve the problem.我已经包含了一个名称选项,如下所示,但这并不能解决问题。

Any idea what it could be?知道它可能是什么吗?

TestCompList.vue <-- The List component TestCompList.vue <-- List 组件

<template>
    <div>
        <p>I am a list</p>

        <template v-for="block in blocks">
            <test-comp :name="block.name" :header="block.name" :more="block.more" :key="block.id"></test-comp>
        </template>
    </div>
</template>

<script>
import TestComp from './TestComp';
export default {
    name: "TestCompList",
    components: {
        TestComp
    },
    props: ['blocks'],
}
</script>

TestComp.vue <--- The Single component TestComp.vue <--- 单一组件

<template>
    <div>
        <h3>{{header}}</h3>
        <p>{{name}}</p>
        <div class="mr-5" v-if="more">
            <test-comp-list :blocks="more"></test-comp-list>
        </div>
    </div>
</template>

<script>
import TestCompList from './TestCompList';
export default {
    name: "TestComp",
    props: ['header', 'name', 'more'],
    components: {
        TestCompList
    }
}
</script>

Page.vue <-- The page passing the data Page.vue <-- 传递数据的页面

<template>
    <div>
       <h3>Testing Recursive components</h3>

       <test-comp-list :blocks="blocks"></test-comp-list>
    </div>
</template>

<script>
import TestCompList from "./TestCompList";
export default {
  components: {
    TestCompList
  },
  data() {
    return {
      blocks: [
        {
          id: 1,
          name: "test1",
          header: "test1Header"
        },
        {
          id: 2,
          name: "test2",
          header: "test2Header"
        },
        {
          id: 3,
          name: "test3",
          header: "test3Header",
          more: [
            {
              id: 4,
              name: "test4",
              header: "test4Header"
            },
            {
              id: 5,
              name: "test5",
              header: "test5Header",
              more: [
                {
                  id: 6,
                  name: "test6",
                  header: "test6Header"
                },
                {
                  id: 7,
                  name: "test7",
                  header: "test7Header"
                }
              ]
            }
          ]
        }
      ]
    };
  }
};
</script>

Any ideas?有任何想法吗? I solved a similar problem here -> Vuejs: Dynamic Recursive components我在这里解决了类似的问题-> Vuejs: Dynamic Recursive components

But can't seem to apply the solution here.但似乎无法在这里应用解决方案。 Worst part is sometimes it seems to work and sometimes it doesn't最糟糕的部分是有时它似乎工作,有时它不

Help!帮助! What could i be missing?我可能会错过什么?

You have a circular dependency.你有一个循环依赖。 Look at the documentation directly below the recursive documentation: Circular References Between Components .查看递归文档正下方的文档: 组件之间的循环引用 You need to add a beforeCreate hook to pull in the child dependency at load time.您需要添加一个beforeCreate挂钩以在加载时引入子依赖项。

This isn't quite the recursive problem that you thought, because if it was recursive, the component would be trying to call itself.这并不是您想象的那种递归问题,因为如果它是递归的,组件就会尝试调用自身。 Instead it's trying to declare a dependency on a component that, in turn, has a dependency on the component that is trying to declare the dependency;相反,它试图声明对组件的依赖关系,而该组件又依赖于试图声明依赖关系的组件; hence the "circular".因此是“圆形”。

Effectively, the vue-loader doesn't know what to do since your dependency graph looks like:实际上, vue-loader不知道该做什么,因为您的依赖关系图如下所示:

Page -> TestCompList -> TestComp -> TestCompList -> TestComp -> ...

As the docs say, this wouldn't be a problem if you registered these components globally (but then you would have an unnecessarily broad dependency structure).正如文档所说,如果您在全局范围内注册这些组件,这将不是问题(但是您将拥有不必要的广泛依赖结构)。 The way to fix this without registering globally, is to have one of the components state it's dependency requirement at runtime in a beforeCreate hook.全局注册的情况下解决此问题的方法是让其中一个组件在运行时在beforeCreate挂钩中声明其依赖项要求。

New TestCompList.vue新的TestCompList.vue

<template>
    <div>
        <p>I am a list</p>

        <template v-for="block in blocks">
            <TestComp :name="block.name" :header="block.name" :more="block.more" :key="block.id"></TestComp>
        </template>
    </div>
</template>

<script>
    export default {
        name: "TestCompList",
        props: ['blocks'],
        beforeCreate: function(){
            this.$options.components.TestComp = require("./TestComp.vue").default;
        }
    }

</script>

A more readable approach would be using Webpack's asynchronous import更易读的方法是使用Webpack 的异步导入

All you need to do is changing the components section of TestCompList.vue into this:您需要做的就是将TestCompList.vue的 components 部分更改为:

        components: {
            TestComp: () => import('./TestComp.vue'),
        }

Your component name does not match the tag you are using您的组件名称与您使用的标签不匹配

name: "TestComp",

<test-comp>

Should be:应该:

name: "test-comp",

<test-comp>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM