1
votes

Let's say I have an App.vue file with the following

<template>
    <task-list>
        <task>Task 1</task>
        <task>Task 2</task>
    </task-list>
</template>
<script>
import TaskList from './tasklist.vue'
export default {
    //...
    components: {
        TaskList
    }
    //...
}
</script>

a TaskList.vue

<template>
    <ul>
        <slot></slot>
    </ul>
</template>
<script>
import Task from './task.vue'
export default {
    //...
    name: 'task-list'
    components: {
        Task
    }
    //...
}
</script>

a Task.vue

<template>
    <li><slot></slot></li>
</template>
<script>
export default {
    name: 'task',
    //...
}
</script>

and a main.js

import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
})

How do I import the sub-component Task.vue only once in TaskList.vue without also having to import it again in App.vue

It seems that if I do it this way, I get an error back from VueJS complaining about unregistered components

[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> at src/App.vue

Is there a way to indicate that task is a sub-component of task-list without global registration or importing again in App.vue?

2
Why don't you include the Task component inside the TaskList component template. This would make more sense. Or is there a specific reason why you choose not to do that?puelo
@puelo I mean for other cases where I just want to have components nested inside eachother that are related, like how li is always a child of ul, I want to know if there's a way to say that this component is a sub-component of another so I can just import tasks in App.vue instead of tasks and taskxort
The normal way would be to create a TaskList and define a property which can be passed down and then inside the TaskList you create the list (however the syntax might be) containing the task sub-components. I don't think you can import multiple components by just importing the parent (unsure). (TaskList example: jsfiddle.net/5xy17zs8/2)puelo

2 Answers

1
votes

If you register Task in TaskList.vue,

then you can only use <task> in TaskList.vue's template.


Try this: App.vue use props to pass tasks (an array) to TaskList.vue

App.vue

<template>
    <task-list :tasks="tasks"></task-list>
</template>
<script>
import TaskList from "./tasklist.vue";
export default {
  //...
  data() {
    return {
      tasks: ['Task 1', 'Task 2']
    };
  },
  components: {
    TaskList
  },
  //...
};
</script>

TaskList.vue

<template>
  <ul>
    <task v-for="task in tasks" :key="task">{{ task }}</task>
  </ul>
</template>

<script>
import Task from './Task.vue';
export default {
  name: "task-list",
  props: {
    tasks: {
      type: Array,
      default: () => []
    }
  },
  components: {
    Task
  }
  //...
};
</script>

Full example app:

Edit Vue Template

1
votes

add a custom component task in App.vue:

<template>
  <task-list>
    <task>Task 1</task>
    <task>Task 2</task>
  </task-list>
</template>

<script>
import TaskList from './tasklist.vue'
import Task from './Task.vue'

export default {
    //...
    components: {
        TaskList,
        Task
    }
    //...
}
</script>