Vue3 父组件异步数据传给子组件,视图未更新

2023-11-14  本文已影响0人  Goorln

问题描述: 子组件中通过点击事件修改DOM元素中的selected选中项,数组中被选中的数据值更新了,但是视图未更新选中的样式

// 子组件
<view class="option">
   <view
      v-for="(item, index) in options.items"
      :key="index"
      class="item"
      :class="item.current ? 'selected' : ''"
      @tap="onClickItem(index)">
        <view class="item-t">{{ item.name }}</view>
        <view class="price"><text v-if="!options.showImg">¥</text>{{ item.price }}</view>
    </view>
</view>

const emit = defineEmits(['update:options'])
const onClickItem = (index) => {
  props.options.items.forEach((item, i) => {
    if (index === i) {
      item.current = !item.current
    } else {
      item.current = false
    }
  })
emit('update:options',  props.options)
}

// 父组件 
const options= ref({
  desc: '请选择',
  items: [
    { name: '选项一', price: '0.00', current: true },
    { name: '选项二', price: '2.00', current: false },
    { name: '选项三', price: '4.00', current: false },
    { name: '选项四', price: '6.00', current: false },
    { name: '选项五', price: '8.00', current: false },
    { name: '选项六', price: '10.00', current: false },
  ],
  showImg: false,
})
<ChildComponent
  v-model:options="options"
  @update:options="options = $event"
/>

onClickItem点击事件时,options.item里面的current的值更新了,但是视图中selected选中样式并未更新。

这是因为:在子组件中,虽然修改了 props.options 的值,但是 Vue 的 Props | 单向数据流特性
会阻止修改 prop

要让选中的项生效,可以:

这样就可以避免子组件直接修改父组件的状态了。

例如:

// 子组件
const emit = defineEmits(['update:selected'])
const selectedIndex = ref(0)
const onClickItem = (index) => {
  selectedIndex.value = index
  emit('update:selected', index)
  props.options.items.forEach((item, i) => {
    if (index === i) {
      item.current = !item.current
    } else {
      item.current = false
    }
  })
}

// 父组件 
<ChildComponent
  v-model:selected="selectedIndex"
  @update:selected="index => {
    options.items[index].current = true 
    options.items.forEach(item => {
      if(item !== options.items[index]) {
        item.current = false  
      }
    })
  }"
/>

最终效果如图所示:


demo.gif
上一篇 下一篇

猜你喜欢

热点阅读