回顾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>
相关推荐
蓝冰凌7 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
Volunteer Technology7 小时前
中间件场景题归纳
中间件·面试·架构
奔跑的呱呱牛7 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉7 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
Greg_Zhong8 小时前
前端基础知识实践总结,每日更新一点...
前端·前端基础·每日学习归类
We་ct8 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
TON_G-T8 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
发际线还在8 小时前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
IT_陈寒8 小时前
JavaScript开发者必看:5个让你的代码性能翻倍的隐藏技巧
前端·人工智能·后端