vue中分别在原生input输入框和组件输入框上运用v-model的注意点

vue中分别在原生input输入框和组件输入框上运用v-model的注意点

问题的发现

在写15届蓝桥杯模拟赛一的最后一题时,竟然被第一问难住了,我用input的双向绑定进行事件触发有问题吗?

题目是这样的,如下:

  • 父组件中的html代码

    <form-input id="nickname" v-model="formData.nickname" :show-message="errorMessage.nickname" :holder="`nickname`"></form-input>
    <form-input id="email" v-model="formData.email" :show-message="errorMessage.email" :holder="`email (8-20 characters)`"></form-input>
    
  • form-input组件里面的代码

    const FormInput = {
      template: `
      <div>
        <input class="form-input" :placeholder="holder" v-model="inputValue"  />
        <div v-if="showMessage" class="error-message">{{ showMessage }}</div>
      </div>
      `,
      props: {
        value: String, // v-model 绑定的值,这里取名为 inputValue
        showMessage: String, // 是否显示消息
        holder: String, // 输入框的占位符
      },
      setup(props, { emit }) {
        const inputValue = ref(props.value);
        const holder = ref(props.holder)
        //  TODO:目标 1 当输入框的值变化时,触发 input 事件更新父组件的 v-model 值
        watch(inputValue,(newValue,oldValue)=>{
          // console.log(newValue,oldValue);
          //这里如果有问题的话可以去看官网怎么解释v-model在组件上的
           //emit('input',newValue)//我当时想,为什么不行????????
          emit('update:modelValue',newValue)
        })
        //  TODO:end
    
        return {
          inputValue,
          holder
        };
      },
    };
    

问题的解决

后面实在觉得这个问题太离谱了,很纳闷,就去看了一下官网文档。之前vue2的文档是没有说明输入组件上使用v-model的,我当时觉得反正v-model在vue2这里就是一个value值的绑定,一个input事件==>v-model。没想到看vue3的文档,变化居然这么大!!!学到了~

对比vue2和vue3,在原生的input输入框上进行数据的双向绑定,他们的原理还是一样的,只是vue3新添加了在输入组件上v-model这个规范约束。下面让我来慢慢陈列~

原生input上使用v-model

首先,原生是这样用的:

<input v-model="data" />

其实在vue2/3的背后,上面的这个代码等价于下面这行代码:

<input
  :value="data"
  @input="data = $event.target.value"
/>

其实看到这里,应该有考虑过我还能用emit事件触发吗?不会啦,它只是对于它自己本身进行操作的,只是我们今天遇到的主要问题是输入组件上绑定的v-model,我们怎么通过组件里面的代码进行事件的触发。

在一个输入组件上使用v-model

先看组件上:

<CustomInput v-model="searchText" />

在背后实际上被展开成:

<CustomInput
  :model-value="searchText"
  @update:model-value="newValue => searchText = newValue"
/>

看官网文档介绍的重点!!!

要让这个例子实际工作起来,<CustomInput> 组件内部需要做两件事:

  1. 将内部原生 <input> 元素的 value attribute 绑定到 modelValue prop
  2. 当原生的 input 事件触发时,触发一个携带了新值的 update:modelValue 自定义事

再看看官网给的例子,就知道父子组件关于数据传输的真实情况了。实际上在做这题也是这样的,我们在组件中触发父组件中的输入组件的update:modelValue事件,顺便将原生输入框的变化值带过去。

<!-- CustomInput.vue -->
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

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

总结

还是得多去看文档吧!我写的只是我个人遇到的问题,关于v-model,vue3官方文档上还写了很多,自己想对这个有更多的了解,就请跳转官网吧!vue3文档中关于v-model的解释

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值