当前位置: 首页 > article >正文

vue3的attr透传属性详解和使用法方式。以及在css样式的伪元素中实现

在 Vue 3 和 TypeScript 中,属性透传(attr pass-through)是指将组件的属性传递到其根元素或某个子元素中。这个概念在开发可复用的组件时非常有用,尤其是当你希望将父组件的属性动态地传递给子组件的某个 DOM 元素时。

在 Vue 3 中,透传属性通常使用 v-bind="$attrs" 结合 v-on="$listeners" 来实现。对于 CSS 样式中的伪元素,你可以通过 ::before::after 等伪元素来实现样式效果。

下面我将详细解释 Vue 3 中如何实现属性透传以及如何在 CSS 样式的伪元素中使用。

1. Vue 3 属性透传 (Attribute Pass-Through)

基本概念

在 Vue 中,$attrs 是一个包含父组件传递给子组件的所有属性的对象(不包括 classstyle)。这些属性可以通过 v-bind="$attrs" 来透传到子组件的根元素或某个特定元素。

$listeners (在 Vue 2 中称为 $on)用于监听父组件传递的事件,也可以通过 v-on="$listeners" 传递给子组件的元素。

例子:属性透传

假设你有一个 Button 组件,想要让父组件传递任何属性给 button 元素,比如 typedisabled

Button.vue(子组件)
<template>
  <!-- 使用 $attrs 将所有传递给该组件的属性透传到 button 元素 -->
  <button v-bind="$attrs" v-on="$listeners">
    <slot></slot>
  </button>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Button',
  // 此处我们可以定义 props,$attrs 会包括除了 props 之外的所有传递的属性
  props: {
    label: {
      type: String,
      required: true,
    }
  }
});
</script>
Parent.vue(父组件)
<template>
  <!-- 父组件传递属性到 Button 组件 -->
  <Button type="submit" disabled>
    Submit
  </Button>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import Button from './Button.vue';

export default defineComponent({
  components: {
    Button,
  }
});
</script>

在这个例子中,Button 组件接收到的 type="submit"disabled 属性会被透传到最终的 <button> 元素上。

注意事项

  1. $attrs 只包含父组件传递给子组件的属性(不包括 classstyle,这些属性会被自动透传)。
  2. 如果组件定义了自己的 props,传递给子组件的属性不会自动作为 props 接收,必须显式通过 v-bind="$attrs" 传递。

2. 在 CSS 伪元素中实现属性透传

CSS 伪元素(如 ::before::after)允许我们为元素添加样式和内容。我们可以通过 Vue 组件的 styleclass 来间接影响伪元素的样式。

基本的伪元素使用

假设我们要为一个按钮添加文本前缀或后缀,通过 CSS 伪元素来实现:

Button.vue(子组件)
<template>
  <button class="button" v-bind="$attrs">
    <slot></slot>
  </button>
</template>

<style scoped>
.button {
  position: relative;
  padding-left: 20px;
}

.button::before {
  content: attr(data-prefix);
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

.button::after {
  content: attr(data-suffix);
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}
</style>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Button',
  props: {
    label: String,
  }
});
</script>

在这个例子中,我们使用了 CSS ::before::after 来实现伪元素,并通过 data-* 属性将父组件传递的数据用于伪元素内容。

Parent.vue(父组件)
<template>
  <!-- 在父组件中,我们通过自定义属性传递值 -->
  <Button data-prefix="Start" data-suffix="End" label="Click Me">
    Button
  </Button>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import Button from './Button.vue';

export default defineComponent({
  components: {
    Button,
  }
});
</script>

解释

  1. Button.vue 中,::before::after 伪元素通过 content: attr(data-prefix)content: attr(data-suffix) 读取传递的自定义属性 (data-prefixdata-suffix)。
  2. Parent.vue 中,父组件传递了 data-prefixdata-suffix 属性,它们将会影响按钮的伪元素内容。

结合 v-bind::before::after

你还可以通过 v-bind="$attrs" 将属性传递给根元素,从而在根元素上动态地设置样式或其他属性。这可以进一步影响伪元素的样式。

<template>
  <button class="button" v-bind="$attrs">
    <slot></slot>
  </button>
</template>

<style scoped>
.button {
  position: relative;
}

.button::before {
  content: attr(data-content);
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}
</style>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Button',
  props: {
    label: String,
  }
});
</script>
父组件传递 data-content
<template>
  <Button data-content="Hello World!">
    Click Me
  </Button>
</template>

总结

  • 属性透传:使用 v-bind="$attrs"v-on="$listeners" 实现将父组件的属性和事件传递给子组件的 DOM 元素。
  • 伪元素使用:CSS 伪元素(如 ::before::after)可用 attr() 函数从元素的属性(如 data-* 属性)中提取内容并显示在页面上。

http://www.kler.cn/a/404716.html

相关文章:

  • 4.langchain中的prompt模板 (partially format prompt templates)
  • ant-design-vue中table组件多列排序
  • C语言Day 04 学习总结
  • Kubernetes 安装配置ingress controller
  • 量化加速知识点(整理中。。。)
  • 基于MySQL的 CMS(内容管理系统)的表结构设计
  • 2446.学习周刊-2024年46周
  • 深入解析QP算法及其Python实现
  • 沃丰科技智能质检与传统质检的对比
  • linux定时删除2周前的日志文件
  • windows基础二
  • sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
  • Docker nginx容器高可用(Keepalived)
  • 每日论文22-24ESSERC一种54.6-65.1GHz多路径同步16振荡器
  • 力扣第59题螺旋矩阵 II
  • 无人机场景 - 目标检测数据集 - 车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • React中使用echarts写出3d旋转扇形图
  • uniapp点左上角返回键, 重复来回跳转的问题 解决方案
  • C# OpenCV 通过高度图去筛选轮廓
  • 智慧路面管理系统平台 智慧照明 智慧市政 智慧交通
  • 40分钟学 Go 语言高并发:Go Channel使用与实践教程
  • k8s 集群安装
  • RTC QoS方法十三.(ReedSolomonFEC简介)
  • 音频信号采集前端电路分析
  • android版本ijkplayer2024编译笔记
  • 开源模型应用落地-qwen模型小试-调用Qwen2-VL-7B-Instruct-更清晰地看世界-vLLM+Docker(七)