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>
标签:
推荐文章
- 执炬奔跑,梦想生生不息——访杭州亚运会火炬手
- 肝火旺有什么症状 肝火旺的症状吃什么药
- 推行“三三”工作模式 石门县公安局全力护航开学季
- 惠安县开展教师节慰问活动
- 长春到沈阳需要隔离吗6月
- 美元指数持续走强,人民币汇率调整压力加大
- 股票行情快报:盘江股份(600395)9月8日主力资金净卖出327.07万元
- 上市四个月急推重组,荣旗科技欲加码新能源领域业务
- 蚂蚁集团正式发布金融大模型,针对个人和专业用户分别推出两大产品
- 海螺水泥(00914)出资10亿元携金石投资等参设合伙企业
- 让生活垃圾“变废为宝”,他们这样做
- 微软正在测试Paint中的背景去除工具
- 破发股巨一科技上半年净利降67% 2021年上市募15.8亿
- 期权有什么投资价值为什么?
- 把“世界超市”义乌搬上京东 京东9.9超省日打造靠谱版“9.9包邮”
- 薛之谦演唱安河桥说再见 薛之谦献唱安河桥
- 参与隋田力造假大案 又有两家上市公司将被罚
- 广哈通信9月8日快速反弹
- 我们几个朋友有轮着组饭局(买单)的习惯
- 跨省就医、交通出行、文旅购票……你手里的这张卡还有这些用处→
- 国有五大行、招行等今迎新一轮存款利率下调,最高降幅达25个基点
- 当好东道主 喜迎山旅会——“万马”奔腾:闻稻谷飘香 品诗酒田园
- 你的思维方式,决定了你的职场高度
- qq炫舞2挂(炫舞2挂)
- 失主刚刚报警,窃贼已被抓获
- 早晨吃牛奶还是晚上喝牛奶好(早晨吃牛奶好还是晚上喝牛奶好)
- 受台风影响,未来三天广珠城际全部列车停运
- 深度金选|年内涨停超30次、成AI首只10倍股!绑定英伟达,鸿博股份第六次转型会成功吗?
- 人民币大消息
- 金枪鱼进出口市场分析 国内金枪鱼行业市场如何?
- 价格暴涨4倍还多:玩家怀念30美元能买PS+一整年
- 聚维酮碘商品报价动态(2023-08-31)
- 高质量发展在申城|对接虹桥国际开放枢纽建设这一国家战略,长宁怎么做?
- 滨海新区警方擒获“百万大盗”
- 陕西发布全国首个考古工地安全专业标准
- 英国空管系统故障或致航司损失1亿美元
- 今起降价!有的便宜了9535元
- 经济法基础考点强化(55)
- 排位赛日本暂列O组第一 中国男篮M组第四 直通巴黎日本占尽先机
- 拼劲十足!崔永熙仅出战9分钟 1中1得到4分1助攻2抢断1追帽
- 物流数据看亮点 经济发展“脉动”强劲
- 揭秘康灵盾为东方肥牛王火锅定制的小料台设计!
- 贩卖明星航班侵犯隐私 航空公司两客服获刑3年
- 吸金不断!Tims天好中国二季度营收4.117亿【附咖啡行业市场分析】
- 人民币市场汇价(8月30日)
- 湘江开放日,为高校学子“智”引未来
- 高新区(新市区):反诈宣传进社区 守护平安聚民心
- 院线电影《加班惊魂》开机 新锐演员鲍李宁担男一引期待
- 让气象雷达更加“耳聪目明”
- 全省法院全链条打击电信网络诈骗犯罪
- 2021年郭冬临小品就地过年(郭冬临小品回家过年是哪年春晚)
- 沪深股通|泰坦科技8月29日获外资买入0.37%股份
- 古代最著名的五大才女(值得收藏史上四大才女)
- “华尔街之狼”正在抄底中国房地产
X 关闭
最新资讯
- 中国梦·大国工匠篇丨我在三江源国家公园当宣传员
- 海河,“津门古渡”的“活力秀带”
- 博山区猕猴桃园开始采摘
- 60余名省内外专家学者、与会嘉宾走进“明代生活的活化石”平坝天龙屯堡
- 港股内房股午后持续走高 绿城中国涨超12%
- 30万株醉蝶花“落户”滨海公园
- “拿什么拯救你,我的男篮” 天时地利人和皆不利,出局基本成定局
- 马士基供应服务公司将削减100多个工作岗位,以简化运营
- 高层次人才赋能首府产业发展研讨会召开
- 分析|湖人新赛季可能看到的5套阵容 双塔or射手阵or詹中锋?
- 成都GDP首次半年破万亿元,高质量发展取得积极进展
- 莱西公交22路(关于莱西公交22路的简介)
- 猪笼草的功效与作用(猪茏草)
- 魔兽世界怀旧服邪恶临近任务怎么做(wowtbc怀旧服邪恶临近任务流程攻略)
- 关爱留守儿童,天旅投集团在行动!
- 84健康/眼部除皱哪家医院好 眼部除皱专家)
- 南昌小伙被诱骗至柬埔寨,江西警方跨境成功解救!
- 男生拍照摆pose大全(男生怎么拍照好看又上镜)
- 华鑫证券:五箭齐发,超跌反弹一触即发
- 行政复议法修订草案三审:扩大行政复议范围、完善行政复议前置范围
- 湖北荆州:用绘本记录旅程 10岁小学生绘“卷”成“书”
- 中国空间站已开展上万次在轨实验
- 制造业当家,全国首个千亿工业大镇容桂,如何转型再突围?
- 《创3》主题曲考核,希林娜依·高逆袭成功,张艺凡引争议
- 福建启动预防台风“苏拉”Ⅳ级应急响应
- 一屋两人三餐四季搞笑下联 一屋两人三餐四季 求一个下联 求浪漫的 谢谢
- 中国太保上半年营业收入同比增长6.5%
- 祥生医疗(688358.SH):选举莫若理为公司第三届董事会董事长
- 极端天气发生后,对GDP有哪些影响?怎样减小损失?
- 李凯尔低迷原因曝光!主教练说出真相,3大水货出炉,王哲林上榜
- 煤炭行业:钢铁方案未提平控 中报披露业绩回落
- 多地盐业:管够,不用囤货
- 保时捷boxster报价
- 客厅电视机尺寸选择标准 客厅电视机尺寸选择
- 原神湖畔的维维安涅成就完成方法
- 我用席慕蓉的诗谱了曲,可以上传到网络上吗
- 拟上市公司实控人母亲或曾是疫苗临床研究所领导
- 释放创新创造活力 为人才提供全方位全周期服务
- 姚洋:中国经济未来的动力是创新,但创新就会有泡沫
- 黔东南“黎从榕”加快对接融入粤港澳大湾区
- 进口禁令,五国达成一致
- 俄称击落乌无人机 乌称打击俄多个目标
- 股票行情快报:索菱股份(002766)8月25日主力资金净卖出219.25万元
- 英国的文化特色有哪些用英语描写(英国的文化特色有哪些)
- 手机相关知识:网易考拉入驻商家条件
- 联盟猎人去哪里抓猪(QQ飞车抓猪是什么意思)
- 铂科新材股东户数增加45.79%,户均持股71.02万元
- 突发!陕西一高速路桥台路面塌陷!这雨是真大、天气是真恶劣!
- 两部门:继续实施公共租赁住房税收优惠政策
- 2023内蒙古锡林浩特市招聘义务教育阶段学校教师(应届毕业生)拟聘公示
X 关闭