vue3,监听不到子组件props的变化?

首先有个父组件

<template>
  <net-setting
     :ip="systemInfo.ip"
     :netmode="systemInfo.netmode"
     @update="handleUpdate"
  />
</template>

<script setup>

let systemInfo = reactive({
   netmode: 1,
   ip: ""
})

const handleUpdate = (params: { name: string; value: any }) => {
   systemInfo[params.name] = params.value
   console.log('systemInfo',systemInfo) // 这里打印出来是有变化的
}
</script>

这是我的子组件

<template>
    <s-form :label-col="2">
            <s-form-item label="网络模式">
               <s-select
                  :value="netmode"
                  name="netmode"
                  @update="handleUpdate"
               >
                  <option :value="0">Static</option>
                  <option :value="1">DHCP</option>
               </s-select>
            </s-form-item>
            <s-form-item label="IP地址">
               <s-input
                  name="ip"
                  :value="ip"
                  @update="handleUpdate"
                  :disabled="disabled"
               />
            </s-form-item>
         </s-form>
</template>

<script setup>
// + 定义属性
interface Props{
    netmode:number
    ip:string,
}
const props = defineProps<Props>()


const emits = defineEmits(["update"])
const handleUpdate = (params) => {
   emits("update", params)
}

// 问题来了,当我改变网络模式的时候,父组件的systemInfo是有变化的,
// 但是在子组件这里的disabled却监听不到变化,应该怎么调整呢?
const disabled = computed(() => Number(props.netmode) === 0)

// 也没有打印
watch(props, (nweProps) => {
   console.log("nweProps", nweProps)
})
</script>

解决

研究了半天发现问题了,父组件初始化的时候我还对数据进行了赋值,如下:

const refreshSysInfo = () => {
   getSysInfo().then((data) => {
      systemInfo = data
   })
}

导致数据由原来的代理对象变成了普通对象。
后面改成了这样子就解决了(打扰了,是我基础不好,谢谢各位大佬)

const state = reactive({
   systemInfo: {
      netmode: 1,
      ip: "",
   }
})

const refreshSysInfo = () => {
   getSysInfo().then((data) => {
      state.systemInfo = data
   })
}
阅读 9.9k
2 个回答

首先指出一个问题,就是你没有defineProps,没有给出props的元素有哪些。
其次就是你用的组件,我没看出来是啥,我用原生的给你表示一下:

<template>
  <form :label-col="2">
    <form-item label="网络模式">
      <select
        :value="netmode"
        name="netmode"
        @change="handleUpdate"
      >
        <option :value="0">
          Static
        </option>
        <option :value="1">
          DHCP
        </option>
      </select>
    </form-item>
    <form-item label="IP地址">
      <input
        name="ip"
        :value="ip"
        :disabled="disabled"
        @update="handleUpdate"
      >
    </form-item>
  </form>
</template>

<script lang="ts" setup>
import { computed, watch } from 'vue'

const props = defineProps({
  netmode: {
    type: Number,
    required: true
  },
  ip: {
    type: String,
    required: true
  }
})
const emits = defineEmits(['update'])
const handleUpdate = (params: Event) => {
  // 我用的原生change事件,这里是Event,所以我自己拼凑了一下参数结构。你用的ui组件如果update时候,就是这个{name: xxx, value: xxx} 的话就直接传 `emits('update', params)`, 否则你传参就是错的。父组件的处理就不会正确。
  emits('update', { name: 'netmode', value: (params.target as any).value })
}

// 问题来了,当我改变网络模式的时候,父组件的systemInfo是有变化的,
// 但是在子组件这里的disabled却监听不到变化,应该怎么调整呢?
const disabled = computed(() => Number(props.netmode) === 0)

watch(props, (nweProps: Props) => {
  console.log('[debug-ts] nweProps', nweProps)
})
</script>

然后并没有问题,一切运行正常。
image.png

所以你检查一下你的代码。

  1. 定义一下defineProps
  2. 确定一下 params 是否是父组件的入参结构
  3. 你自行封装的那个select中update事件,逐步debug看看。

子组件根本没接收父组件的props啊,用defineProps来声明一下吧。你直接用props是拿到的全局变量props。props.netmode可能直接报错Uncaught ReferenceError了吧

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题