Как использовать слоты в HTML с однофайловыми компонентами - PullRequest
0 голосов
/ 12 июня 2019

Я хочу использовать слоты в Vue для создания динамического модального компонента.

Я уже пробовал много уроков по Vue / slots, но ни один из них не является именно тем, что я ищу.

Это часть моего modal.vue:

<template>
  ...
    <slot name="modal-body"></slot>
  ...
</template>
<script>
</script>
<style>
</style>

Это мой скомпилированный файл JavaScript:

import Vue from 'vue';
import modal from './modal.vue';

new Vue({
  el: '#modal',
  render: r => r(modal)
});

Это часть моего HTML-файла:

...
<div id="modal">
  <template v-slot="modal-body">
    <input type="text" id="dynamic-input">
  </template>
</div>
...

Я ожидал, что все элементы, присутствующие внутри #modal (в данном случае #dynamic-input), были вставлены в слот с именем modal-body внутри моего элемента Vue. Возможно ли это сделать? Я что-то упустил?

1 Ответ

0 голосов
/ 12 июня 2019

Проверьте, какую версию Vue вы используете. Синтаксис именованных слотов изменен в 2.6.0. Рассмотрим различия ниже. Один использует функции рендеринга, а другой шаблон Strings.

Vue@2.6.10

// Example using template String
const modalTemplateString = {
  template: "<div><div>above</div><slot name=\"modal-body\"></slot><div>below</div></div>"
};

const appTemplateString = new Vue({
  el: "#appTemplateString",
  components: {
    modal: modalTemplateString
  },
  template: "<div><modal><template v-slot:modal-body><div>foobar</div></template></modal></div>"
});

// Example using render function
const modalRenderFunc = {
  render(h) {
    return h("div", [
      h("div", "above"),
      h("div", this.$slots["modal-body"]),
      h("div", "below")
    ]);
  }
}

const appRenderFunc = new Vue({
  el: "#appRenderFunc",
  components: {
    modal: modalRenderFunc
  },
  render(h) {
    return h("div", [
      h("modal", [
        h("div", {
          slot: "modal-body"
        }, "foobar")
      ])
    ]);
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

<h2>Template String</h2>
<div id="appTemplateString"></div>
<hr/>
<h2>Render Function</h2>
<div id="appRenderFunc"></div>

Vue@2.5.22

// Example using template String
const modalTemplateString = {
  template: "<div><div>above</div><slot name=\"modal-body\"></slot><div>below</div></div>"
};

const appTemplateString = new Vue({
  el: "#appTemplateString",
  components: {
    modal: modalTemplateString
  },
  template: "<div><modal><template slot=\"modal-body\"><div>foobar</div></template></modal></div>"
});

// Example using render function
const modalRenderFunc = {
  render(h) {
    return h("div", [
      h("div", "above"),
      h("div", this.$slots["modal-body"]),
      h("div", "below")
    ]);
  }
}

const appRenderFunc = new Vue({
  el: "#appRenderFunc",
  components: {
    modal: modalRenderFunc
  },
  render(h) {
    return h("div", [
      h("modal", [
        h("div", {
          slot: "modal-body"
        }, "foobar")
      ])
    ]);
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>

<h2>Template String</h2>
<div id="appTemplateString"></div>
<hr/>
<h2>Render Function</h2>
<div id="appRenderFunc"></div>
...