【从零开始学习Vue|第七篇】深入组件——Props

1. Props声明

  • 一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute

在使用 <script setup> 的单文件组件中,props 可以使用 defineProps() 宏来声明:

xml 复制代码
<script setup>
const props = defineProps(['foo'])

console.log(props.foo)
</script>

除了使用字符串数组来声明 props 外,还可以使用对象的形式:

xml 复制代码
// 使用 <script setup>
defineProps({
  title: String,
  likes: Number
})

对于以对象形式声明的每个属性,key 是 prop 的名称,而值则是该 prop 预期类型的构造函数。比如,如果要求一个 prop 的值是 number 类型,则可使用 Number 构造函数作为其声明的值。

2. 响应式Props解构(vue3.5)

2.1. Vue3.5 之前

在 Vue 3.4 及之前版本,直接解构 defineProps()丢失响应性

xml 复制代码
<script setup>
// ❌ 错误方式 - 会丢失响应性
const { title } = defineProps(['title'])

// 当父组件更新 title 时,这里的 title 不会更新
</script>

传统解决方案:需要使用 toRefs()toRef() 来保持响应性:

xml 复制代码
<script setup>
import { toRefs, toRef } from 'vue'

const props = defineProps(['title', 'count'])

// 方案1:toRefs 保持响应式引用
const { title, count } = toRefs(props)

// 方案2:toRef 单个转换
const title = toRef(props, 'title')
</script>

2.2. Vue3.5 新特征

Vue 3.5 允许直接解构 defineProps(),同时自动保持响应性:

xml 复制代码
<script setup>
// ✅ Vue 3.5+ 可以直接解构,保持响应性
const { title, count } = defineProps(['title', 'count'])

// 这些变量是响应式的,会随父组件更新而更新
</script>

3. 传递prop的细节

3.1. Prop名字格式

如果一个 prop 的名字很长,应使用 camelCase 形式,因为它们是合法的 JavaScript 标识符,可以直接在模板的表达式中使用,也可以避免在作为属性 key 名时必须加上引号。

scss 复制代码
defineProps({
  greetingMessage: String
})
css 复制代码
<span>{{ greetingMessage }}</span>

3.2. props校验详解

3.2.1. 基础语法(对象语法)

xml 复制代码
<script setup>
const props = defineProps({
  name: {
    type: String,
    required: true,
    default: '匿名用户',
    validator: (value) => {
      return value.length > 0
    }
  }
})
</script>

也可以支持多类型,如下

xml 复制代码
<script setup>
const props = defineProps({
  // 可以是字符串或数字
  id: [String, Number],
  
  // 可以是字符串或布尔值
  flag: [String, Boolean],
  
  // 多种类型
  value: [String, Number, Boolean, Object]
})
</script>
相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学2 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端