记自己学习Vue3做项目时碰到的一个小坑
直接上简化后的代码
import Child from './components/Child.vue'
import { ref } from 'vue'
const config = [{
filed: 'id',
lable: 'id'
}, {
filed: 'name',
lable: '用户名'
},
]//配置
const defaultInfo = {}
config.forEach(item => {
defaultInfo[item.filed] = ''
})//获取自己需要的字段
const formData = ref(defaultInfo)
const handleData = (data) => {
Object.keys(data).forEach(key => {
if (key in defaultInfo) {
defaultInfo[key] = data[key]
}
})
formData.value = defaultInfo //更新值
//console.log(formData.value)
}
<template>
<div style="background-color: aqua;">
<h1>获得的数据:</h1>
<h1 v-for="item in formData">{{ item }}</h1>
</div>
<Child @handle-post-data="handleData"></Child>
</template>
问题描述
子组件被点击后会给父组件传数据data(table中的一行数据),但是我们并不需要所有的数据,于是根据配置中数据初始化一个普通对象,包含着我们需要数据的key,然后监听数据时先判断key是否需要后再设置,但是点击的时候发现视图却没有更新,输出值发现formData的值也变了,但视图却没更新。
分析和解决
最后发现是因为 formData.value = defaultInfo 这一行赋值操作出了问题,按照官方文档来说ref返回一个响应式对象,改变value值会触发响应,但是我们这样赋值实际没有改变value的值,因为defaultInfo是对象,属于引用类型,我们改变它的key,value时并没有修改它的值,所以不会触发vue的响应式系统,明白是这个原因后我们只要修改为 formData.value = {...defaultInfo} 即可触发视图更新。