当前位置: 首页 > 知识库问答 >
问题:

vue3 - 用@update:modelValue方法,为啥子组件把数据置空,父组件不同步生效?

羊舌墨一
2023-08-06
//父组件<template>  <div>    <Search v-model="form" @getData="getData" />    <el-divider />    <el-form ref="formRef" :model="form" label-width="120px" class='flex'>      <el-form-item label="项目名称">        <el-input v-model="form.name" />      </el-form-item>      <el-form-item label="申请类型">        <el-select v-model="form.region" placeholder="请选择">          <el-option label="北京" value="北京" />          <el-option label="广州" value="广州" />        </el-select>      </el-form-item>      <el-form-item label="申请时间">        <el-date-picker          v-model="form.date"          type="daterange"          range-separator="至"          start-placeholder="开始时间"          end-placeholder="结束时间"          :size="size"        />      </el-form-item>      <!-- <el-form-item>        <el-button @click="resetForm">重置</el-button>        <el-button type="primary" @click="onSubmit">查询</el-button>      </el-form-item> -->  </el-form>  </div></template>
<script lang='ts' setup>import {defineComponent, reactive, toRefs, ref, onBeforeMount, onMounted } from 'vue';import Search from './search.vue';const form = reactive({  name: '',  region: '',  date: '',})function getData(){  console.log('form54',form);  }</script><style scoped lang="scss">.flex{  display: flex;  flex-wrap: wrap;}</style>
//子组件<template>  <el-form ref="formRef" :model="formData" label-width="120px" class='flex'>    <el-form-item label="项目名称">      <el-input v-model="formData.name" />    </el-form-item>    <el-form-item label="申请类型">      <el-select v-model="formData.region" placeholder="请选择">        <el-option label="北京" value="北京" />        <el-option label="广州" value="广州" />      </el-select>    </el-form-item>    <el-form-item label="申请时间">      <el-date-picker        v-model="formData.date"        type="daterange"        range-separator="至"        start-placeholder="开始时间"        end-placeholder="结束时间"        :size="size"      />    </el-form-item>    <el-form-item>      <el-button @click="resetForm">重置</el-button>      <el-button type="primary" @click="onSubmit">查询</el-button>    </el-form-item>  </el-form></template>
<script lang="ts" setup>import { reactive, ref, watch, nextTick } from 'vue'const props = defineProps({    modelValue: {      type: String,      default: '',    },})const formRef = ref();const formData = ref<any>(props.modelValue);const emit = defineEmits(['update:modelValue', 'getData']);watch(  () => props.modelValue,  (d) => {    formData.value = d  })watch(  () => formData.value,  (data) => {    console.log('data56',data);    emit('update:modelValue', data)  },  {    deep: true,  })// 重置function resetForm(){    formData.value = {};    // formData.value.region = '';    emit('getData');}// 查询const onSubmit = () => {  console.log('submit!')}</script><style scoped lang="scss">.flex{  display: flex;  flex-wrap: wrap;}</style>

1691242933539.png

问题:为啥子组件重置把 formData.value 置空后,父组件的 form 不同步生效?

共有2个答案

姜振濂
2023-08-06

这是一个典型的错误。

const formData = ref<any>(props.modelValue);

props.modelValue 是一个值,而不是 Ref,失去了响应性
上面这行代码的实际作用是以 setup 时 props.modelValue 的值初始化了一个新 Ref,之后就与 props 无关了。
因而 props 更新时,watch 得不到预期中的结果。

修改方案:

  1. 使用 toRefs 保持响应性

    const { modelValue } = toRefs(props)
  2. watch 整个 props

    watch(props, () => {    formData.value = props.modelValue})

友情提示:
你的代码中其它一些可能有问题的地方

  1. defineComponent 是一个编译期宏,不应当被 import
汪安然
2023-08-06
a = {a:1}b = ab = {b:2}

看上去 b 也不应该把 a 改变吧?下面这种应该是可以的

a = {a:1}b = ab.b = 2
 类似资料:
  • 本文向大家介绍vue同步父子组件和异步父子组件的生命周期顺序问题,包括了vue同步父子组件和异步父子组件的生命周期顺序问题的使用技巧和注意事项,需要的朋友参考一下 关于vue组件的引入方式有两种 一、 同步引入 例子: import Page from '@/components/page' 二、异步引入 例子:const Page = () => import('@/components/pag

  • 本文向大家介绍Vue父组件调用子组件事件方法,包括了Vue父组件调用子组件事件方法的使用技巧和注意事项,需要的朋友参考一下 Vue父组件向子组件传递事件/调用事件 不是传递数据(props)哦,适用于 Vue 2.0 方法一:子组件监听父组件发送的方法 方法二:父组件调用子组件方法 子组件: 父组件: 以上这篇Vue父组件调用子组件事件方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希

  • 父组件 子组件 为什么执行getSonData的时候,无法获取到子组件的data?sonRef.value.data只能在onMounted内使用吗?不能在父组件的方法里执行?

  • vue3中子组件向父组件传值 在传值的时候为什么只能在声明一个方法的时候传递,而不能在定义click的时候传递呢

  • vue3.0+tsx中子组件注册的两个emit方法,点击事件btnclick在父组件中正常,然后一个接收消息的事件rollback,没触发。 子组件: 接收socket消息是正常的,msg也能正常打印,就是父组件无法接收事件 父组件: 父组件没触发rollback方法,有没有大神帮忙看下怎么回事