Vue:将实例化的组件传递到插槽

时间:2018-08-14 16:51:53

标签: vuejs2 vue-component

我正在编写一个呈现文本的组件。当单词以“ @”开头时,它是用户的参考(例如在twitter中),我必须使用用户的信息创建工具提示。

这是我实例化用户的信息组件的方式(这很好,我在应用程序的其他位置使用它):

    const AvatarCtor = Vue.extend(AvatarTooltip);
    let avatarComponent = new AvatarCtor({
      propsData: {
        user: user
      }
    });

这是TooltipWrapper组件:

<template>
  <el-tooltip>
    <slot name="content" slot="content"></slot>
    <span v-html="text"></span>
  </el-tooltip>
</template>

<script>
  import {Tooltip} from 'element-ui';

  export default {
    name: "TooltipWrapper",
    components: {
      'el-tooltip': Tooltip
    },
    props: {
      text: String
    }
  }
</script>

这就是我将它们连接在一起的方式:

const TooltipCtor = Vue.extend(TooltipWrapper);
const tooltip = new TooltipCtor({
    propsData: {
        text: "whatever"
    }
});
tooltip.$slots.content = [avatarComponent];
tooltip.$mount(link);

这不起作用。但是,如果我在content插槽中设置了一些随机文本,则效果很好:

tooltip.$slots.content = ['some text'];

所以我的问题是我不知道如何将组件传递到插槽。我在做什么错了?

1 个答案:

答案 0 :(得分:1)

this.$slots是VNode,但是您分配了一个组件实例。

下面是一种方法(将组件安装到一个元素上,然后引用其vnode )以达到目标。

Vue.config.productionTip = false
const parentComponent = Vue.component('parent', {
  template: `<div>
  <div>
    <slot name="content"></slot>
    <span v-html="text"></span>
  </div>
</div>`,
  props: {
    text: {
      type: String,
      default: ''
    },
  }
})

const childComponent = Vue.component('child', {
  template: `<div>
  <button @click="printSomething()">@<span>{{user}}</span></button>
  <h4>You Already @ {{this.clickCount}} times!!!</h4>
</div>`,
  props: {
    user: {
      type: String,
      default: ''
    },
  },
  data(){
    return {
      clickCount: 1
    }
  },
  methods: {
    printSomething: function () {
      console.log(`already @${this.user} ${this.clickCount} times` )
      this.clickCount ++
    }
  }
})

const TooltipCtor = Vue.extend(parentComponent)
const tooltip = new TooltipCtor({
  propsData: {
    text: "whatever"
  }
})
const SlotContainer = Vue.extend(childComponent)
const slotInstance = new SlotContainer({
  propsData: {
    user: "one user"
  }
})
slotInstance.$mount('#slot')
tooltip.$slots.content = slotInstance._vnode
tooltip.$mount('#link')
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="link">
</div>
<div style="display:none"><div id="slot"></div></div>