Vue 列表组件不渲染对象属性

问题描述 投票:0回答:2

我在 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中启动数据(
{{ -- }}
语法)。

javascript vue.js vuejs3
2个回答
1
投票

问题是您声明了一个名为

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 }}

Vue 游乐场

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>

更多信息


0
投票

您正在定义 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 对象上引用它们。 它还明确定义了道具的名称,允许在模板中直接使用,同时仍然避免名称隐藏的可能性。

© www.soinside.com 2019 - 2024. All rights reserved.