Vue插槽slot的用法

2.6.0中,使用v-slot(以前具名插槽:slot,作用域插槽:slot-scope)。

v-slot的几种用法

用法一 插槽内容—template

核心:承载组件的分发内容。

// 定义,在 <navigation-link> 的模板中
<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

// 调用,调用<navigation-link>对应的组件
<navigation-link url="/profile">
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

// 渲染结果
<a
  v-bind:href="url"
  class="nav-link"
>
  <span class="fa fa-user"></span>
  Your Profile
</a>
用法一 插槽内容—render
// 定义,在 <navigation-link> 的render函数中
render: function (createElement) {
  // `<div><slot></slot></div>`
  return createElement('div', this.$slots.default)
}

// 调用,调用<navigation-link>对应的组件
同上

// 渲染结果
同上
用法二 后备内容

核心:插槽可以设置默认内容

// 定义
<button type="submit">
  <slot>Submit</slot>
</button>

// 调用
<submit-button></submit-button>

// 渲染结果
<button type="submit">
  Submit
</button>
用法三 具名插槽

核心:插槽内容与插槽通过名称一一对应

// 定义
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

// 调用
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

// 渲染结果
<div class="container">
  <header>
     <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
     <p>Here's some contact info</p>
  </footer>
</div>
用法四 作用域插槽—template用法

核心:父组件中插槽内容调用子组件中数据,处理后在插槽中渲染内容。

// 定义,其中user为该current-user组件的一个实例属性user:{firstName:xing, lastName:ming}
<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

// 调用
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

// 渲染结果
<span>
  xing
</span>
用法四 作用域插槽—渲染函数用法

核心:vm.$scopedSlots等于 < slot > 标签

// 定义,子组件
Vue.component('child', {
  name: "child",
  render: function (createElement) {
    return createElement('div', [
      this.$scopedSlots.default({
        text: "scopedSlots 测试"
      })
    ])
    // `<div><slot :text="'scopedSlots 测试'"></slot></div>`
  }
});

// 调用,父组件
import child from './child.vue';
Vue.component('parent', {
  name: "parent",
  components: {
    child
  },
  render: function (createElement) {
    return createElement('div', [
      createElement('child', { // 引用子组件
        scopedSlots: {// 获取子组件的scopedSlots
          default: function (props) {// 获取scopedSlots.default,命名为props
            return createElement('span', props.text) // scopedSlots.default.text
          }
        }
      })
    ])
    /*
    <div>
    	<child v-slot:default='slotProps'>
    		<span>{{ slotProps.text }}</span>
    	</child>
    </div>
    */
  }
});

// 渲染结果
<div>
  <div>
    <span>scopedSlots 测试</span>
  </div>
</div>
用法五 遍历示例

核心:for循环中每一项都有各自的不同的插槽内容。

// 定义
<ul>
  <li
    v-for="todo in filteredTodos"
    v-bind:key="todo.id"
  >
    <!--
    我们为每个 todo 准备了一个插槽,将 `todo` 对象作为一个插槽的 prop 传入。
    -->
    <slot name="todo" v-bind:todo="todo">
      <!-- 后备内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

// 调用
<todo-list v-bind:todos="todos">
  <template v-slot:todo="{ todo }">
    <span v-if="todo.isComplete">✓</span>
    {{ todo.text }}
  </template>
</todo-list>

// 渲染结果
/* 假设 todos=[
		{id: 0, text: '列表0', isComplete: true}, 
	    {id: 1, text: '列表1', isComplete: true}
	]
*/
<ul>
  <li
    key="0"
  >
    列表0
  </li>
  <li
    key="1"
  >
    列表1
  </li>
</ul>
<div>
	<child scopedSlots=>
	</child>
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值