Home > OS >  How to overcome: 'v-slot' directive must be owned by a custom element, but 'slot'
How to overcome: 'v-slot' directive must be owned by a custom element, but 'slot'

Time:12-10

I have Vue.js app and the key part of the code of component looks as following:

specific-modal.vue:

<template>
  <v-modal-dialog
    :visible="isModalVisible"
    title="CONNECTION"
    okText="Save"
    cancelText="Cancel"
    :isSaveDisabled="isDisabled"
    :width="550"
    :height="620"
    @ok="onOk"
    @cancel="onCancel"
    @hiding="onHiding"
  >
    ...

base-modal.vue:

<template>
  <DxPopup
    v-bind="$attrs"
    :hide-on-outside-click="true"
    :drag-enabled="true"
    :wrapper-attr="popupAttributes"
    position="center"
    v-on="$listeners"
    @hiding="onHiding"
  >
    <slot />
    <slot name="footer">
      <DxToolbarItem template="save-template" toolbar="bottom" location="after" />
      <template #save-template>
        <DxButton text="Ok" @click="onOk" />
      </template>

      <DxToolbarItem template="cancel-template" toolbar="bottom" location="after" />
      <template #cancel-template>
        <DxButton text="Cancel" @click="onCancel" />
      </template>
    </slot>
  </DxPopup>
</template>

<script>
import { DxPopup, DxToolbarItem } from "devextreme-vue/popup";
import DxButton from 'devextreme-vue/button';
...

The #save-template is underlined with red line and there is a message:

'v-slot' directive must be owned by a custom element, but 'slot' is not.eslint-plugin-vue

How to overcome this isssue?

EDIT:

If I do as following:

<slot />
<slot name="footer">
  <DxToolbarItem template="save-template" toolbar="bottom" location="after" />
  <custom-element>
    <template #save-template>
      <DxButton text="TEST" @click="onOk" />
    </template>
  </custom-element>

  <DxToolbarItem template="cancel-template" toolbar="bottom" location="after" />
  <custom-element>
    <template #cancel-template>
      <DxButton text="Cancel" @click="onCancel" />
    </template>
  </custom-element>
</slot>

When I run the app, I'm getting the following error:

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

I'm not sure how to do it.

CodePudding user response:

<template #save-template is a shorthand for <template v-slot='save-template'.

So the eslint rule is complaining that the <template v-slot='save-template' is owned (has a parent) that is not a custom element (which is ).

<slot> is a like a placeholder that external components can use to add data. But in your code it seems like you are saying a placeholder has provided a placeholder inside it.

To overcome this either change parent slot tag to something else. Or, wrap template tag in a tag like:

<template>
    <DxPopup
        v-bind="$attrs"
        :hide-on-outside-click="true"
        :drag-enabled="true"
        :wrapper-attr="popupAttributes"
        position="center"
        v-on="$listeners"
        @hiding="onHiding"
    >
        <slot />

        <slot name="footer">
            <DxToolbarItem template="save-template" toolbar="bottom" location="after" />

            <!-- Add custom element wrapping here -->
            <custom-element>
                <template #save-template>
                    <DxButton text="TEST" @click="onOk" />
                </template>
            </custom-element>
        </slot>
    </DxPopup>
</template>

More details:

CodePudding user response:

I've found the solution on Stackoverflow:

<template>
  <DxPopup
    v-bind="$attrs"
    :hide-on-outside-click="true"
    :drag-enabled="true"
    :wrapper-attr="popupAttributes"
    position="center"
    v-on="$listeners"
    @hiding="onHiding"
  >
    <slot />
    <slot name="footer">
      <DxToolbarItem template="save-template" toolbar="bottom" location="after" />
      <DxToolbarItem template="cancel-template" toolbar="bottom" location="after" />
    </slot>

    <template #save-template>
      <DxButton text="TEST" @click="onOk" />
    </template>
    <template #cancel-template>
      <DxButton text="Cancel" @click="onCancel" />
    </template>
  </DxPopup>
</template>
  • Related