如何在DOM中指定子组件的位置?

时间:2017-10-27 11:10:57

标签: javascript vue.js vuejs2

考虑一个Vue组件my-wrapper

<template>
  <div class="inner">
    <div class="outer">
      <!-- render children here? -->
    </div>
  </div>
</template>

它的目的是这样使用:

<template>
  <my-wrapper>
    <h1>Cards</h1>
    <card :data="card1"/>
    <card :data="card2"/>
  </my-wrapper>
</template>

如何在my-wrapper组件中指定子组件的位置?

Bonus 是否也可以传入已命名的子组件并将它们放在Vue.js模板中的不同位置?像这样的事情? (这显然不起作用):

<template>
  <div>
    <div class="left">
      <place-child ref-name="left"></place-child>
    </div>
    <div class="right">
      <place-child ref-name="left"></place-child>
    </div>
  </div>
</template>

my-wrapper的使用示例:

<template>
  <my-wrapper>
    <card ref="left" :data="card1"/>
    <card ref="right" :data="card2"/>
  </my-wrapper>
</template>

2 个答案:

答案 0 :(得分:2)

Vue使用content distribution with slots支持此功能。您可以使用<slot>元素标记模板中要渲染子项的插槽。您还可以使用named slots在模板中包含多个不同的目标。

使用插槽非常简单:

Vue.component('my-wrapper', {
  template: `
    <div>
      <div class="box left">
        <slot name="left"></slot>
      </div>
      <div class="box right">
        <slot name="right"></slot>
      </div>
      <div class="after">
        <slot>
          This is some default content
        </slot>
      </div>
    </div>
  `
});

var app = new Vue({
  el: '#app',
});
.box {
  width: calc(50% - 10px);
  border: 1px solid blue;
  min-height: 20px;
  margin: 4px;
}
.box.left {
  float: left;
}
.box.right {
  float: right;
}
.after {
  clear: both;
}

#app > div {
  border-bottom: 1px solid #CCC;
  margin-bottom: 10px;
}
<div id="app">
  <!-- This on just displays the default content -->
  <my-wrapper></my-wrapper>
  
  <!-- Here, the default content is overwritten -->
  <my-wrapper>
    Hello world!
  </my-wrapper>
  
  <!-- Left slot and overwriting the unnamed slot -->
  <my-wrapper>
    <template slot="left">Some left content</template>
    And overwriting the default
  </my-wrapper>

  <!-- Right slot, but keeping the default content -->
  <my-wrapper>
    <template slot="right">Just right content</template>
  </my-wrapper>
  
  <!-- All combined. We don’t have to use the template element -->
  <my-wrapper>
    <div slot="left">Some logo</div>
    <ul slot="right">
      <li>Item 1</li>
      <li>Item 2</li>
    </ul>
    <p>This is some new content</p>
  </my-wrapper>
</div>

<script src="https://unpkg.com/vue/dist/vue.js"></script>

答案 1 :(得分:1)

快速举例:

<template id="my-wrapper">
  <div>
    <div class="left">
      <slot name="left"></slot>
    </div>
    <div class="right">
      <slot name="right"></slot>
    </div>
  </div>
</template>

用法:

<template>
  <my-wrapper>
    <card slot="left" :data="card1"></card>
    <card slot="right" :data="card2"></card>
  </my-wrapper>
</template>