Vue插槽原理与用法详解
作者:deniro_li 发布时间:2024-05-09 10:43:09
本文实例讲述了Vue插槽原理与用法。分享给大家供大家参考,具体如下:
1 插槽内容
Vue 实现了一套内容分发的 API,这套 API 基于当前的 Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
它允许你像这样合成组件:
<div id="app1">
<navigation-link url="/profile">
Your Profile
</navigation-link>
</div>
然后你在 <navigation-link>
的模板中可能会写为:
Vue.component('navigation-link', {
template: `
<a
v-bind:href="url" rel="external nofollow"
class="nav-link"
>
<slot></slot>
</a>
`
});
当组件渲染的时候,这个 <slot>
元素将会被替换为“Your Profile”。
插槽内可以包含任何模板代码,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
甚至其它的组件:
<navigation-link url="/profile">
<!-- 添加一个图标的组件 -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
如果 <navigation-link>
没有包含一个 <slot>
元素,则任何传入它的内容都会被抛弃。
2 具名插槽
有些时候我们需要多个插槽。例如,一个假设的 <base-layout>
组件多模板如下:
<div class="container">
<header>
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
</footer>
</div>
对于这样的情况,<slot>
元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
在向具名插槽提供内容的时候,我们可以在一个父组件的 <template>
元素上使用 slot 特性:
<base-layout>
<template 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 slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
另一种 slot 特性的用法是直接用在一个普通的元素上:
<base-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</base-layout>
我们还是可以保留一个未命名插槽,这个插槽是默认插槽,也就是说它会作为所有未匹配到插槽的内容的统一出口。上述两个示例渲染出来的 HTML 都将会是:
<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>
3 默认插槽的内容
有的时候为插槽提供默认的内容是很有用的。例如,一个 <submit-button>
组件可能希望这个按钮的默认内容是“Submit”,但是同时允许用户覆写为“Save”、“Upload”或别的内容。
你可以在 <slot>
标签内部指定默认的内容来做到这一点。
<button type="submit">
<slot>Submit</slot>
</button>
如果父组件为这个插槽提供了内容,则默认的内容会被替换掉。
4 编译作用域
当你想在插槽内使用数据时,例如:
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
该插槽可以访问跟这个模板的其它地方相同的实例属性 (也就是说“作用域”是相同的)。但这个插槽不能访问 <navigation-link>
的作用域。例如尝试访问 url 是不会工作的。牢记一条准则:
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
5 作用域插槽
2.1.0+ 新增
有的时候你希望提供的组件带有一个可从子组件获取数据的可复用的插槽。例如一个简单的 <todo-list>
组件的模板可能包含了如下代码:
Vue.component('todo-list',{
template:`
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id">
{{ todo.text }}
</li>
</ul>
`
});
但是在我们应用的某些部分,我们希望每个独立的待办项渲染出和 todo.text 不太一样的东西。这也是作用域插槽的用武之地。
为了让这个特性成为可能,你需要做的全部事情就是将待办项内容包裹在一个 <slot>
元素上,然后将所有和其上下文相关的数据传递给这个插槽:在这个例子中,这个数据是 todo 对象:
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<!-- 我们为每个 todo 准备了一个插槽,-->
<!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
<slot v-bind:todo="todo">
<!-- 回退的内容 -->
{{ todo.text }}
</slot>
</li>
</ul>
现在当我们使用 <todo-list>
组件的时候,我们可以选择为待办项定义一个不一样的<template>
作为替代方案,并且可以通过 slot-scope 特性从子组件获取数据:
<todo-list v-bind:todos="todos">
<!--插槽作用域的名字是 slotProps-->
<template slot-scope="slotProps">
<!-- 为指定的待办项定义一个模板-->
<span v-if="slotProps.todo.isComplete">✓</span>
{{ slotProps.todo.text }}
</template>
</todo-list>
在 2.5.0+,slot-scope 不再限制在 <template>
元素上使用,而可以用在插槽内的任何元素或组件上。
解构 slot-scope
如果一个 JavaScript 表达式在一个函数定义的参数位置有效,那么这个表达式实际上就可以被 slot-scope 接受。也就是说你可以在支持的环境下 单文件组件或现代浏览器),在这些表达式中使用 ES2015 解构语法。例如:
<todo-list v-bind:todos="todos">
<template slot-scope="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
这会使作用域插槽变得更干净一些。
希望本文所述对大家vue.js程序设计有所帮助。
来源:https://blog.csdn.net/deniro_li/article/details/80690693


猜你喜欢
- 在JAVA WEB应用中,如何获取servlet请求中的参数,并传递给跳转的JSP页面?例如访问http://localhost:8088/
- 前言本文主要给大家介绍了关于Mysql元数据生成Hive建表语句注释脚本的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的
- 目录一、Python 3.8 安装1.通过 Apt 安装Python3.82.配置 python3.8 为系统默认 python3二、卸载p
- 一、Mysql SQL Mode简介通常来说MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式。这样
- Python Assert 为何不尽如人意?Python中的断言用起来非常简单,你可以在assert后面跟上任意判断条件,如果断言失败则会抛
- 大家好,我是小五前一阵给大家分享了,Python如何给图片加水印。评论区就有小伙伴问,可不可使用Python去除图片水印的方法呢?这个肯定有
- xlsxwriter可能用过的人并不是很多,不过使用后就会感觉,他的功能让你叹服,除了可以按要求生成你所需要的excel外还可以加上很形象的
- 前段时间接触了一个批量抠图的模型库,而后在一些视频中找到灵感,觉得应该可以通过抠图的方式,给视频换一个不同的场景,于是就有了今天的文章。我们
- 我们在使用pycharm的时候总是很喜欢其强大的代码提示功能,只需ctrl+左键就可以查看源码,"."也能显示所含的函数
- 图像在计算机中的存储图像其实就是一个像素值组成的矩阵。1、黑白或灰度图像如何存储在计算机中在这里,我们已经采取了黑白图像,也被称为一个灰度图
- 之前我们使用VSCode搭建C#项目,今天写一篇关于django项目的搭建,其实以其说是搭建django框架,不如说是如何通过vscode开
- 在写代码时,经常会遇到多个矩阵数组拼接的情况,numpy里dstack, hstack, vstack, 都有拼接的作用,那么这些函数是怎么
- 工作中有时候需要对vgg进行定制化处理,比如有些时候需要借助于vgg的层结构,但是需要使用的是2 channels输入,等等需求,这时候可以
- 本文实例讲述了Sanic框架蓝图用法。分享给大家供大家参考,具体如下:蓝图是可以用于应用程序内子路由的对象。蓝图并未向应用程序内添加路由,而
- 我在程序首端添加了On Error Resume Next ,以更好地处理执行时引起的错误,但在数据库访问中引出了麻烦,因为我在一个查询操作
- 为什么使用生产者消费者模式在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发中,如果生产者处理速度很快,而消费者
- hasattr()函数hasattr()函数用于判断是否包含对应的属性语法:hasattr(object,name)参数:object--对
- 通常大家想知道数据库是否增长了,增长了多少。大家可能想到用数据库的各个历史时期的大小来比较就可以了。 但怎么能得到这些历史的大小数据呢?好像
- 如何制作一个弹出式的调查窗口?执行下面这段ASP代码: <% &n
- 更新什么?概况一览1、优化了 Promise.all 的定义,在 3.7 版本中一些混用 null 或 undefined 的时候的问题已经