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

Vue3多v-model自定义修饰符重复代码重构咨询

重构Vue3多v-model的重复修饰符处理代码

当然可以重构,以下是具体的实现方案,完全基于Vue官方多v-model的方式,不用拆分组件,同时彻底解决代码冗余问题:

<script lang="ts" setup>
const props = defineProps({
  firstName: String,
  lastName: String,
  firstNameModifiers: {
    default: () => ({})
  },
  lastNameModifiers: {
    default: () => ({})
  },
});
const emit = defineEmits(["update:firstName", "update:lastName"]);

// 通用修饰符处理函数:集中管理所有修饰符的逻辑
function applyModifiers(value: string, modifiers: Record<string, boolean>) {
  let processedValue = value;
  if (modifiers.capitalize) {
    processedValue = processedValue.charAt(0).toUpperCase() + processedValue.slice(1);
  }
  // 新增修饰符直接在这里加判断即可
  if (modifiers.toUppercase) {
    processedValue = processedValue.toUpperCase();
  }
  if (modifiers.toLowerCase) {
    processedValue = processedValue.toLowerCase();
  }
  return processedValue;
}

// 工厂函数:根据字段名生成对应的输入事件处理器
function createInputHandler(propName: keyof typeof props) {
  return (e: Event) => {
    const target = e.target as HTMLInputElement;
    // 自动匹配对应字段的修饰符
    const modifiers = props[`${propName}Modifiers` as keyof typeof props] as Record<string, boolean>;
    const processedValue = applyModifiers(target.value, modifiers);
    // 自动触发对应字段的update事件
    emit(`update:${propName}`, processedValue);
  };
}

// 生成各个字段的事件处理函数
const firstNameEmitValue = createInputHandler('firstName');
const lastNameEmitValue = createInputHandler('lastName');
</script>

<template>
  <input type="text" :value="firstName" @input="firstNameEmitValue" />
  <input type="text" :value="lastName" @input="lastNameEmitValue" />
</template>

重构思路说明

  • 集中管理修饰符逻辑:把所有修饰符的处理逻辑抽到applyModifiers函数中,后续新增任何修饰符(比如toUppercase、toLowerCase),只需要在这个函数里添加对应的处理代码,不用修改每个字段的事件函数。
  • 用工厂函数消除重复:通过createInputHandler工厂函数,根据传入的字段名自动生成事件处理器,自动匹配对应字段的修饰符和触发对应的update事件,彻底避免重复代码。
  • 简化props定义:原代码中修饰符的default写法冗余,简化为default: () => ({})即可,符合Vue的默认值规范。
  • 避免手动错误:工厂函数自动关联字段和对应的修饰符,解决了原代码中lastName误用firstNameModifiers的问题。

后续扩展优势

以后如果需要新增字段(比如middleName),只需要:

  1. 在defineProps中添加middleName和middleNameModifiers
  2. 在defineEmits中添加update:middleName
  3. 调用createInputHandler('middleName')生成事件函数
  4. 在模板中添加对应的input标签

新增修饰符只需要在applyModifiers函数里加一行判断逻辑,完全不用动其他代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:00:58