Vue列表组件不呈现对象属性

dw1jzc5e  于 2023-08-07  发布在  Vue.js
关注(0)|答案(3)|浏览(131)

我在vue 3中有2个组件;第一个是FilmComp.vue,它表示单个电影(一个带有某些属性的卡片div);第二个是ListFilms.vue,它表示使用v-for渲染的Film组件列表,但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组件应该是see film property object,用于在html中执行数据绑定({{ -- }}语法)。

ou6hu8tu

ou6hu8tu1#

问题是您声明了一个名为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
  }
})


这样,在template部分中,您就不再需要显式引用props,因为当您要从props对象中提取属性时,Vue会自动检测到它。
在本例中,在<script>部分中,可以通过props变量访问属性。

console.log(props.film)


<template>部分中,应该在不使用“props”关键字的情况下引用它,类似于“Options API”。在<script>节中声明变量时,不要使用与属性同名的名称,这一点非常重要!因此,在这种情况下,不应该有类似const film = 'test'或类似的声明...

{{ film }}


VuePlayground

是否需要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>

更多信息

  • prop 声明- Vue文档
  • defineProps()- Vue文档
jaxagkaj

jaxagkaj2#

const props = defineProps({
  film: {
    type: Object,
    required: true
  }
});

字符串
应该没问题。您正在定义一个与'film'对象同名的常量。
如果您不打算在'script'标记之间使用常量,那么不将props分配给常量的访问也是可以的。

7vux5j2d

7vux5j2d3#

您正在定义props,但试图将结果props对象用作单个prop; defineProps()返回一个以props为属性的reactive对象。
由于您使用的名称(与 prop 相同),它隐藏了实际的 prop ,您最终尝试访问不存在的 prop 。
你该换衣服了

const film = defineProps({
  // ...
})

字符串

const props = defineProps({
  // ...
})


或者是

defineProps({
  // ...
})

**模板中,**可以直接使用 prop ;你不必使用props对象。您甚至不需要分配它,如上面的第三个代码块所示。

但是,我认为这是一种反模式,因为它模糊了数据源,并允许在出现任何警告时隐藏名称(如您的情况)。在props对象上访问它们或使用toRefs()明确定义它们可以避免这些问题。
这种方法的一个更好的方法是使用$props对象(仅模板的“Meta变量”)。
这也解决了前面提到的问题,但在脚本中没有任何额外的开销。
如果需要,可以使用解构props对象的常见模式:

const props = defineProps({
  film: {
    type: Object,
    required: true
  }
})

const { film } = toRefs(props)


它使用toRefs()辅助对象提取film属性作为引用。
它允许在脚本中使用**直接访问props,而不必在props对象上引用它们。它还明确定义了 prop 的名称,允许在模板中直接使用,同时仍然避免了名称隐藏的可能性。

相关问题