最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuejs: Dynamic Recursive components (Tree Like Structure) - Stack Overflow

programmeradmin0浏览0评论

I am trying to make a custom ponent that calls the 'list' version of itself. i keep getting an error

Unknown custom element: - did you register the ponent correctly? For recursive ponents, 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 ponent

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

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

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

TestComp.vue <--- The Single ponent

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

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

Page.vue <-- The page passing the data

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

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

<script>
import TestCompList from "./TestCompList";
export default {
  ponents: {
    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 ponents

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?

I am trying to make a custom ponent that calls the 'list' version of itself. i keep getting an error

Unknown custom element: - did you register the ponent correctly? For recursive ponents, 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 ponent

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

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

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

TestComp.vue <--- The Single ponent

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

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

Page.vue <-- The page passing the data

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

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

<script>
import TestCompList from "./TestCompList";
export default {
  ponents: {
    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 ponents

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?

Share Improve this question asked Feb 15, 2018 at 15:22 Raymond AtivieRaymond Ativie 1,8283 gold badges28 silver badges51 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7

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.

This isn't quite the recursive problem that you thought, because if it was recursive, the ponent would be trying to call itself. Instead it's trying to declare a dependency on a ponent that, in turn, has a dependency on the ponent 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:

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

As the docs say, this wouldn't be a problem if you registered these ponents 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 ponents state it's dependency requirement at runtime in a beforeCreate hook.

New 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.ponents.TestComp = require("./TestComp.vue").default;
        }
    }

</script>

A more readable approach would be using Webpack’s asynchronous import

All you need to do is changing the ponents section of TestCompList.vue into this:

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

Your ponent name does not match the tag you are using

name: "TestComp",

<test-p>

Should be:

name: "test-p",

<test-p>
发布评论

评论列表(0)

  1. 暂无评论