Vue 3 中的 v-model:实现组件间的双向绑定

举报
周杰伦本人 发表于 2025/06/28 19:24:14 2025/06/28
【摘要】 Vue 3 中的 v-model:实现组件间的双向绑定1. v-model 的作用v-model 是 Vue 中实现双向绑定的指令,允许你在表单输入框、选择框等元素上实现数据的双向绑定。在 Vue 3 中,v-model 的使用方式和底层实现与 Vue 2 有所不同。2. v-model 的底层原理在 Vue 3 中,v-model 的底层实现基于两个核心部分:modelValue:用于传递...


    Vue 3 中的 v-model:实现组件间的双向绑定

    1. v-model 的作用

    v-model 是 Vue 中实现双向绑定的指令,允许你在表单输入框、选择框等元素上实现数据的双向绑定。在 Vue 3 中,v-model 的使用方式和底层实现与 Vue 2 有所不同。

    2. v-model 的底层原理

    在 Vue 3 中,v-model 的底层实现基于两个核心部分:

    1. modelValue:用于传递数据。

    2. update:modelValue:用于更新数据。

    HTML 元素上的 v-model

    对于原生 HTML 元素(如 <input>),v-model 的本质是:

    • 绑定 value 属性:将数据传递到输入框。

    • 监听 input 事件:更新数据。

    自定义组件上的 v-model

    对于自定义组件,v-model 的实现需要手动处理:

    • 接收 modelValue:通过 props 接收父组件传递的数据。

    • 触发 update:modelValue:通过 $emit 更新数据。

    3. 示例代码

    HTML 元素上的 v-model


    <template>
      <div>
        <input v-model="username" />
        <p>用户名:{{ username }}</p>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue';
    
    const username = ref('张三');
    </script>
    

    自定义组件上的 v-model


    <!-- 父组件 -->
    <template>
      <div>
        <AtSiliconInput v-model="username" />
        <p>用户名:{{ username }}</p>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue';
    import AtSiliconInput from './AtSiliconInput.vue';
    
    const username = ref('张三');
    </script>
    


    <!-- AtSiliconInput.vue -->
    <template>
      <input
        :value="modelValue"
        @input="$emit('update:modelValue', $event.target.value)"
      />
    </template>
    
    <script setup>
    import { defineProps, defineEmits } from 'vue';
    
    const props = defineProps({
      modelValue: String
    });
    
    const emit = defineEmits(['update:modelValue']);
    </script>
    

    在某些情况下,你可能希望自定义 v-model 绑定的字段名称,而不是默认的 modelValue。Vue 3 允许你通过在 v-model 后面添加字段名称来实现这一点。


    <template>
      <div>
        <AtSiliconInput v-model:name="username" v-model:password="password" />
        <p>用户名:{{ username }}</p>
        <p>密码:{{ password }}</p>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue';
    import AtSiliconInput from './AtSiliconInput.vue';
    
    const username = ref('张三');
    const password = ref('123456');
    </script>
    

    子组件(AtSiliconInput.vue)


    <template>
      <div>
        <input
          :value="name"
          @input="$emit('update:name', $event.target.value)"
        />
        <input
          type="password"
          :value="password"
          @input="$emit('update:password', $event.target.value)"
        />
      </div>
    </template>
    
    <script setup>
    import { defineProps, defineEmits } from 'vue';
    
    const props = defineProps({
      name: String,
      password: String
    });
    
    const emit = defineEmits(['update:name', 'update:password']);
    </script>
    

    通过这上面的代码也可以看出来,在 Vue 3 中,你可以在一个组件上使用多个 v-model,每个 v-model 可以绑定不同的字段。这使得组件可以同时管理多个数据源。

    4. 注意事项

    1 v-model 的默认修饰符

    • 在 Vue 3 中,v-model 的默认修饰符是 modelValueupdate:modelValue

    • 在 Vue 2 中,v-model 的默认修饰符是 valueinput

    2 自定义组件的 v-model

    • 自定义组件需要手动处理 modelValueupdate:modelValue

    • 确保在子组件中正确绑定 value 属性,并触发 update:modelValue 事件。

    3 类型检查

    • 使用 TypeScript 时,确保正确处理事件对象的类型,避免类型错误。

    4  字段名称的自定义

    • 你可以通过在 v-model 后面添加字段名称来自定义绑定字段,例如 v-model:name

    • 子组件需要通过 props 接收对应的字段,并通过 update:字段名 事件更新数据。

    5 多个 v-model 的使用

    • 在一个组件上可以使用多个 v-model,每个 v-model 绑定不同的字段。

    • 子组件需要为每个字段定义 props 和对应的更新事件。

    5. 总结

    v-model 是 Vue 中实现双向绑定的重要指令,它在 Vue 3 中的实现方式与 Vue 2 有所不同。对于自定义组件,需要手动处理 modelValueupdate:modelValue,以实现双向绑定。通过自定义字段名称,你可以在一个组件上使用多个 v-model,从而实现更复杂的双向绑定。我们在使用v-model的时候一定要注意是在HTML 元素:直接使用 v-model 即可,自定义组件:确保正确接收 modelValue,并通过 update:modelValue 更新数据。UI 组件库:理解底层实现原理,以便更好地使用和自定义组件。 多个 v-model:在需要管理多个数据源时,可以使用多个 v-model

    【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
    • 点赞
    • 收藏
    • 关注作者

    评论(0

    0/1000
    抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。