Subscribe on changes!

父组件v-model对子组件template中只包含一个根节点input时出现的问题

avatar
Mar 3rd 2023

Vue version

3.2.45

Link to minimal reproduction

(https://sfc.vuejs.org/#eNp9kc1Og0AUhV/lZjZoUmai1Q2hpsaNb+BmNhVuW5T5ycyFagjv7oX+hKJxBXPO5Zzhfp149l62DYpM5LEIlSeISI1/0rYy3gWCDgJuoYdtcAYSHk0u1ivWtXtzoS6XJ1uqF2fGQJ4qnI0EJu5gNWTcJMmttrk61nBBTmh8vSHkd4B8fzc+AbqOv+n7UVRnNZ+WtalxJdYrLXhSC1BDmrrEiYU43jA1Gy8/orP8e90Qo09G1CKDURk0vu5w1mJP5GOmVGP9504Wzqg1eyo0liqDaenMeinv5cOjKqtIU11iNOl7cIeIgRu1WEzCFYsthjSgLTFg+LdsNntVOPN+lQ6dvLeeF3Dm8AfYGkcq7mAZTMKgJkzmVPhcWd8Q0LdH3jfhF/HCrwBwkBYzAv0PebfOxQ==)

Steps to reproduce

父组件

<script setup>
import { ref } from 'vue'
import HelloWorld3 from './components/HelloWorld3.vue'
const msg = ref('')
</script>

 <HelloWorld3 v-model="msg" />

子组件 HelloWorld3

<script setup>
const msgown = ''
</script>

<template>
<input type="text" v-model="msgown">
</template>

这里我知道,透传attr会让子组件的input标签上多一个modelvalue,但是为什么当我使用子组件键入内容的时候msgown和msg的值都会同步更新

What is expected?

什么当我使用子组件键入内容的时候msgown和msg的值都会同步更新?

What is actually happening?

why is this

System Info

Any additional comments?

avatar
Mar 3rd 2023
avatar
Mar 3rd 2023

@baiwusanyu-c thank you 谢谢你 我第一次用issue 不会贴代码链接。I will not post code link the first time I mention errors. Thank you for your help

avatar
Mar 3rd 2023

If the component does not define props, then all the properties on the template will be inherited by the elements rendered by the component, including the compiled attribute onUpdate:modelValue of v-model, which makes there are two onUpdate:modelValue events on the input element, I am not sure if this is a bug, but onUpdate:modelValue is a reserved field in vue, I think it should not be directly inherited by child elements

avatar
Mar 3rd 2023

you should add inheritAttrs: false to the child component. Because you did not define modelValue as props in the child component.

avatar
Mar 3rd 2023

Yes, the problem went away when I added props

avatar
Mar 5th 2023

I closed the pr because I thought it over and thought it was expected

  1. InheritAttrs: false is not set, so some attributes will be inherited by subcomponents to dom by default
  2. From the source code pointed out by @RicardoErii, it can be seen that the corresponding props need to be explicitly set in the component, and the component will be considered as requiring the component to process the relevant logic of onUpdate:xxx by itself, otherwise it will be inherited to the subcomponent dom on
avatar
Mar 6th 2023

@baiwusanyu-c I SEE,I don't think anyone will ever use it like I do ,lol

avatar
Mar 6th 2023

@baiwusanyu-c But I still have a question,this disappears when I use msgown in the child component,this issue arises again when I remove the use of msgown from the child component template,Look at this example: https://sfc.vuejs.org/#eNqVkU1OwzAQha8y8iYgNbZKWVUuKmLDDdh4U5ppG4h/ZE9aUJS7M05L1QaBxCrOvJn37Pk68RiC3Lco5kKndawDQUJqw4NxtQ0+EnQQcQM9bKK3UHBrcZaesWn8i49NNTvJUj15Oxhy19q7RGDTFhbZ46Yobo3T6hjDAZrQhmZFyGeAruPOvs9H0JfO+9L6CpuFEdxgBKg8qs6zYiKO1yntKsi35B2/pcs25iQkI+YwVHKN75b/jdgRhTRXqnXhfSvX3qolayq2jmqLZeXtcibv5P1UVXWiy7rEZMvX6A8JIycaMbkwV1zcYywjugojxj/DRr1XgSPtR2jO5HX1vIDvpf+PYoMDHX9wvwAaI9K76fA9weLBIy+tBkHXLrQE9BmQYRF+ENO6oscTRozw9V/l595i

When I use msgown in the child component, the parent's msg doesn't change。 Let's go back to when msgown isn't used in the child component template, notice that my msgown definition doesn't use ref,I'm using const msgown = ‘’; which is not gown in playground because you can't change the constant, but it's not gown in local vite created projects.,I need to replace it with let(这个在vite项目中是不会报错的,只会在playground中报错,vite项目中可正常使用const),The parent component's msg and the child component's msgown constant still change simultaneously,So there's something weird about it, and I wonder if that's how vue was designed。

It was tested locally by me,The v-model directive can be used with ordinary variables(not ref or reactive). The difference is that it is not responsive, but the data does change. The v-model variable declared with const does not change the data(No errors are reported in vite); it retains its original value; the let variable changes the data,I tested it with settimeout here。

summarize: When the properties bound to the v-model in the component are used in the child component template, the parent component's v-model does not have the same problems as in my topic.

我有个问题: 当我在子组件的template模板中 通过h1标签中使用msgown时, 这个问题就消失了, 不再出现父组件中msg也改变的问题,当我删掉h1标签中使用msgown时,这个问题就又出现了,这是什么原因呢? 这里的msgown我用的是普通变量而非ref或者reactive对象, 用ref对象也会产生一样的效果就是h1标签中使用msgown时, 这个问题就消失了,删掉又出现了。

另外使用vite开发项目时,发现使用const 声明的普通常量(非ref) v-model时绑定到input时,修改input不像playground会报错说常量无法修改,而是正常使用,只不过值不会同步给常量,常量的值还是初始值。 但是查看vue devtools发现值变了,通过settimeout打印值还是初始值。

用let声明的话就没问题。

avatar
Mar 7th 2023

我有个问题: 当我在子组件的template模板中 通过h1标签中使用msgown时, 这个问题就消失了, 不再出现父组件中msg也改变的问题,当我删掉h1标签中使用msgown时,这个问题就又出现了,这是什么原因呢?

如果子组件只有一个跟节点且在没有设置 inheritAttrs: false 的情况下,传递给子组件的属性会自动应用到这个根节点上。

avatar
Mar 7th 2023

如果子组件只有一个跟节点且在没有设置 inheritAttrs: false 的情况下,传递给子组件的属性会自动应用到这个根节点上。 ok thanks