回顾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>
相关推荐
Jerry6 小时前
使用 Material 3 在 Compose 中设置主题
前端
耶啵奶膘6 小时前
uni-app头像叠加显示
开发语言·javascript·uni-app
chéng ௹6 小时前
uniapp 封装uni.showToast提示
前端·javascript·uni-app
生擒小朵拉6 小时前
STM32添加库函数
java·javascript·stm32
tuokuac6 小时前
nginx配置前端请求转发到指定的后端ip
前端·tcp/ip·nginx
程序员爱钓鱼7 小时前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go
万少7 小时前
鸿蒙创新赛 HarmonyOS 6.0.0(20) 关键特性汇总
前端
还有多远.7 小时前
jsBridge接入流程
前端·javascript·vue.js·react.js
蝶恋舞者7 小时前
web 网页数据传输处理过程
前端