本文详解 vue 3 `
在 Vue 3 的组合式 API 中,defineProps() 是声明组件接收外部属性的核心机制。但一个常见却极易被忽视的逻辑错误是:在 。这会导致 film 变量本身成为整个 props 对象,而其内部的 film 属性反而被“遮蔽”——即 film.title 实际访问的是 props.film.title,但此时 film 已不是原始数据对象,而是 props 容器,从而引发模板中 {{ film.title }} 报错或渲染为空。
✅ 正确做法:统一使用 props 作为 props 对象标识符
修改 FilmComp.vue 的
✅ 关键点说明:
- props 是约定俗成、语义清晰的变量名,99% 的 Vue 项目都采用此命名,避免歧义;
- 模板中仍直接使用 {{ film.title }}、:src=”film.imgSrc” 等语法——Vue 会自动从 props 对象中解构并暴露所有 prop 名为顶层变量(即“模板自动解构”),无需写 props.film.title;
- 若需在
❌ 错误示例(问题根源)
// ❌ 危险!创建了同名变量,造成作用域污染
const film = defineProps({ film: { type: Object, required: true } })
// 此时 film === { film: { ... } },而非预期的 { title, year, ... }
// 模板中 {{ film.title }} 实际尝试访问 undefined.title → 渲染失败
? 补充优化建议
-
添加类型提示(推荐 TypeScript 或 JSDoc)
提升开发体验与安全性:// FilmComp.vue —— 使用 TypeScript 类型 interface Film { id: number title: string year: number genre: string imgSrc: string } const props = defineProps() -
Prop 校验增强(可选)
确保传入对象结构完整:const props = defineProps({ film: { type: Object as PropType, required: true, validator: (v: Film) => v.id && v.title && v.imgSrc // 自定义校验 } }) -
ListFilms.vue 无需改动
你当前的列表组件写法完全正确: 会将每个数组项作为 film prop 传入,只要子组件 FilmComp.vue 正确定义并消费 props,即可正常渲染。
✅ 最终验证效果
修复后,FilmComp.vue 模板中的以下绑定将全部生效: