Skip to content

defineModel() leaks internal props into props (defineProps()) #14148

@Fan-iX

Description

@Fan-iX

Vue version

3.5, 3.6

Link to minimal reproduction

https://play.vuejs.org/#eNp9Uc1OwzAMfpXIp00aAWnAYRpIgHYACTYBN4JQ6bytW5pEiTuKqr47TquWHabd8v3Y/uxUcOec3BcIE5iG1GeOREAq3K0yqTWBhPPWBXEjlrjKDC4iGnwoSBR8DjtPbpeoe89zRAMWp+dtR+7FgDB3OiFkJERVifn3FlOSO/wNg2bIUNR1LDowwggo8IxVtpbbYA2nrGK5gtTmLtPo544yzqBgIholaonW9uep4cgXOOr4dIPp7gi/DWXkFCw8BvR7VNBrlPg1UivP3l6w5Hcv8t6FZvcJ8RWD1UXM2NruC7Pk2Ae+Ju1j7qynzKzfw6wkNKFbKgaNzrrxK+Cvejix+n/csbxs6pSp+Ypfe/SxJx9wLK/lxVmi3SaRV1D/Abp4qpU=

Steps to reproduce

<script setup>
const props = defineProps(["a"])
const model = defineModel()
</script>

<template>
  {{ Object.keys(props) }}
</template>

see minimal reproduction

What is expected?

only prop keys defined by defineProps ("a") will be shown

What is actually happening?

extra prop keys ("modelValue", "modelModifiers") are shown

System Info

Any additional comments?

For actual case, I use defineOptions({ inheritAttrs: false }) and defineProps to separate bindings for wrapper and content components. e.g.

<script setup>
defineOptions({ inheritAttrs: false })
const { prop1, prop2, ...props } = defineProps(["prop1", "prop2", "class", "style"])
const model = defineModel()
</script>

<template>
  {{ Object.keys(props) }}
  <div v-bind="props">
    <my-component v-bind="$attrs"></my-component>
  </div>
</template>

I'll have to drop extra model keys ("modelvalue", "modelmodifiers") from the props object, otherwise it will render the wrapper element with extra attributes (<div class="my-class" modelvalue="[object Object]">)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions