首页 > 解决方案 > 为什么我使用方法时我的 vue3 组件没有更新?

问题描述

我有一个卡片选择器组件,让用户从一副牌中挑选一些卡片。这是我的 Vue3 代码:

<template>
  <v-layout row justify-center>
    <card3
      v-for="(card, index) in cards"
      :key="index"
      :card="card"
      :cardWidth="cardWidth"
      :isSelected="contains(card, selectedCards)"
      v-on="$listeners"
    ></card3>
  </v-layout>
</template>

<script lang="ts">
import { defineComponent, ref, contains, watch, computed } from "@/common"
import Card3 from "@/components/Card3.vue"
import { Cards, Card } from "@/types"

type Props = {
  selectedCards: Cards
}

export default defineComponent({
  props: {
    cards: {
      type: Array,
      default: () => []
    },
    selectedCards: {
      type: Array,
      default: () => []
    },
    faceUp: {
      type: Boolean,
      default: true
    },
    cardWidth: {
      type: Number,
      default: 16
    }
  },
  components: {
    Card3
  },

  setup(props: Props, context) {
    const { selectedCards } = props

    return {
      contains
    }
  }
})
</script>

该组件从父组件中获取卡片和 selectedCards。然后它会检查是否选择了卡片,然后将该信息传递给子组件,该子组件呈现卡片并在所选卡片周围放置边框。

此时一切都按预期工作!

但是,现在我想做一个小的重构。我创建了一个方法 isSelected 并将其公开给模板:

const isSelected = (card: Card) => contains(card, selectedCards)

return {
  contains,
  isSelected
}

然后我使用模板中的方法而不是包含:

:isSelected="isSelected(card)"

但是,该组件现在已停止工作!selectedCards 按预期更新,但子组件未按预期更新所选卡片。当我进行这一次更改时,指示所选卡片的边框不会被重新渲染。

有人可以解释我为什么吗?

我试图将所有这些都放在codesandbox.io上的一个工作示例中,但不幸的是我不得不放弃。

标签: vue.js

解决方案


我发现了问题。问题是我正在破坏我的道具,从而失去反应性。

如果我改为这样做:

const isSelected = (card: Card) => contains(card, props.selectedCards)

或这个:

const { selectedCards } = toRefs(props)

...然后我(显然)保持反应性并且它起作用了。谈论一个陷阱!

谢谢您的帮助!


推荐阅读