Vue3从入门到精通 11
透传 Attributes
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。
Attributes 继承
当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。举例来说,假如我们有一个 <MyButton> 组件,它的模板长这样:
(资料图片仅供参考)
<!-- <MyButton> 的模板 --><button>click me</button>
一个父组件使用了这个组件,并且传入了 class:
<MyButton class="large" />
最后渲染出的 DOM 结果是:
<button class="large">click me</button>
这里,<MyButton> 并没有将 class 声明为一个它所接受的 prop,所以 class 被视作透传 attribute,自动透传到了 <MyButton> 的根元素上。
禁用 Attributes 继承
如果你不想要一个组件自动地继承 attribute,你可以在组件选项中设置 inheritAttrs: false。
最常见的需要禁用 attribute 继承的场景就是 attribute 需要应用在根节点以外的其他元素上。通过设置 inheritAttrs 选项为 false,你可以完全控制透传进来的 attribute 被如何使用。
这些透传进来的 attribute 可以在模板的表达式中直接用 $attrs 访问到。
<span>Fallthrough attribute: {{ $attrs }}</span>
这个 $attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。
有几点需要注意:
和 props 有所不同,透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像 foo-bar 这样的一个 attribute 需要通过 $attrs["foo-bar"] 来访问。像 @click 这样的一个 v-on 事件监听器将在此对象下被暴露为一个函数 $attrs.onClick。插槽 Slots
插槽内容于出口
我们已经了解到组件能够接收任意类型的 JavaScript 值作为 props,但组件要如何接收模板内容呢?在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
示例:
<template> <h1>{{ title }}</h1> <BaseSlot> <div> <h3>标题:</h3> <p>内容:</p> </div> </BaseSlot></template><script>import BaseSlot from "./components/BaseSlot.vue";export default { data() { return { title: "插槽 slots" } }, components: { BaseSlot }}</script>
<template> <h2>{{ title }}</h2> <!-- 插槽出口 --> <slot></slot></template><script>export default { data() { return { title:"插槽 信息" } }}</script>
<slot> 元素是一个插槽出口(slot outlet),标示了父元素提供的插槽内容(slot content) 将在哪里被渲染。
渲染作用域
插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的。
<template> <h1>{{ title }}</h1> <ComponentA> <p>{{ message }}</p> </ComponentA></template><script>import ComponentA from "./components/ComponentA.vue";export default { data() { return { title: "插槽 slots", message:"App->ComponentA->message" } }, components: { ComponentA }}</script>
<template> <h2>{{ title }}</h2> <p> {{ message }}</p> <slot></slot></template><script>export default { data() { return { title: "A", message: "Component A -> message" } }, components: { }}</script>
这里的两个 {{ message }} 插值表达式渲染的内容都是一样的。
插槽内容无法访问子组件的数据。Vue 模板中的表达式只能访问其定义时所处的作用域,这和 JavaScript 的词法作用域规则是一致的。换言之:
默认内容
在外部没有提供任何内容的情况下,可以为插槽指定默认内容。
如果我们想在父组件没有提供任何插槽内容时,只需要将默认内容写在 <slot> 标签之间来作为默认内容
<template> <h1>{{ title }}</h1> <ComponentA> <!-- <p>{{ message }}</p> --> </ComponentA></template><script>import ComponentA from "./components/ComponentA.vue";export default { data() { return { title: "插槽 slots", message:"App->ComponentA->message" } }, components: { ComponentA }}</script>
<template> <h2>{{ title }}</h2> <p> {{ message }}</p> <slot>默认内容</slot></template><script>export default { data() { return { title: "A", message: "Component A -> message" } }, components: { }}</script>
具名插槽
有时在一个组件中包含多个插槽出口是很有用的。
要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:
<template> <h2>{{ title }}</h2> <slot name="top">默认内容</slot> <br> <slot name="content">默认内容</slot></template>
<slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容
<ComponentA> <template v-slot:top> <p>{{ slotTopMsg }}</p> </template> <template v-slot:content> <p>{{ slotContentMsg }}</p> </template> </ComponentA>
v-slot 有对应的简写 #,因此 <template v-slot:top> 可以简写为 <template #top>。其意思就是*“将这部分模板片段传入子组件的 top 插槽中”*。
完整示例:
<template> <h1>{{ title }}</h1> <ComponentA> <template #top> <p>{{ slotTopMsg }}</p> </template> <template v-slot:content> <p>{{ slotContentMsg }}</p> </template> </ComponentA></template><script>import ComponentA from "./components/ComponentA.vue";export default { data() { return { title: "插槽 slots", slotTopMsg:"slot top msg", slotContentMsg:"slot content msg" } }, components: { ComponentA }}</script>
<template> <h2>{{ title }}</h2> <slot name="top">默认内容</slot> <br> <slot name="content">默认内容</slot></template><script>export default { data() { return { title: "A" } }, components: { }}</script>
插槽数据传递
插槽的内容无法访问到子组件的状态。
然而在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。
要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。
可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes。
<template> <h3>{{ title }}</h3> <slot :text="childMessage" :count="1"></slot></template>
当需要接收插槽 props 时,默认插槽和具名插槽的使用方式有一些小区别。下面我们将先展示默认插槽如何接受 props,通过子组件标签上的 v-slot 指令,直接接收到了一个插槽 props 对象:
<ComponentB v-slot="slotProps"> <h2>{{ message }}</h2> <p>text: {{ slotProps.text }}</p> <p>count: {{ slotProps.count }}</p> </ComponentB>
具名插槽数据传递
具名作用域插槽的工作方式也是类似的,插槽 props 可以作为 v-slot 指令的值被访问到:v-slot:name="slotProps"。当使用缩写时是这样:
<ComponentB> <h2>{{ message }}</h2> <template #one="slotProps"> <p>one - text: {{ slotProps.text }}</p> </template> <template #two="slotProps"> <p>two - count: {{ slotProps.count }}</p> </template> </ComponentB>
向具名插槽中传入 props:
<template> <h3>{{ title }}</h3> <hr> <!-- <slot :text="childMessage" :count="1"></slot> --> <slot name="one" :text="childMessage"></slot> <hr> <slot name="two" :count="1"></slot></template>
完整示例:
<template> <h1>{{ title }}</h1> <!-- <ComponentB v-slot="slotProps"> <h2>{{ message }}</h2> <p>text: {{ slotProps.text }}</p> <p>count: {{ slotProps.count }}</p> </ComponentB> --> <ComponentB> <h2>{{ message }}</h2> <template #one="slotProps"> <p>one - text: {{ slotProps.text }}</p> </template> <template #two="slotProps"> <p>two - count: {{ slotProps.count }}</p> </template> </ComponentB></template><script>import ComponentB from "./components/ComponentB.vue";export default { data() { return { title: "插槽 slots", message: "App->父级" } }, components: { // ComponentA, ComponentB }}</script>
<template> <h3>{{ title }}</h3> <hr> <!-- <slot :text="childMessage" :count="1"></slot> --> <slot name="one" :text="childMessage"></slot> <hr> <slot name="two" :count="1"></slot></template><script>export default { data() { return { title: "component b", childMessage: "组件 B 的数据" } }}</script>
标签:
推荐文章
- Vue3从入门到精通 11
- 全球微头条丨住进这些高颜值民宿,体验不同季节的山水魅力
- 普及金融知识万里行 工行扬州开发支行在行动 世界热议
- 绿色校园手抄报内容_绿色校园手抄报资料 环球微动态
- 热资讯!挑战巨人搜查强哥怎么玩
- 暗黑4第一件“军帽”在韩服现身 一件比别人一身都要强|每日时讯
- 世界简讯:6部门公布81个紧密型城市医疗集团建设试点城市名单
- 金湖:一条巡察问题 助推非遗传承-全球动态
- 看热讯:苹果Vision Pro头显低配版曝光:显示屏、处理器和传感器会缩水
- 小兔跳铃铛 下载_小兔跳铃铛
- 2023年中国南昌国际龙舟赛开赛 44支队伍竞渡九龙湖
- “五个一工程”获奖话剧《路遥》将于7月初上演于美琪大戏院
- 【环球播资讯】迂回曲折的意思(迂回的意思)
- 陈亦博:黄金本周来回震荡,下周先多后空!
- 好望角游戏交易平台什么时候开通(好望角游戏交易平台)-环球新视野
- 恭喜梅西!迈阿密新阵容曝光,球王新位置出人意料,冲第八座金球 环球速讯
- 高考结束,多地景区宣布全国高考考生凭准考证可免费游览
- 玉溪非遗资源系列微视频展播《玉溪手艺》之传奇鱼笼——大鱼笼编织工艺|环球热门
- 大金鼠:你生在冬天还是春天?出生的季节决定财富!
- 一位付费API工程师如何制造了推特今年第七次崩溃?|每日动态
- 永兴县鲤鱼塘镇:为留守儿童庆生 护航儿童成长 环球简讯
- beangry with sb beangrywith和beangryat的区别以及各自的用法
- 钱报健康小站|一到夏天皮肤就瘙痒,不妨试试中医止痒
- 全球聚焦:2023端午节股市休市几天
- 40大城市2022年人均收入:京沪逼近8万大关,长沙领跑中西部 环球消息
- 华商记者帮|小区近200个车位大部分都被上了地锁 社区:不允许私装地锁|百事通
- 当前最新:Sam Altman问答张宏江:模型开源是正确发展路径,应小心前行
- 国内物价运行总体平稳——解读5月份CPI和PPI数据 世界播资讯
- 古蜀先民5000年前主食都吃啥?小小牙齿为你揭秘→
- 网贷逾期10天严重吗?逾期多久就会被起诉呢?-今日讯
- 每日速看!勒夫:总决赛1比3落后我经历过
- 腾讯企鹅辅导电脑版(企鹅辅导电脑版)|环球最新
- 美英领导人发表《大西洋宣言》 美英寻求建立“新型创新伙伴关系”!_每日精选
- 华为获转让问界商标:可用于汽车等_全球独家
- 打新套利动辄千万,“万人摇”乱象丛生,楼市限价走到十字路口_世界新视野
- 世界观天下!万事俱备只欠东风的意思和故事(万事俱备只欠东风的意思)
- 潜在客户转化为现实客户的方法有_潜在客户
- 今年四川将建设19个秸秆综合利用重点县
- 全球滚动:浙江高考成绩将在6月26日左右公布
- 上海市宝山区发布大风黄色预警 环球资讯
- 超级玛丽中文版无限生命(超级玛丽中文版)-环球热资讯
- 当前简讯:耀华中学红桥学校7月招生 计划招收140人
- 思明区政务服务中心“政务智能办”专区启用
- 牵手胡继勇的董思槿相貌前后相差这么大的秘密-当前要闻
- 前沿资讯!四川阿坝州茂县发生3.2级地震
- 世界球精选!八年级上册语文课件ppt七彩课堂(八年级上册语文课件ppt)
- 圈圈圈住大神(圈圈圈住大神txt)
- 小儿鹅口疮怎么治好得快,小儿鹅口疮处理方法 今日报
- 全球热讯:人工智能冲击:美国5月失业岗位近4000个
- 环球讯息:鸿均老祖的师傅是谁啊(鸿均)
- 忱怎么读(忱)|全球微头条
- RTX 40系赚翻了!但RTX系列的安装量比例仍不足一半
- 突发!蔡英文与台空军通话,疑似"被解放军打断"!俄罗斯重大宣布:在此地部署核武器
- 美英领导人发表《大西洋宣言》 美英寻求建立“新型创新伙伴关系”!|环球热讯
X 关闭
最新资讯
- 茅台咖啡来了!12元可多加2ml飞天茅台酒 最新回应-快看点
- 零食赛道火热,三只松鼠“遇冷”-全球热资讯
- 被低估的智能门锁,为何成为智能家居顶流?
- “文根”何以“深种”?看文博会如何寻找岭南新坐标
- 天天短讯!什么算是一体成型 一体成型结构
- 厦门推出今年第二批商住用地 计划本月底拍卖出让-世界速看料
- 中国驻英使馆发言人就英国首相苏纳克涉华错误言论答记者问
- 高福回应:顶级中国科学家称不该排除实验室泄露?BBC又在抹黑
- 为工业机器人领域培育高素质技术技能人才
- 最资讯丨从越野的本质出发,为什么说坦克Hi4-T当下新能源越野的更优解
- 天天观点:沈阳2023租房公积金提取条件是什么?
- 自智网络中国产业峰会成功召开,联合倡议助推L4演进
- 世界关注:市场避险情绪缓和 预计原油或随宏观震荡运行
- 安徽印发行动方案加强外经贸金融服务 全球关注
- 沪深股通|登康口腔6月8日获外资买入249.0股
- 人工智能(AI)热潮提振了的科技股,并推高了对冲基金的回报,帮助他们挽回去年的损失 世界通讯
- 世界报道:中国进出口银行董事长吴富林:自贸区新格局下需要处理好三对关系
- 海口美兰区“魅力美兰潮玩文化节”周末市集三部曲即将开启|新消息
- 董家岭_关于董家岭的简介
- 仪征化纤公司荣获仪征市“环保示范性企业” 天天看热讯
- 爱旭股份副总经理卢浩杰:ABC组件可交付效率24% 电池效率年底目标27% 全球时快讯
- 今日热搜:“假新闻”扰乱市场!国际油价一度跌超4%
- 环球快讯:环保剑第二季(环保剑大结局)
- 互联网+废品回收 回收处理行业将迎来新的发展机遇 废品回收行业市场发展现状
- 天天快消息!注意!光库科技将于7月14日召开股东大会
- 当前热议!太平洋给予海德股份买入评级 海德股份:重视个贷不良资产处置中的AI+司法应用
- 截至6月1日当周 美国2022/2023年度大豆出口净销售为20.7万吨
- 小米13 Ultra DXOMARK评分不敌竞品
- 至于高考迟到几分钟近不近人情的事,本人这里有个极端的例子
- 海南省肿瘤医院率先引进宫颈癌早诊新技术[图] 世界看热讯
- 朱江入职Lucid,美国造车新势力能否成功入局中国市场?|视讯
- ecplaza主要什么产品_ecplaza 当前动态
- 加速推进5G全连接工厂建设 中兴通讯发布多个“价值用网”创新方案|全球微动态
- 【聚看点】建发致新6月15日深交所首发上会 拟募资4.84亿元
- 环球观速讯丨天津滨海新区2023招生幼儿园联系方式+地点
- 《神仙道3》游戏攻略介绍|热头条
- 大妈占科三考场晒麦 多名学员挂科:可取消考试再约,挂科要自行承担_环球快看点
- 去年全国法院审结环境资源案件24万余件 快讯
- 银川老年科技大学科普教学示范点在兴庆区挂牌 视讯
- 6月7日焦煤期货行情下跌-精选
- 今天周大生黄金首饰价格行情(2023年6月7日)
- 焦点讯息:河失镇吹响镇域河道汛期前安全清障集结号
- 硬核科技论 | 高通8295:算力暴涨8倍可带11块屏/真不是“马甲”-全球时快讯
- 亨迪药业06月07日主力资金大幅流出
- 全国爱眼日:“江苏博爱光明行”(常州)项目正式启动-世界快消息
- 昆凌17岁就被周杰伦追到手,她的旧照曝光后,难怪周杰伦急不可耐
- 【当前热闻】把好“四关”防风险
- Norges Bank增持万物云(02602)290.36万股 每股作价约28.19港元
- 全球动态:和胜股份:在项目研发前沿领域一直与宁德时代深度合作
- 塞尔达传说王国之泪你是萨派还是科派任务怎么做[多图]-全球速看料
X 关闭