IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue3 中插槽(slot)的用法 -> 正文阅读

[JavaScript知识库]Vue3 中插槽(slot)的用法

Vue3(其实从2.6开始)中引入了一个新的指令v-slot,用来表示具名插槽和默认插槽

基础示例

<!-- default slot -->
<foo v-slot="{ msg }">
    {{ msg }}
</foo>

<!-- named slot -->
<foo>
    <template v-slot:one="{msg}">
        {{ msg }}
    </template> 
</foo>

为什么要这么做

<foo>
  <bar slot-scope="foo">
    <baz slot-scope="bar">
      <div slot-scope="baz">
        {{ foo }} {{ bar }} {{ baz }}
      </div>
    </baz>
  </bar>
</foo>

?像上面这种情况,我们无法立即分辨出模板上作用域变量是由那一个组件提供的。

引入一个新的指令v-slot

我们可以在slot容器<template>上使用v-slot来表示一个传入组件的插槽,通过指令参数来表示插槽的名称。

<foo>
    <template v-slot:header>
        <div class="header"></div>
    </template>
    <template v-slot:body>
        <div class="body"></div>
    </template>
    <template v-slot:footer>
        <div class="footer"></div>
    </template>
</foo>

作用域插槽的内部工作原理是将插槽的内容包裹在一个函数里

    function(slotProps){
        // 插槽内容
    }

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

<foo>
    <template v-slot:header="{ msg }">
        <div class="header">
            Message from header slot: {{ msg }}
        </div>
    </template>
</foo>

v-slot可以直接用在组件上,如果没有参数,则表示默认的作用域插槽,传递给默认插槽的属性应该作为变量在其属性值声明

<foo v-slot="{ msg }">
    {{ msg }}
</foo>

新旧语法对比

对于常用的场景(只有一个默认的作用域插槽)

<foo v-slot="{msg}">{{msg}}</foo>

作用域变量与组件之间的联系更加的清晰

<!-- old -->
<foo>
  <bar slot-scope="foo">
    <baz slot-scope="bar">
      <div slot-scope="baz">
        {{ foo }} {{ bar }} {{ baz }}
      </div>
    </baz>
  </bar>
</foo>

使用新语法也可以达到同样的效果

<foo v-slot="foo">
  <bar v-slot="bar">
    <baz v-slot="baz">
      {{ foo }} {{ bar }} {{ baz }}
    </baz>
  </bar>
</foo>

动态插槽名

动态指令参数也可以用在?v-slot?上,来定义动态的插槽名:

<foo>
    <template v-slot:[slotName]>
        ...
    </template>
</foo>

插槽指令的缩写

和?v-bindv-on相似,缩写只有在存在参数时才生效,这就意味着v-slot没有参数时不能使用#=,对于默认插槽,可以使用#default来代替v-slot

<!-- full syntax -->
<foo>
  <template v-slot:header="{ msg }">
    Message from header: {{ msg }}
  </template>

   <template v-slot:footer>
    A static footer
  </template>
</foo>

<!-- shorthand -->
<foo>
  <template #header="{ msg }">
    Message from header: {{ msg }}
  </template>

   <template #footer>
    A static footer
  </template>
</foo>
<foo v-slot="{ msg }">
  {{ msg }}
</foo>

<foo #default="{ msg }">
  {{ msg }}
</foo>

更多的用例对比

默认的文本作用域插槽

<!-- old -->
<foo>
    <template slot-scope="{ msg }">
        {{ msg }}
    </template>
</foo>

<!-- new -->
<foo v-slot="{ msg }">
    {{ msg }}
</foo>

默认的含DOM节点的插槽

<!-- old -->
<foo>
    <div slot-scope="{msg}">
        {{msg}}
    </div>
</foo>

<!-- new -->
<foo v-slot="{msg}">
    <div>
        {{msg}}
    </div>
</foo>

嵌套的默认插槽

<!-- old -->
<foo>
    <bar slot-scope="foo">
        <baz slot-scope="bar"> 
            <template slot-scope="baz">
                {{ foo }} {{ bar }} {{ baz }}
            </template>
        </baz>
    </bar>
</foo>

<!-- new -->

<foo v-slot="foo">
    <bar v-slot="bar">
        <baz v-slot="baz">
            {{ foo }} {{ bar }} {{ baz }}
        </baz>
    </bar>
</foo>

命名插槽?

<!-- old -->
<foo>
    <template slot="one" slot-scope="{ msg }">
        text slot: {{ msg }}
    </template>
    <div slot="two" slot-scope="{ msg }">
        element slot: {{ msg }}
    </div>
</foo>

<!-- new -->
<foo>
    <template v-slot:one="{ msg }">
        text slot:{{msg}}
    </template>
    <template v-slot:two="{msg}">
        <div>
            element slot: {{msg}}
        </div>
    </template>
</foo>

嵌套 & 命名 / 默认

<!-- old -->
<foo>
  <bar slot="one" slot-scope="one">
    <div slot-scope="bar">
      {{ one }} {{ bar }}
    </div>
  </bar>

  <bar slot="two" slot-scope="two">
    <div slot-scope="bar">
      {{ two }} {{ bar }}
    </div>
  </bar>
</foo>

<!-- new -->
<foo>
  <template v-slot:one="one">
    <bar v-slot="bar">
      <div>{{ one }} {{ bar }}</div>
    </bar>
  </template>

  <template v-slot:two="two">
    <bar v-slot="bar">
      <div>{{ two }} {{ bar }}</div>
    </bar>
  </template>
</foo>

具名插槽

当有多个插槽时,插槽增加了name属性来正确渲染对应的部分,父组件需要使用<template></template>。可以认为匿名插槽是特殊的具名插槽

<!-- my-layout子组件定义 -->
<template>
    <div>
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <!-- 其实就是<slot name="default"></slot> -->
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    </div>
</template>

<!-- 父组件调用my-layout -->
<my-layout>
    <!-- 填充内容顺序无关 -->
    <template v-slot:footer>
    	<p>我来组成脚丫子</p>
  	</template>
    
    <!-- v-slot:header可以简写为#header -->
	<template v-slot:header>
    	<h1>我来组成头部</h1>
  	</template>

    <!-- v-slot:default可以忽略不写 -->
  	<template v-slot:default>
        <p>我来组成身体</p>
  	</template>
</my-layout>

<!-- 父组件页面渲染为 -->
<div>
    <header>
        <h1>我来组成头部</h1>
    </header>
    <main>
    	<p>我来组成身体</p>
    </main>
    <footer>
        <p>我来组成脚丫子</p>
    </footer>
</div>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:44:26  更:2022-04-28 11:47:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:40:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码