vue总结系列 --- 插槽slot

2023-05-16

前因

这个是我这个系列的第二篇,这一篇文章我也修改过三次(2019-9-10)我是想以vue官方文档为基础,来进行理解,有人说有官方文档,还要写自己的文章干嘛,我的用意其实是我确实想把官网文档中的案例全部写一遍,来加深自己对这个知识点的理解,因为看还是不如写吧,我在吧我遇到的问题,和我的理解,写出来,以便我以后的忘记,和与我有类似经历的人不用再浪费时间

插槽

其实就是在组件的innerHTML中的内容,他会传递给这个组件中的<slot>元素,其实从功能上来看这个过程有点像prop,但用prop是传递的属性值,而插槽传递的是文本,和HTML,用法就是我们的基本格式不变我变的是其中的一些内容,这样跟好的可控性我们些组件开发的时候就可以经常用到

父组件书写

<navigation-link url="/profile">
  Your Profile
</navigation-link>

子组件模板书写

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。插槽内可以包含任何模板代码

1.包括HTML

<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

2.包括其他组件

<navigation-link url="/profile">
  <!-- 添加一个图标的组件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

如果 <navigation-link>的子组件模块中 没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。

编译的作用域

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

例如:

<navigation-link url="/profile">
  Logged in as {{ user.name }}
</navigation-link>

在官网中这里的意思是user是子组件中的data对象中的值,他不可以再父组件中的作用域中显示会报错,其实也就是子组件中定义的值和父组件中的不同的作用域,所以引用会报错

后备(默认)内容

有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。

例如在一个<submit-button> 组件中他的template是:

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

那么他就可以在下<submit-button> 组件中没提供插槽的时候会有默认的Submit的值,只有在<submit-button> 组件中提供了值才会把默认值给替换掉

具名插槽

这里我们使用2.6版本的语法 v-slot

当我们需要多个插槽的时候,例如对于一个带有如下模板的 <base-layout> 组件他的tenplate为

<div class="container">
  <header>
    <!-- 我们希望把页头放这里 -->
  </header>
  <main>
    <!-- 我们希望把主要内容放这里 -->
  </main>
  <footer>
    <!-- 我们希望把页脚放这里 -->
  </footer>
</div>

对于这样的情况,<slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:

 <base-layout> 组件他的tenplate修改后

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

一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以v-slot 的参数的形式提供其名称:

v-slot最好是写在<template>上面

那我们给组件上添加什么内容呢?

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

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

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

现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有v-slot 的 <template> 中的内容都会被视为默认插槽的内容

然而,如果你希望更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容:

<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>

以前2.6以前用slot的写法是

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

  <template slot = 'default'>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template 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>

注意 v-slot 只能添加在一个 <template> 上 (只有一种例外情况,等下文),这一点和已经废弃的 slot特性不同,建议都写。

作用域插槽

前面有说插槽(父组件中的innerHTML)的值是没办法访问子组件中的数据,但要是我们需要访问,我们要怎么办呢?

官网是这样讲的我来简单的解释一下

例如,设想一个带有如下模板的<current-user> 组件的tempalte为:

这里的前题是user是组件current-user中的值不是父组件中的值(这里为全局)

<span>
  <slot>{{ user.lastName }}</slot> //这里的{{user.lastName}}是当父组件没传slot过来的时候的默认值
</span>

组件插槽为:

<current-user>
  {{ user.firstName }}
</current-user>

在这里会报错,因为我们上面说过:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。作用域中没有这个值就会报错

为了让 user 在父级的插槽内容可用,我们可以将 user 作为一个 <slot> 元素的特性绑定上去:

注意:这里一个不带 name 的 <slot> 出口会带有隐含的名字“default”

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

我的理解是这个<slot>上现在具有了一个可变化的属性他叫user,他的值是current-user组件中的user的值,这个值目前来说是一个对象

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

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

经过我写过后的理解就是current-user组件之后有定义一个对象user我们需要把他传对应的插槽,对应的插槽在接收通过name的值来对应相应的值,在这里<template v-slot:default="slotProps">的意思是在这里

1.用v-slot来接收,

2.名字为default(默认值)的传过来的值,

3.并把传过来的user这个值变命名为slotProps这个对象中的一个属性,

4.所以在slotProps中找到user中的firstName了

上面有说v-slot只可以写在<template>上唯一一种情况就是:当提供的内容只有默认插槽时

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

也就是<slot>上没写name,name默认为default

具名插槽的缩写

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header

然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

由于<template>中 v-slot:default=' ' 可以简写为 v-slot = ' '但是

由于下面是全部是default可以把<template>省去,把v-slot:default=' '写再父组件上

<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>

如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:

<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>

解构插槽prop

v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop

<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

为什么可以这样?

上文说过

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

我们父主键接到的是slotProps对象现在我们把他解构为{ user },这样我们拿到的值就是 slotProps对象中的 user的这个属性值了

总结

插槽看到这里我的理解就是对组件的高效利用,比如我现在写过的一个弹窗组件,这个弹窗的中间内容我们就可以在父组件中自己定义,这样这个组件的可利用价值就增加了,就不用说一种弹窗写一个组件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue总结系列 --- 插槽slot 的相关文章

  • 震惊!Ajax项目中的使用

    啊啊 xff01 实习第一天写了个移动端的分享列表 就在第三天我们的技术大佬亲自教我们如何对接后台 当然用的是我写的移动端的分享列表 虽然这次应用不是很深入 xff0c 但还是比较广泛 用到了Ajax xff0c sui框架 zepto x

随机推荐

  • 关于viewport视口的学习

    简单来说 lt meta name 61 34 viewport 34 content 61 34 width 61 device width initial scale 61 1 0 34 gt content属性值 width 可视区域
  • 淘宝的H5布局

    利用viewport和rem布局实现的淘宝布局 下面先看看em布局的原理 em作为font size的单位时 xff0c 其代表父元素的字体大小 xff0c em作为其他属性单位时 xff0c 代表自身字体大小 MDN em作为字体单位 x
  • css的优先级

    优先级 浏览器通过优先级来判断哪些属性值与一个元素最为相关 xff0c 从而在该元素上应用这些属性值 优先级是基于不同种类选择器组成的匹配规则 优先级是如何计算的 优先级就是分配给指定的 CSS 声明的一个权重 xff0c 它由 匹配的选择
  • Django设置分享到微信好友和朋友圈时的标题、摘要、链接和图片

    主要参考官方文档 1 前端分享给好友和朋友圈的js代码 share html lt DOCTYPE html gt lt html lang en gt lt head gt lt meta charset UTF 8 gt lt meta
  • 孙其功陪你学之——如何将shell命令的返回值赋值给应用程序的变量

    如何将shell命令的返回值赋值给应用程序的变量 博主最近做了个路由器的项目 xff0c 需要得到路由器现在网络状态和参数 xff0c 使用UCI get 获得 xff0c 但是使用了system xff08 UCI get xff09 之
  • shell编程2条件语句

    文章目录 shell编程之条件语句1 条件测试1 1 返回值1 2 test 2 文件测试3 整数值比较4 逻辑测试5 if语句5 1 单分支 if 语句5 2 双分支 if 语句5 3 多分支 if 语句 6 case 语句7 实验7 1
  • html和css的hack的学习

    在整理基础的时候总结 html和css的hack的学习 hack是什么 xff1f 就是针对不同的浏览器写不同的css样式让各浏览器能达到一致的渲染效果 xff0c hack分为HTML和CSS HTML hack lt if lte IE
  • 数组的迭代与归并的方法

    迭代的作用 xff1a 减少代码量 xff1a 例如因为map xff0c filter方法会自动生产数组不用自己在for创建 xff0c 有利于性能优化 xff1b 和无需知道对象的长度 补充19 6 11 xff1a 迭代的方法是表达式
  • js数组的常见属性和方法

    属性 strong length strong 是Array的实例属性 返回或设置一个数组中的元素个数 该值是一个无符号 32 bit 整数 xff0c 并且总是大于数组最高项的下标 xff0c 不只是可读 Array prototype
  • js闭包的作用和应用的学习

    什么是闭包 一个函数和对其周围状态 xff08 lexical environment xff0c 词法环境 xff09 的引用捆绑在一起 xff08 或者说函数被引用包围 xff09 xff0c 这样的组合就是闭包 xff08 closu
  • css面试题布局

    不试试怎么知道自己行不行 昨天加了张鑫旭的微信 xff0c 我草贼开心 xff0c 发现他星期六会直播 xff0c 一下就是我看直播学到的一些总结 那么是什么呢 xff1f 其实就是一个简单的左右排版 xff0c 在张老师的讲了4种不是很好
  • 获取css的方法区别

    不试试怎么知道自己不可以 xff1f 对吧 首先我们要知道css在HTML中有多少总方法 xff1f 呵呵大家都知道的 行内 xff1a 顾名思义就是和标签在同一行 lt div class 61 34 text 34 style 61 3
  • 关于offsetLeft和offsetTop的兼容性问题

    不试一下怎么知道自己不可以 xff1f 首先我们要看下offsetLeft和offsetTop他们两的API的作用 xff1b 元素相对于offsetParent的左边距和上边距 xff08 为什么没有bottom xff0c right呢
  • js深度拷贝和浅度拷贝的深入理解

    首先我们来说说什么是拷贝 xff1a 就是复制的同时加上了传值 然后问题就来了什么是有深度的什么是浅度的 xff0c 在想要了解我们这个问题之前我们先来了解一下下面的一个知识点 基本类型传递 xff0c 引用类型传递 首先我们来看下基本类型
  • npm的基本使用

    npm的下载 npm的下载其实就是把node js 百度下node官网 下载好了那么npm就附带下载好了 检查是否下载好 window 43 r 后输入cmd打开终端 xff0c 在终端中输入node v xff1b npm v 他们会输出
  • 从 (a==1&&a==2&&a==3) 成立中看javascript的隐式类型转换

    几天上班看到一个题目就是 if a 61 61 1 amp amp a 61 61 2 amp amp a 61 61 3 console log 34 a等于什么才会输出这一句话呢 xff1f 34 当a为什么的时候输出 xff1a a等
  • Bootstrap实用功能总结

    导航栏 xff1a navbar 导航栏容器可以包含以下几个常用组成 xff1a 1 品牌LOGO xff08 navbar brand xff09 2 导航菜单 xff08 navbar nav xff09 3 导航文本 xff08 na
  • 微信小程序的AJAX初次体验

    GET请求 微信小程序用GET传送数据 微信小程序通过 wx request发送ajax请求 wx request url app globalData pubSiteUrl 43 39 user information get infor
  • vue总结系列 ------ 组件之间的传值

    原因 半年前开始学Vue学到了今天 xff0c 也没有机会好好整理一下自己的知识点 xff0c 因为上公司的项目不是依赖于Vue xff0c 还是在用JQ 和文件之间来传递代码 xff0c 所以其实在对vue的学习成面上来讲对我的帮助并不大
  • vue总结系列 --- 插槽slot

    前因 这个是我这个系列的第二篇 这一篇文章我也修改过三次 xff08 2019 9 10 xff09 我是想以vue官方文档为基础 xff0c 来进行理解 xff0c 有人说有官方文档 xff0c 还要写自己的文章干嘛 xff0c 我的用意