【问题标题】:Vue pass slot template to extended componentVue 将插槽模板传递给扩展组件
【发布时间】:2017-08-19 20:24:07
【问题描述】:

有没有办法将模板传递给扩展组件?举例说明问题:

有一个名为 Slide 的组件,其模板如下:

<template>
    <div class="swiper-slide swiper-slide-one">
        <div class="swiper-filter"></div>
        <slot />
    </div>
</template>

在其他地方,我需要以命令式样式创建和安装该组件:

import SlideComponent from '@/components/Slide'
const Slide = Vue.extend(SlideComponent);
new Slide().$mount('#container');

问题是我不知道如何传递将在扩展组件的插槽中编译的模板。

jsfiddle

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您可以将Vue.compile$createElement 结合使用。

    const slotTemplate = `<div><h4>This is the slot content</h4>{{message}}</div>`;
    const renderer = Vue.compile(slotTemplate)
    const slotContent = {
      data(){
        return {
          message: "some data in the slot"
        }
      },
      render: renderer.render,
      staticRenderFns: renderer.staticRenderFns
    }
    
    const instance = new Slide();
    instance.$slots.default = [instance.$createElement(slotContent)];
    instance.$mount("#container");
    

    以上是需要一些数据的插槽示例。如果您的广告位内容只是 HTML,您可以只用这个:

    const slotTemplate = `<div><h4>This is the slot content</h4></div>`
    const instance = new Slide();
    instance.$slots.default = [instance.$createElement(Vue.compile(slotTemplate))];
    instance.$mount("#container");
    

    这是example

    注意: $slots[key] should be an array of vNodes。如果您使用 vNode,它将正确呈现,但会有错误(例如调用 vm._update 时)

    【讨论】:

    • @Edd 您的编辑被拒绝,但我将其添加到答案中。你是对的。
    • 请记住,子组件(如果有)将在下一个刻度之前可用。如果将其简化为 mixin 或方法,则可以返回一个承诺以公开创建的子组件。
    • 如果有人想更改广告位内容怎么办? vm.$slots.default = [ ]vm.$slots.default.push(somevnode) 好像没用?
    【解决方案2】:

    如果您愿意稍微改变您的方法,请使用 &lt;component&gt; 而不是 &lt;slot&gt;

    https://jsfiddle.net/jonataswalker/z5Lgbjv8/

    const Parent = {
      template: `<div>
            <span>parent content</span>
          <component :is="view"></component>
        </div>`,
      data() {
        return { view: '' }
      }
    }
    
    const Other = {
      template: `<div>
            <h1>from Other</h1>
        </div>`
    }
    
    const Slide = Vue.extend(Parent)
    
    // how to pass template to the Parent`s slot?
    new Slide({
      data: { view: Other }
    }).$mount('#container')
    

    【讨论】:

      【解决方案3】:

      (这个问题与SO question 类似。我将在此处分享我针对该问题发布的类似答案。)

      诀窍很简单。基本上,在扩展时,创建一个将Parent 注册为本地组件的新组件。

      演示:https://jsfiddle.net/jacobgoh101/omjgmb3f/

      const Slide = Vue.extend({
        components: {
          Parent
        },
        template: `
        <Parent>
          <div style="color:red">I am a slot</div>
        </Parent>
      `
      });
      new Slide().$mount('#container')
      

      【讨论】:

        【解决方案4】:

        如果您可以更改源代码结构, 您还应该能够使用 jsx。 在 Vue-Cli3 中它需要额外的 babel 插件,在 Nuxt 中它是开箱即用的)。 您只需创建一些钩子函数作为方法或计算,例如:

        slotHook () {
          return(
          <template v-slot.../>
        )}
        

        并将其放在渲染函数中。 然后,在子组件(扩展默认组件)中,你覆盖了 slotHook 方法:

        slotHook () {
          return (
            <template v-slot... some-differen-params:.../>
        )}
        

        这种方法在渲染过程中不会导致任何错误/问题,并且可以完美运行。 其他方法可能是使用 PUG 模板及其块和扩展功能。 我知道我发布此回复很晚,但也许它可以帮助某人。

        【讨论】:

          【解决方案5】:

          你必须像这样传递它:

          <Slide>
             //HTML code here goes to slot
          </Slide>
          

          【讨论】:

          • 我无法控制需要安装组件的位置的模板。所以问题是如何从代码中传递槽数据...
          • 你能解释一下你到底在看什么吗?
          猜你喜欢
          • 2018-09-14
          • 2020-04-23
          • 2019-01-21
          • 2018-11-11
          • 2020-03-12
          • 2021-03-07
          • 1970-01-01
          • 2018-12-27
          • 2020-02-14
          相关资源
          最近更新 更多