Vue2 和 Vue3 中的 v-model 的区别#记录

vue3对v-model的语法进行了改动。
vue2 中有两种方式实现数据的双向绑定(组件与外部数据的双向绑定),一种是使用v-model,另一种是使用v-bind.sync修饰符。

vue2中的v-model,主要是进行value属性的绑定和input事件的派发。

<ChildComponent v-model="pageTitle" />

// 等价于
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />
//子组件
this.$emit('update:title', newValue)

//父组件
<ChildComponent :title.sync="pageTitle" />

//等价于
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

Vue3.x自定义组件实现v-model

1.子组件的props和事件,需要和v-model冒号后的绑定值相对应,例如若绑定值为v-model:text,则子组件中

props应为:props:[text] ,事件应为: update:text

2.vue3.x,删除了vue2.x中的model选项,并可以设置多个v-model

//父组件
<template>
  <div>
		<!-- v-model后不写值,默认就是modelValue -->
    <Child 
      v-model="message1"
      v-model:text="message2" 
    />
    <div>绑定的值1:{{message1}}</div>
    <div>绑定的值2:{{message2}}</div>
  </div>
</template>

//子组件
<template>
  <div>
    <!-- 3.x默认值改为了update:modelValue-->
    <input 
      type="text" 
      :value="modelValue" 
      @input="$emit('update:modelValue', $event.target.value)"
    >
    <input 
      type="text" 
      :value="text" 
      @input="$emit('update:text', $event.target.value)"
    >
  </div>
</template>
<script>
export default {
  // 3.x默认值改为了modelValue
  props:['modelValue','text']
}
</script>

vue3可以自定义 v-model 修饰符

在 Vue2 中的 v-model 上,我们用过 .trim、.lazy 和 .number这三个内置修饰符,而 Vue3 则在这个基础上增加了自定义修饰符。

<ChildComponent v-model.capitalize="name"></ChildComponent>
<!-- ChildComponent 组件 -->
 
<template>
  <div>
    <input type="text" :value="modelValue" @input="emitValue" />
  </div>
</template>
 
<script>
export default {
  props: {
    modelValue: String,
    modelModifiers: {  // 自定义修饰符会默认传入这个 prop 中
      type: Object,
      default: () => ({}),
    },
  },
  mounted() {
    // 当组件 v-model 后面加上了自定义修饰符,组件内部会在 modelModifiers 上获取到修饰符状态
    console.log(this.modelModifiers);
  },
  methods: {
    emitValue(e) {
      let value = e.target.value;
      // 如果使用了自定义修饰符,即状态为 true,就处理值
      if (this.modelModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1);
      }
      // emit value
      this.$emit("update:modelValue", value);
    },
  },
};
</script>

如果是 v-model 带上了参数,同时使用了自定义修饰符,如下所示:

<ChildComponent  v-model:name.capitalize="nameValue"></ChildComponent >
<!-- ChildComponent  组件 -->
 
<template>
  <div>
    <input type="text" :value="name" @input="emitValue" />
  </div>
</template>
 
<script>
export default {
  props: {
    name: String,  // modelValue -> name
    nameModifiers: {  // modelModifiers -> nameModifiers
      type: Object,
      default: () => ({}),
    },
  },
  mounted() {
    console.log(this.nameModifiers);
  },
  methods: {
    emitValue(e) {
      let value = e.target.value;
 
      // 如果使用了自定义修饰符,就处理值
      if (this.nameModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1);
      }
      // emit value
      this.$emit("update:name", value);
    },
  },
};
</script>

  • 15
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值