回顾vue中的Props与Attrs

基本功能

  1. props常用来数据通信
  2. attars所有非props属性的透穿

props传值:

基本传值‌

xml 复制代码
<!-- 父组件 -->
<ChildComponent title="欢迎页面" />

<!-- 子组件 -->
<script>
export default {
  props: ['title']
}
</script>

动态绑定‌

xml 复制代码
<!-- 父组件 -->
<ChildComponent :count="dynamicValue" />

<!-- 子组件 -->
<script>
export default {
  props: ['count']
}
</script>

类型验证‌

yaml 复制代码
// 子组件
props: {
  age: {
    type: Number,
    required: true,
    validator: value => value > 0
  }
}

默认值设置‌

css 复制代码
props: {
  theme: {
    type: String,
    default: 'light'
  }
}

对象形式传值‌

xml 复制代码
<!-- 父组件 -->
<UserProfile v-bind="userData" />

<!-- 等价于 -->
<UserProfile 
  :name="userData.name"
  :age="userData.age"
  :email="userData.email" 
/>

attars属性透穿

属性透穿的主要特点既然是接受非props以外的属性,前端可以主动接受某些特定的属性,也可以不接受这些属性。

实际应用场景如下:

组件的二次封装,比如常见的按钮:

子组件

xml 复制代码
<template>
  <!-- 按钮组件,使用动态class绑定 -->
  <button 
    class="base-btn" 
    :class="computedClasses" 
    v-bind="attrs"  <!-- 透传其他属性(如disabled、title等) -->
  >
    <slot></slot>
  </button>
</template>

<script setup>
import { useAttrs, computed } from 'vue'

// 获取所有透传的非props属性
const attrs = useAttrs()

// 根据透传的属性计算样式类
const computedClasses = computed(() => {
  const classes = []
  
  // 如果透传了type属性,添加对应的样式类
  if (attrs.type) {
    classes.push(`btn-${attrs.type}`)
  }
  
  // 如果透传了size属性,添加对应的样式类
  if (attrs.size) {
    classes.push(`btn-${attrs.size}`)
  }
  
  // 如果透传了round属性,添加圆角样式
  if (attrs.round) {
    classes.push('btn-round')
  }
  
  // 如果透传了special属性,添加特殊样式
  if (attrs.special) {
    classes.push('btn-special')
  }
  
  return classes
})
</script>

<style scoped>
/* 基础按钮样式 */
.base-btn {
  padding: 8px 16px;
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s ease;
}

/* 不同类型按钮的样式 */
.btn-primary {
  background-color: #42b983;
  color: white;
}

.btn-danger {
  background-color: #ff4444;
  color: white;
}

.btn-warning {
  background-color: #ffbb33;
  color: black;
}

/* 不同尺寸按钮的样式 */
.btn-small {
  padding: 4px 8px;
  font-size: 12px;
}

.btn-large {
  padding: 12px 24px;
  font-size: 16px;
}

/* 圆角样式 */
.btn-round {
  border-radius: 20px;
}

/* 特殊样式 */
.btn-special {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  text-transform: uppercase;
  letter-spacing: 1px;
}

/* 鼠标悬停效果 */
.base-btn:hover {
  opacity: 0.9;
  transform: translateY(-2px);
}
</style>

父组件

xml 复制代码
<template>
  <div class="button-group">
    <!-- 基础按钮 -->
    <CustomButton>基础按钮</CustomButton>
    
    <!-- 主要按钮(带类型) -->
    <CustomButton type="primary">主要按钮</CustomButton>
    
    <!-- 危险按钮(带类型和尺寸) -->
    <CustomButton type="danger" size="large">危险按钮</CustomButton>
    
    <!-- 警告按钮(带类型、尺寸和圆角) -->
    <CustomButton type="warning" size="small" round>警告按钮</CustomButton>
    
    <!-- 特殊按钮(带自定义属性) -->
    <CustomButton special title="这是一个特殊按钮">特殊按钮</CustomButton>
    
    <!-- 禁用状态按钮(透传原生属性) -->
    <CustomButton type="primary" disabled>禁用按钮</CustomButton>
  </div>
</template>

<script setup>
import CustomButton from './CustomButton.vue'
</script>

<style scoped>
.button-group {
  display: flex;
  gap: 10px;
  padding: 20px;
  flex-wrap: wrap;
}
</style>
相关推荐
竟未曾年少轻狂1 小时前
Vue3 生命周期钩子
前端·javascript·vue.js·前端框架·生命周期
TT哇1 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
蓝帆傲亦1 小时前
Web前端跨浏览器兼容性完全指南:构建无缝用户体验的最佳实践
前端
晴殇i1 小时前
【前端缓存】localStorage 是同步还是异步的?为什么?
前端·面试
不一样的少年_1 小时前
Chrome 插件实战:如何实现“杀不死”的可靠数据上报?
前端·javascript·监控
深度涌现1 小时前
DNS详解——域名是如何解析的
前端
小码哥_常1 小时前
Android内存泄漏:成因剖析与高效排查实战指南
前端
卤代烃1 小时前
✨ 形势比人强,Chrome 大佬也去搞 Gemini 了
前端·agent·vibecoding
偶像佳沛1 小时前
JS 对象
前端·javascript
Jing_Rainbow2 小时前
【React-6/Lesson89(2025-12-27)】React Context 详解:跨层级组件通信的最佳实践📚
前端·react.js·前端框架