vue2和vue3组件v-model区别详析

 更新时间:2023年06月20日 09:48:43   作者:老电影故事  
v-model通常用于input的双向数据绑定,它并不会向子组件传递数据,下面这篇文章主要给大家介绍了关于vue2和vue3组件v-model区别的相关资料,需要的朋友可以参考下

前言

单向数据流,父组件传给子组件的数据,子组件只能展示,不能修改,如果需要修改则需要emit事件让父组件修改

有些时候,一些组件并不是通过input来进行触发事件。也就是说value和input事件在大多数情况下能够适用,但是存在value另有含义,或者不能使用input触发的情况,这时候我们就不能使用v-model进行简写了。

就比如说选择框,绑定的值是checked而不是value,接收事件不是input而是change。

为了解决这个问题,尤雨溪在Vue2.2中,引入了model组件选项,也即是说你可以通过model来指定v-model绑定的值和属性。

vue2组件v-model.

1、vue2中双向绑定单个值(input)

<ChildComponent v-model = "title />
// 实际上是下面这种的简写
<ChildComponent :value = "title"  @input = "title = $event" />

子组件:

<template>
  <input type="text" :value="value" @input = "inputChange">
</template>

<script>
export default {
  name: "CustomInput",
  props: ['value'],
  methods: {
    inputChange(e) {
      this.$emit('input', e.target.value)
    }
  }
}
</script>

父组件:

<template>
  <div class="test">
    <span>自定义组件:</span>
    <CustomInput v-model="age"/> 
    // 等价
    // <CustomInput :value="age" @input="changeAge"/>
    {{age}}
  </div>
</template>
<script>
import CustomInput from "./CustomInput";
export default {
  name: "Test",
  components: {
    CustomInput,
  },
  data() {
    return {
      age: 20,
    }
  },
  methods: {
    changeAge(value) {
      this.age = Number(value);
    }
  }
}
</script>

在vue2中,v-model相当于用value传递了绑定值,用@input事件接收了子组件通过$emit传递的参数。

2、vue2中双向绑定单个值(非input 设置model选项)

通过上面的代码,我们可以看到通过设置model选项,我们就可以直接使用指定的属性和事件,而不需要必须使用value和input了,value和input可以另外它用了。

3、vue2中双向绑定多个值

但是这样的话写起来很麻烦,而且v-model只能绑定一个值,这样的话我的组件封装不是只能改变一个值了,这样好像也不符合开发。

所以,再看下vue2文档

.syncv-model类似,就是传递值和接收事件的简写。这样的话我们就可以不用写model了。直接告诉我更新哪个值。

注意哦

子组件:

父组件:

所以,绑定多个值,我们可以传递一个obj下去,使用v-bind.sync=‘obj’

再看一个例子:

子组件:

<template>
  <div>
    <input :value="value" @input = "inputChange">
    <input :value="name" @input = "inputNameChange">
  </div>
</template>
<script>
export default {
  name: "CustomInput",
  props: ['value', 'name'],
  methods: {
    inputChange(e) {
      this.$emit('input', e.target.value)
    },
    inputNameChange(e) {
      this.$emit('update:name', e.target.value);
    }
  }
}
</script>

父组件:

<template>
  <div class="test">
    <span>自定义组件:</span>
    <CustomInput v-model="age" :name.sync="name"/> 
    // 此处v-model相当于:value="age" @input="age=$event"
  </div>
</template>
<script>
import CustomInput from "./CustomInput";
export default {
  name: "Test",
  components: {
    CustomInput,
  },
  data() {
    return {
      name: 'yn',
      age: 20,
    }
  },
  methods: {
    // changeAge(value) {
    //   this.age = Number(value);
    // }
  }
}
</script>

是不是学着有点懵B,又是.sync 又是update:title的,vue3又删除了.sync,看下vue3的吧,更好用

vue3组件v-model

通过上面知道vue2.x中既然v-model的主要原因是由于value和input事件可能另有它用,那么我们可不可以直接使用另外的属性和方法,而不需要去通过model进行定义。

vue3中就实现了这个功能,v-model绑定的不再是value,而是modelValue,接收的方法也不再是input,而是update:modelValue。使用方法如下:

1、vue3中双向绑定单个值

v-model 在原生元素上的用法:

<input v-model="searchText" />

其实等价于下面这段:

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

而当使用在一个组件上时,v-model 会被展开为如下的形式:

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>

在子组件中写法是:

export default defineComponent({
    name:"CustomInput",
    props:{
        modelValue:String,   // v-model绑定的属性值
    },
    setup(props, {emit}) {
        const updateValue = (e: KeyboardEvent) => {
          emit("update:modelValue",targetValue);   // 传递的方法
        }
    }
}

也就是说vue3中,value改成了modelValue,input方法了改成update:modelValue

再看个例子

子组件:

<template>
  <div class='CustomInput'>
    <input :value="modelValue" @input = "inputChange">
  </div>
</template>
<script>
export default {
  name: 'CustomInput',
  props: {
    modelValue: String,
  },
  setup(props, {emit}) {
    function inputChange(e) {
      emit('update:modelValue', e.target.value)
    };
    return {
      inputChange,
    }
  }
};
</script>

父组件:

<template>
  <div class='test'>
  <CustomInput v-model="name"/>
    {{name}}
  </div>
</template>
<script>
import CustomInput from './CustomInput';
import { defineComponent, ref} from 'vue';
export default defineComponent({
  name: 'test',
  components: {
    CustomInput
  },
  setup() {
    const name = ref('zm');
    return {
      name
    }
  }
});
</script>

2、vue3中双向绑定多个值

例子1:

<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>
<script setup>
defineProps({
  firstName: String,
  lastName: String
})
defineEmits(['update:firstName', 'update:lastName'])
</script>
<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

例子2:

父组件:

<template>
  <div class='test'>
  <CustomInput v-model:name="name" v-model:age="age"/>
    {{name}} {{age}}
  </div>
</template>
<script>
import CustomInput from './CustomInput';
import { defineComponent, ref} from 'vue';
export default defineComponent({
  name: 'test',
  components: {
    CustomInput
  },
  setup() {
    const name = ref('zm');
    const age = ref(20);
    return {
      name,
      age
    }
  }
});

子组件:

<template>
  <div class='CustomInput'>
    <input :value="age" @input = "inputChange">
    <input :value="name" @input = "inputNameChange">
  </div>
</template>
<script>
export default {
  name: 'CustomInput',
  props: {
    name: String,
    age: Number,
  },
  setup(props, {emit}) {
    function inputChange(e) {
      emit('update:age', e.target.value)
    };
    function inputNameChange(e) {
      emit('update:name', e.target.value);
    }
    return {
      inputChange,
      inputNameChange,
    }
  }
};
</script>

3、v-model参数

默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字:

<MyComponent v-model:title="bookTitle" />

那么在子组件中,就可以使用title代替modelValue

<!-- MyComponent.vue -->
<script setup>
defineProps(['title'])
defineEmits(['update:title'])
</script>
<template>
  <input
    type="text"
    :value="title"
    @input="$emit('update:title', $event.target.value)"
  />
</template>

也就是说,我们最终的使用方法是:

<ChildComponent v-model:title="title"  />
// 或者
<ChildComponent :title="title" @update:title = "title = $event" />

再看个例子

父组件:

<template>
  <div id="app">
    <h1>Vue3中v-model的变化</h1>
    <input type="text" v-model="name"/>
    <p>{{ name }}</p>
    <!-- Vue2的写法 -->
    <!-- v-model实际上就是:value和@input的语法糖 -->
    <!-- 双向绑定多个属性的时候可以使用.sync关键字 -->
    <CustomInput v-model="age" :name.sync="name"/>
    <!-- Vue3的写法 -->
    <CustomInput v-model:age="age" v-model:name="name"/>
  </div>
</template>
<script>
import CustomInput from "../components/CustomInput.vue";
export default {
  name: "App",
  components: {
  	CustomInput
  },
	data() {
    return {
    	name: "你好",
      age: 20,
    }
  },
}
</script>

子组件:

<template>
  <div class="custom-input">
    <h1>自定义的input</h1>
    <!-- Vue2的写法 -->
    <input type="text" :value="value" @input="onInput" />
    <input type="text" :value="name" @input="onNameInput" />
    <!-- Vue3的写法 -->
    <input type="text" :value="age" @input="onInput" />
    <input type="text" :value="name" @input="onNameInput" />
  </div>
</template>
<script>
import CustomInput from "../components/CustomInput.vue";
export default {
  // Vue2的写法
  props: ["value", "name"],
  // Vue3的写法,直接接收绑定的参数
  props: ["age", "name"],
  // Vue3双向绑定单个属性时,可以使用modelValue来接收参数并更新,对应的触发事件为update:modelValue
  props: ["modelValue"],
  methods: {
  	onInput(e) {
      // Vue2的写法
      // 触发的事件只能是input
      // e.target.value是字符串需要转换成数字
    	this.$emit("input", parseInt(e.target.value));
      // Vue3的写法
      this.$emit("update:age", e.target.value);
    },
    onNameInput(e) {
      // 只能用update
    	this.$emit("update:name", e.target.value);
    },
  },
}
</script>

好了,到目前为止,我们介绍了vue2中的v-model的使用以及问题,vue3中v-model的新的使用语法。赶快去体验vue3的使用吧。

总结

到此这篇关于vue2和vue3组件v-model区别的文章就介绍到这了,更多相关vue组件v-model区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3 el-upload单张图片回显、编辑、删除功能实现

    vue3 el-upload单张图片回显、编辑、删除功能实现

    这篇文章主要介绍了vue3 el-upload单张图片回显、编辑、删除功能实现,图片回显时隐藏上传区域,鼠标悬浮显示遮罩层进行编辑、删除操作,删除图片后显示上传区域,本文通过实例代码分享实现方法,感兴趣的朋友一起看看吧
    2023-12-12
  • 解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题

    解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题

    这篇文章主要介绍了解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 详解vue文件中使用echarts.js的两种方式

    详解vue文件中使用echarts.js的两种方式

    这篇文章主要介绍了详解vue文件中使用echarts.js的两种方式,主要介绍了两种使用方式,一种是以组件的形式另一种直接引入,非常具有实用价值,需要的朋友可以参考下
    2018-10-10
  • Vue3中引入Pinia存储库使用示例详解

    Vue3中引入Pinia存储库使用示例详解

    这篇文章主要介绍了Vue3中引入Pinia存储库使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Vue循环组件加validate多表单验证的实例

    Vue循环组件加validate多表单验证的实例

    今天小编就为大家分享一篇Vue循环组件加validate多表单验证的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue使用canvas手写输入识别中文

    vue使用canvas手写输入识别中文

    这篇文章主要介绍了vue使用canvas手写输入识别中文,工作时遇到一些项目如:系统上的输入法使用不方便,客户要求做一个嵌入web网页的手写输入法。下面我们来看看文章得具体描述吧
    2021-11-11
  • vue el-input设置必填提示功能(单个与多个)

    vue el-input设置必填提示功能(单个与多个)

    有的功能需要设置必填项,当然也需要判断是不是添上了,下面这篇文章主要给大家介绍了关于vue el-input设置必填提示功能(单个与多个)的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • 从0搭建Vue3组件库之如何使用Vite打包组件库

    从0搭建Vue3组件库之如何使用Vite打包组件库

    这篇文章主要介绍了从0搭建Vue3组件库之如何使用Vite打包组件库,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • vuejs 单文件组件.vue 文件的使用

    vuejs 单文件组件.vue 文件的使用

    本篇文章主要介绍了vuejs 单文件组件.vue 文件的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • vue 页面卡死,点击无反应的问题及解决

    vue 页面卡死,点击无反应的问题及解决

    这篇文章主要介绍了vue 页面卡死,点击无反应的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10

最新评论