回首Vue3之指令篇(八)

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战html

这篇文章咱们来说一下v-slot的使用方法,以及在使用它的时候咱们须要注意的地方。vue

如何使用

v-slot结合<slot>元素提供具名插槽或须要接收 prop 的插槽。v-slot的简写为#,只可用于<template>组件中。编程

基础使用

假定咱们自定义一个组件my-button为:markdown

<button>   
    <slot>提交</slot> 
</button>
复制代码

slot元素中,咱们能够给默认值(使用组件不传内容的时候会显示默认值,不然默认值会被替换),也能够为空,直接为<slot></slot>。那么咱们该怎么去使用这个组件呢,以下:app

<my-button>
    1. 此处什么都不放,编译后显示默认值
    
    2. 此处能够放字符串
    
    3.此处能够听任何模板代码 或 组件
</my-button>
复制代码

此外,须要咱们注意的是:父级模板里的全部内容都是在父级做用域中编译的;子模板里的全部内容都是在子做用域中编译的。也就是说<my-button></my-button>包裹的内容不能访问my-button的做用域。dom

具名插槽

有时咱们须要多个插槽,<slot> 元素有一个特殊的 attribute:name,咱们可使用这个属性来写你须要的插槽,假定一个组件base-layout以下:ide

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
复制代码

属性name不存在的时候,<slot> 出口会带有隐含的名字“default”。那么咱们该怎么使用呢,以下:函数

<base-layout>
    //使用 v-slot
  <template v-slot:header>
    <h1>name为header的插槽</h1>
  </template>

    //默认插槽能够不用写 v-slot:default ,可是若是用缩写的方式就须要写上 #default
  <template #default>
    <p>v-slot 时能够不用写</p>
    <p>缩写时要加上 #default</p>
  </template>
    
    //使用缩写 #
  <template #footer>
    <p>缩写形式</p>
  </template>
</base-layout>
复制代码

做用域插槽

为了让插槽内容可以访问子组件中才有的数据,咱们可使用做用于插槽。oop

用法

单个插槽 假定组件todo-list为:post

<ul>
  <li v-for="(item, index) in items">
    <slot :item="item" :index="index"></slot>
  </li>
</ul>
复制代码

使用时咱们能够有两种方式:

  1. v-slot做用在组件上
<todo-list v-slot="slotProps">
    //slotProps 是个对象,包含了绑定在 slot 上除 name 之外的全部属性,例如上述包含了item、index
    //slotProps 是个变量,能够取任意名字
    
    //此时不能用template包裹
    <span>{{slotProps.item}}</span>
</todo-list>
复制代码

咱们这个例子是默认插槽,若是例子中是具名插槽,好比 slotname="header",那咱们要这样使用:

<todo-list v-slot:header="slotProps">
    <span>{{slotProps.item}}</span>
</todo-list>
复制代码
  1. v-slot做用在插槽包裹元素template
<todo-list>
    //必定要用 template 包裹,由于v-slot只能用于 template 或 组件中
    <template v-slot="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
</todo-list>
复制代码

若是组件给了一个具名插槽,使用方法和1相同。

多个插槽

此时v-slot只能做用在插槽包裹元素template上,假定组件todo-list为:

<ul>
  <li v-for="(item, index) in items">
    <slot name="slot1" :item="item" :index="index"></slot>
    <slot name="slot2" :item="item" :index="index"></slot>
    <slot name="slot3" :item="item" :index="index"></slot>
  </li>
</ul>
复制代码

使用方法以下:

<todo-list>
    //slot1
    <template v-slot:slot1="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
    
    //slot2
    <template v-slot:slot2="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
    
    //slot3
    <template v-slot:slot3="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
</todo-list>
复制代码

解构插槽Prop

经过上述内容咱们知道slotProps是个对象,那么咱们在使用的时候能够解构插槽。咱们以1的具名插槽为例:

<todo-list v-slot:header="{item,index}">
    <span>{{item}} {{index}}</span>
</todo-list>

或者

<todo-list v-slot:header="{item:x,index:y}">
    <span>{{x}} {{y}}</span>
</todo-list>
复制代码

动态插槽

动态指令参数也能够用在 v-slot 上,来定义动态的插槽名,也就是说你能够根据本身的需求,来动态的改变插槽内容,以下:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>
复制代码

假设你有三个插槽,可是你每次只想展现一个插槽内容,那么咱们就能够用动态插槽来作这件事。

注意事项

Vue3统一了普通插槽和做用域插槽。当使用渲染函数时,即 h,将插槽定义为当前节点的子对象,以下:

h(LayoutComponent, {}, {
  header: () => h('div', this.header),
  content: () => h('div', this.content)
})
复制代码

当你须要以编程方式引用做用域插槽时,Vue3与Vue2的用法是不同的,在Vue3中它们如今被统一到 $slots 选项中,使用以下:

// 2.x 语法
this.$scopedSlots.header

// 3.x 语法
this.$slots.header()
复制代码

总结

  1. 使用动态插槽可让咱们在处理同一区域复杂内容切换更灵活。

  2. Vue3<template>里面能够放代码片断,因此咱们能够在使用插槽的时候,里面能够放不少的dom或组件。

  3. 具名插槽和解构插槽Prop均可以让我更好的去完成需求,咱们能够根据本身的状况,去合理的使用它们。

相关文章
相关标签/搜索