代码之家  ›  专栏  ›  技术社区  ›  Harshal Patil

如何创建Vue。js插槽编程?

  •  20
  • Harshal Patil  · 技术社区  · 6 年前

    我有以下带插槽的组件:

    <template>
        <div>
            <h2>{{ someProp }}</h2>
            <slot></slot>
        </div>
    </template>
    

    由于某些原因,我必须手动实例化此组件。我就是这样做的:

    const Constr = Vue.extend(MyComponent);
    const instance = new Constr({
        propsData: { someProp: 'My Heading' }
    }).$mount(body);
    

    问题是:我无法以编程方式创建插槽内容。 到目前为止,我可以创建简单的基于字符串的插槽:

    const Constr = Vue.extend(MyComponent);
    const instance = new Constr({
        propsData: { someProp: 'My Heading' }
    });
    
    // Creating simple slot
    instance.$slots.default = ['Hello'];
    
    instance.$mount(body);
    

    问题是-我如何创建 $slots 并将其传递给我正在使用 new ?

    注意:我没有使用Vue的完整版本。js(仅限运行时)。所以我没有Vue。js编译器可用于动态编译模板。

    4 回复  |  直到 5 年前
        1
  •  14
  •   Harshal Patil    6 年前

    我查看了 Vue.js 我在Vue组件实例上发现了一个未记录的函数: $createElement() .我的猜测是,传递给 render(createElement) 组件的功能。因此,我可以通过以下方式来解决:

    const Constr = Vue.extend(MyComponent);
    const instance = new Constr({
        propsData: { someProp: 'My Heading' }
    });
    
    // Creating simple slot
    const node = instance.$createElement('div', ['Hello']);
    instance.$slots.default = [node];
    
    instance.$mount(body);
    

    但这显然是非法的,因此值得怀疑。如果有更好的方法可用,我不会标记它的答案。

        2
  •  4
  •   Andrew H    6 年前

    我想我终于找到了一种以编程方式创建slot元素的方法。据我所知,这种方法似乎不适用于功能组件。我不知道为什么。

    如果要为组件实现自己的渲染方法,可以使用createElement方法(或在渲染方法中使用别名的任何方法)以编程方式创建传递给子元素的插槽,并传递一个数据哈希,其中包括{slot:NAME\u OF\u your\u slot},后跟该插槽中的子元素数组。

    例如:

    Vue.config.productionTip = false
    Vue.config.devtools = false;
    
    Vue.component('parent', {
      render (createElement) {
        return createElement('child', [
          createElement('h1', { slot: 'parent-slot' }, 'Parent-provided Named Slot'),
          createElement('h2', { slot: 'default' }, 'Parent-provided Default Slot')
        ])
      }
    })
    
    Vue.component('child', {
      template: '<div><slot name="parent-slot" /><slot /></div>'
    })
    
    new Vue({
      el: '#app',
      template: '<parent />'
    })
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    
    <div id='app'>
    </div>
        3
  •  1
  •   Jacob Goh    6 年前

    (这不是真正的答案 How to create Vue.js slot programatically? .但它确实解决了你的问题。)

    与使用 $createElement()

    基本上,创建一个注册的新组件 MyComponent 作为本地组件。

    const Constr = Vue.extend({
      template: `
      <MyComponent someProp="My Heading">
        <div>slot here !!!</div>
      </MyComponent>
      `,
      components: {
        MyComponent: MyComponent
      }
    });
    const instance = new Constr().$mount('#app');
    

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

        4
  •  0
  •   Disco12    5 年前

    我刚刚在vue论坛上找到了一个答案: slots

    原则是:没有任何东西像createElement('slot'…) 相反,有一个渲染函数提供 开槽的 innerHtml作为函数: $ScopedLots。默认值()

    用法:

    render: function (createElement) {
      const self = this;
      return createElement("div", this.$scopedSlots.default());
    }

    如果希望在没有为插槽提供内容的情况下提供默认设置,则需要自己编写一个DiscTintion并呈现其他内容。 (上面的链接提供了一个更详细的示例)

    该函数返回一个数组,因此不能将其用作渲染函数的根。它需要包装到单个容器节点中,如 部门 在上述示例中。