vue 修改v-for 循环内的item数据视图不刷新

需求

修改v-for后得到的每一项内的某个数据,视图应当重新渲染

如下面的代码

============================================
这是父组件,给子组件传了一个 类型为
interface DataType { title: string value: string show: boolean } 的数组

<template>
    <Tree :options="dataSource" />
</template>

<script setup lang="ts">

import Tree from '@/test/tree/Tree.vue'

const dataSource = [
  {
    title: 'test1',
    value: 'test1',
    show: false
  },
  {
    title: 'test2',
    value: 'test2',
    show: false
  },
  {
    title: 'test3',
    value: 'test3',
    show: false
  }
]
</script>

这是子组件

<script lang="ts" setup>
import { ref, toRefs } from 'vue'

export interface DataType {
  title: string
  value: string
  show: boolean
}

//获取父组件传过来的props,并把数据变成响应式
const props = defineProps<{ options: DataType }>()
const { options: dataSource } = toRefs(props)

//监听点击事件,并将循环后的item数据拿到并修改
//按理来说数据已经用toRefs响应式监听了,修改数据视图应该改变才对
//但是运行代码后视图并没有刷新
const select = ref<DataType>({ title: '', value: '', show: false })
const onClick = (item: DataType) => {
  item.show = !item.show
}
</script>

<template>
  <div class="wrap">
    <div v-for="item in dataSource" :key="item.title">
      //点击这个元素将item上的属性show变成true或者false
      <div class="title" @click="onClick(item)">{{ item.title }}</div>
      //当item对象上的show属性为true时应该展示在视图上
      <div class="content" v-if="item.show">{{ item.value }}</div>
    </div>
  </div>
</template>


原因

1.toRefs(props)确实会把这个对象编程响应式,所以监听元素click事件并修改item上的show时 dataSource的确会变
2.dataSource变化后vue会重新执行这个组件内的代码获取新的虚拟dom然后去对比之前的dom再局部更新,
3.关键再于vue重新执行这个组件内的代码时又拿到了父组件传来的数据,而这个数据自始自终是没有发生改变的,所以得到的虚拟dom永远和第一次渲染的dom一模一样所以视图永远不变

解决方法

父组件传数据的时候应该传个ref这能解决这个问题,但是vue不推荐子组件修改外部数据

const dataSource = ref<DataType[]>([
  {
    title: 'test1',
    value: 'test1',
    show: false
  },
  {
    title: 'test2',
    value: 'test2',
    show: false
  },
  {
    title: 'test3',
    value: 'test3',
    show: false
  }
])
思考

当数据不是重父组件传过来的,修改v-for传回的数据会不会改变视图?

答案是会的,只要这个数据用响应式ref或者reactive包裹就可以

总结

1.子组件不应该修改外部数据,应该通知父组件修改数据
2.在不方便通知父组件修改数据时,父组件应该传ref给子组件不然子组件修改的数据永远数复制品,没有效果

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值