菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
80
0

Vue 的作用域插槽是个难点

原创
05/13 14:22
阅读数 501

一段时间不用,很快就忘光了。为方便自己快速回忆,特此记上一笔。

先回忆最简单的

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>
</base-layout>

上述slot="header"的写法已被废弃,改用如下v-slot:header的写法

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

如果觉得这样写很麻烦,可以使用如下所示#header简写形式

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>
</base-layout>

如果该组件有且只有一个默认插槽(独生槽),则可以去掉<template>标签进一步简写

<base-layout>
    <h1>Here might be a page title</h1>
</base-layout>

再看作用域插槽

先写一个带有作用域插槽的vue组件,取名为 user-list 组件。此组件有3个插槽,一个名叫first,一个名叫last,还有一个是默认插槽default(可以省略name="default"

<template>
    <ul class="list-unstyled">
        <li v-for="user in users">
            <slot :user="user">
                {{user.id}}
            </slot>
            <slot name="first" :first="user">
                {{user.firstName}}
            </slot>
            <slot name="last" :last="user">
                {{user.lastName}}
            </slot>
        </li>
    </ul>
</template>

<script>
    export default {
        props: ['users']
    }
</script>

在blade模版中敲入代码<user-list :users="{{$users}}"></user-list>,显示如下信息
Vue 的作用域插槽是个难点
开始玩花样了,用下面这段代码格式化firstName(改成大写,并放到【】里面)

    <user-list :users="{{$users}}">
        <template #first="props">
            【@{{props.first.firstName.toUpperCase()}}】
        </template>
    </user-list>

效果如下图。这里分析一下这段代码的含义:调用者是blade模板,调用的是user-list组件,调用者调用组件后对组件的first插槽做了点手脚,使得组件呈现的效果有所不同(从而达到格式化的目的)。注意这行<template #first="props">,其中#first是不能变的,这是由插槽的名字决定的;引号里面的props是自由可变的。需要注意的是props.first.firstName.toUpperCase()这句代码里面的first是怎么来的?这个first是组件定义插槽时决定的。组件定义插槽时有这么一行<slot name="first" :first="user">,这里面有个:first,就是由这个带冒号的属性决定的。
Vue 的作用域插槽是个难点

作用域插槽的对象解构

使用对象解构,会让代码简单一些

    <user-list :users="{{$users}}">
        <template #last="{last}">
            <span class="text-primary"> @{{last.lastName}} </span>
        </template>
    </user-list>

效果如下图。这里面的#last="{last}"就是对象解构,使用的时候就可以直接写成last.lastName了。这比前例的写法要紧凑,前例多了一个自由命名的props
Vue 的作用域插槽是个难点
在定义插槽的时候,不同的插槽要取不同的名字,这点毫无疑问。但是不同插槽的属性名称是没必要区分的,属性名称完全可以取一模一样的名字。
具体来说:<slot :user="user"><slot name="first" :first="user"><slot name="last" :last="user">,其中default插槽取了一个叫做:user的属性名称,first取了一个叫做:first的属性名,最后一个取了一个:last的属性名。这种区分完全没必要。
可以全部写成一样的:user,即<slot :user="user"><slot name="first" :user="user"><slot name="last" :user="user">
最后一例:默认插槽的对象解构(格式化默认插槽,并清空first插槽及last插槽的默认数据)

    <user-list :users="{{$users}}">
        <template #default="{user}">
            (@{{user.id}}) @{{user.name}}
        </template>
        <template #first><i></i></template>
        <template #last><i></i></template>
    </user-list>

以下为效果图
Vue 的作用域插槽是个难点

独占式作用域插槽

修改user-list组件,将其中的first插槽及last插槽的定义代码全部删除,只保留一个default插槽,形成独占,称之:独占式作用域插槽(也就是组件的“独生带域槽”)。对于独生带域槽,调用的时候可以完全删除<template>标签,但是要将#default="{user}"挪到父标签里面(代码如下,展示效果跟上图一样)

    <user-list :users="{{$users}}" #default="{user}">
        (@{{user.id}}) @{{user.name}}
    </user-list>

为什么要使用作用域插槽?

blade模版对user-list组件说:我给你一批用户数据,你帮我展现出来。
user-list组件说:好的,我用一个for循环依次处理。
blade模版:但是不能完全按你的那一套来,在slot这个地方要改一改。
user-list组件:具体要怎么改?
blade模版:你把材料拿过来,我演示给你看。
user-list组件:好的,给你 :user(这一步早在插槽定义的时候就准备好了的 <slot :user="user">)。
blade模版接过材料:看好了,我给你写个模版,你要照着模版弄(所谓 的接过材料,其实就是解构出 user )
<template #default="{user}">
(@{{user.id}}) @{{user.name}}
</template>
user-list组件:好的,没问题。
通过使用作用域插槽,blade模版达到了效果定制的目的;而user-list组件也通过作用域插槽明白了调用者的意图。

代码库

本文代码 git@gitee.com:zhaiduting/see.git
1、git clone git@gitee.com:zhaiduting/see.git
2、cd see; composer install; npm install; npm run dev
3、配置 .env
4、php artisan migrate --seed
5、搭建服务器
6、使用http://x.xx.x/slot查看效果
7、版本回退,重新编译后再看效果

发表评论

0/200
80 点赞
0 评论
收藏
为你推荐 换一批