You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue组件v-model修饰符capitalize返回空的原因及解决方法

问题:Vue自定义v-model修饰符无法获取,modelModifiers返回空对象

我在Vue组件中使用带修饰符的自定义v-model:

<hello-world v-model="refInputModel"
             v-model:firstName.capitalize="refInputModel2"/>

运行时,HelloWorld组件的onUpdated钩子中执行console.log("modelModifiers:",props.modelModifiers);返回空对象,但期望得到{ capitalize: true }。

App组件代码

<template>
  <img alt="Vue logo" src="./assets/logo.png">
    <div>
      <button @click="counterFunc">methodHandler</button>
      
      <hello-world v-model="refInputModel"
               v-model:firstName.capitalize="refInputModel2"/>
    </div>
</template>

<script> 
export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<script setup> 
import HelloWorld from './components/HelloWorld.vue'
import {ref,defineProps} from 'vue' 

const props = defineProps(['inputModel_','inputModel_2'])
let refInputModel = ref(props.inputModel_)
let refInputModel2 = ref(props.inputModel_2)

const counterFunc = ()=> {
  refInputModel.value = "changed"
  refInputModel2.value = "changed2"
}
</script>

HelloWorld组件代码(原代码)

<template>
  <div class="hello">
  <input :value="modelValue"
         @input="$emit('update:modelValue', $event.target.value)"/>
   
  <input :value="firstName"
         @input="$emit('update:firstName', $event.target.value)"/>
  </div>
  
</template>

<script>
export default {
  name: 'HelloWorld',
}
</script>

<script setup> 
import { onUpdated,defineProps,defineEmits} from 'vue'

const props = defineProps({
  modelValue:String,
  firstName:String,
  modelModifiers: { default: () => ({}) }
})
defineEmits(['update:modelValue', 'update:firstName'])

onUpdated(()=>{
  console.log("HelloWorld.onUpdated");
  console.log("modelValue:",props.modelValue);
  console.log("modefirstNamelValue:",props.firstName);
  console.log("modelModifiers:",props.modelModifiers);
})
</script>

原因分析

你把修饰符加在了**带参数的v-model(v-model:firstName)**上,但组件中声明的是默认v-model对应的modelModifiers。Vue的规则是:

  • 不带参数的默认v-model,修饰符对应prop为modelModifiers
  • 带参数的v-model(如v-model:xxx),修饰符对应prop为xxxModifiers

你的修饰符是给firstName这个v-model参数加的,所以对应的prop应该是firstNameModifiers,而非modelModifiers,这就是原代码中modelModifiers为空的原因。

修正方法

修改HelloWorld组件的defineProps,添加firstNameModifiers,并在钩子中打印该prop:

<script setup> 
import { onUpdated,defineProps,defineEmits} from 'vue'

const props = defineProps({
  modelValue: String,
  firstName: String,
  modelModifiers: { default: () => ({}) },
  // 添加对应参数的修饰符prop
  firstNameModifiers: { default: () => ({}) }
})
defineEmits(['update:modelValue', 'update:firstName'])

onUpdated(()=>{
  console.log("HelloWorld.onUpdated");
  console.log("modelValue:",props.modelValue);
  console.log("firstName:",props.firstName);
  console.log("modelModifiers:",props.modelModifiers);
  // 打印对应参数的修饰符
  console.log("firstNameModifiers:",props.firstNameModifiers); // 此时会输出 { capitalize: true }
})
</script>

如果需要在组件内应用这个修饰符的逻辑,比如在触发update事件时将输入值首字母大写,可以修改input的事件处理:

<template>
  <div class="hello">
  <input :value="modelValue"
         @input="$emit('update:modelValue', $event.target.value)"/>
   
  <input :value="firstName"
         @input="handleFirstNameInput"/>
  </div>
  
</template>

<script setup> 
import { onUpdated,defineProps,defineEmits} from 'vue'

const props = defineProps({
  modelValue: String,
  firstName: String,
  modelModifiers: { default: () => ({}) },
  firstNameModifiers: { default: () => ({}) }
})
const emit = defineEmits(['update:modelValue', 'update:firstName'])

const handleFirstNameInput = (e) => {
  let value = e.target.value
  // 如果有capitalize修饰符,执行首字母大写逻辑
  if (props.firstNameModifiers.capitalize) {
    value = value.charAt(0).toUpperCase() + value.slice(1)
  }
  emit('update:firstName', value)
}

onUpdated(()=>{
  console.log("firstNameModifiers:",props.firstNameModifiers);
})
</script>

内容的提问来源于stack exchange,提问作者Amrmsmb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:28:28