我在 Vue.js 3 中有 2 个组件;第一个是
FilmComp.vue
表示单个影片(具有某些属性的卡片 div)和 ListFilms.vue
表示使用 v-for
渲染的影片组件列表,但 FilmComp.vue
看不到影片对象属性。
FilmComp.vue
<template>
<div
class="relative flex w-96 flex-col rounded-xl bg-white bg-clip-border text-gray-700 shadow-md"
>
<div
class="relative mx-4 mt-4 h-80 overflow-hidden rounded-xl bg-white bg-clip-border text-gray-700 shadow-lg"
>
<img :src="film.imgSrc" alt="profile-picture" />
</div>
<div class="p-6 text-center">
<h4
class="mb-2 block font-sans text-2xl font-semibold leading-snug tracking-normal text-blue-gray-900 antialiased"
>
{{ film.title }}
</h4>
<p
class="block bg-gradient-to-tr from-pink-600 to-pink-400 bg-clip-text font-sans text-base font-medium leading-relaxed text-transparent antialiased"
>
{{ film.genre }}
</p>
</div>
<div class="flex justify-center gap-7 p-6 pt-2">
{{ film.year }}
</div>
</div>
</template>
<script setup>
const film = defineProps({
film: {
type: Object,
required: true
}
})
</script>
ListFilms.vue
<template>
<div class="bg-white">
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl lg:px-8">
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-4 xl:gap-x-8">
<div v-for="film in films" :key="film.id" class="group relative">
<FilmComp :film="film" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import FilmComp from './FilmComp.vue'
const films = ref([
{
id: 1,
title: 'The Shawshank Redemption',
year: 1994,
genre: 'drama',
imgSrc: 'aaaaaaaaa'
},
{
id: 2,
title: 'The Godfather',
year: 1972,
genre: 'drama',
imgSrc: 'aaaaaaaaa0'
},
{
id: 3,
title: 'The Godfather: Part II',
year: 1974,
genre: 'drama',
imgSrc: 'aaaaaaaaa1'
}
])
</script>
ListFilms
组件应参见电影属性对象,用于在html中启动数据({{ -- }}
语法)。
问题是您声明了一个名为
film
的变量。你说这个变量的值应该是元素的所有属性。其中一项属性是 film
。
因此,您可以从 const 对象访问属性
film
。其中一项属性名为 film
。因此,在您的情况下,提取 film
属性将是 film.film
。一般来说,在大约 99% 的情况下,我们将属性命名为
props
。
const props = defineProps({ ... });
在这种情况下,我可以通过const变量
props
访问元素的所有属性。如果我声明一个名为 film
的属性,我将以 props.film
的形式访问它。
const props = defineProps({
film: {
type: Object,
required: true
}
})
这样,在模板部分,您不再需要显式引用
props
,因为当您想要从 props 对象中提取属性时,Vue 会自动检测到它。
在这种情况下,在
<script>
部分中,您可以通过 props 变量访问属性。
console.log(props.film)
在
<template>
部分,您应该在不使用“props”关键字的情况下引用它,类似于“Options API”。重要的是不要声明与 <script>
部分中的属性同名的变量!所以,在这种情况下,不应该有类似 const film = 'test'
或类似的声明...
{{ film }}
const props
有必要吗?如果您不想引用
<script>
部分中的任何属性,则没有必要。
const props
(仅使用<template>
)<!-- WORKING -->
<template>
<div>{{ film }}</div> <!-- WORKING -->
</template>
<script setup>
defineProps({
film: {
type: Object,
required: true
}
})
</script>
const props
(仅使用<template>
)<!-- WORKING -->
<template>
<div>{{ film }}</div> <!-- WORKING -->
</template>
<script setup>
const props = defineProps({
film: {
type: Object,
required: true
}
})
</script>
但是,如果您想在某处引用它们,则需要声明
const props
,因为它允许您重用 <script>
中的属性。我建议始终将其声明为 const props
并保留为此目的保留的变量名称 props
,以保持清晰且有组织的代码。
const props
<!-- ERROR -->
<template>
<div>{{ film }}</div> <!-- WORKING -->
</template>
<script setup>
defineProps({
film: {
type: Object,
required: true
}
})
console.log(film) // ERROR: film is not defined
</script>
const props
<!-- WORKING -->
<template>
<div>{{ film }}</div> <!-- WORKING -->
</template>
<script setup>
const props = defineProps({
film: {
type: Object,
required: true
}
})
console.log(props.film) // WORKING
</script>
defineProps()
-Vue 文档您正在定义 props,但尝试将生成的 props 对象用作单个 prop;
defineProps()
返回一个以 props 作为属性的响应式对象。你应该改变
const film = defineProps({
// ...
})
到
const props = defineProps({
// ...
})
或
defineProps({
// ...
})
在模板中,可以直接使用props;您不必使用 props 对象。您甚至不需要分配它,如上面的第三个代码块所示。
但是,我认为这是一种反模式,因为它掩盖了数据的来源,并允许名称被引发的任何警告所掩盖(如您的情况)。 在 props 对象上访问它们或使用
toRefs()
明确定义它们可以避免这些问题。
这种方法的更好方法是使用
$props
对象(仅模板“元变量”)。如果需要,您可以使用解构 props 对象的常见模式:
const props = defineProps({
film: {
type: Object,
required: true
}
})
const { film } = toRefs(props)
这使用
toRefs()
助手来提取 film
道具作为参考。
它允许在脚本中使用 直接访问 props,而不必在 props 对象上引用它们。 它还明确定义了道具的名称,允许在模板中直接使用,同时仍然避免名称隐藏的可能性。