vue2和vue3組件v-model區(qū)別詳析
前言
單向數(shù)據(jù)流,父組件傳給子組件的數(shù)據(jù),子組件只能展示,不能修改,如果需要修改則需要emit事件讓父組件修改
有些時(shí)候,一些組件并不是通過(guò)input來(lái)進(jìn)行觸發(fā)事件。也就是說(shuō)value和input事件在大多數(shù)情況下能夠適用,但是存在value另有含義,或者不能使用input觸發(fā)的情況,這時(shí)候我們就不能使用v-model進(jìn)行簡(jiǎn)寫(xiě)了。
就比如說(shuō)選擇框,綁定的值是checked而不是value,接收事件不是input而是change。
為了解決這個(gè)問(wèn)題,尤雨溪在Vue2.2中,引入了model組件選項(xiàng)
,也即是說(shuō)你可以通過(guò)model來(lái)指定v-model綁定的值和屬性。
vue2組件v-model.
1、vue2中雙向綁定單個(gè)值(input)
<ChildComponent v-model = "title /> // 實(shí)際上是下面這種的簡(jiǎn)寫(xiě) <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"/> // 等價(jià) // <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相當(dāng)于用value傳遞了綁定值,用@input事件接收了子組件通過(guò)$emit傳遞的參數(shù)。
2、vue2中雙向綁定單個(gè)值(非input 設(shè)置model選項(xiàng))
通過(guò)上面的代碼,我們可以看到通過(guò)設(shè)置model選項(xiàng),我們就可以直接使用指定的屬性和事件,而不需要必須使用value和input了,value和input可以另外它用了。
3、vue2中雙向綁定多個(gè)值
但是這樣的話(huà)寫(xiě)起來(lái)很麻煩,而且v-model只能綁定一個(gè)值,這樣的話(huà)我的組件封裝不是只能改變一個(gè)值了,這樣好像也不符合開(kāi)發(fā)。
所以,再看下vue2文檔
.sync
和v-model
類(lèi)似,就是傳遞值和接收事件的簡(jiǎn)寫(xiě)。這樣的話(huà)我們就可以不用寫(xiě)model了。直接告訴我更新哪個(gè)值。
注意哦
子組件:
父組件:
所以,綁定多個(gè)值,我們可以傳遞一個(gè)obj下去,使用v-bind.sync=‘obj’
再看一個(gè)例子:
子組件:
<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相當(dāng)于: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>
是不是學(xué)著有點(diǎn)懵B,又是.sync 又是update:title的,vue3又刪除了.sync,看下vue3的吧,更好用
vue3組件v-model
通過(guò)上面知道vue2.x中既然v-model的主要原因是由于value和input事件可能另有它用,那么我們可不可以直接使用另外的屬性和方法,而不需要去通過(guò)model進(jìn)行定義。
vue3中就實(shí)現(xiàn)了這個(gè)功能,v-model綁定的不再是value,而是modelValue,接收的方法也不再是input,而是update:modelValue。使用方法如下:
1、vue3中雙向綁定單個(gè)值
v-model 在原生元素上的用法:
<input v-model="searchText" />
其實(shí)等價(jià)于下面這段:
<input :value="searchText" @input="searchText = $event.target.value"/>
而當(dāng)使用在一個(gè)組件上時(shí),v-model 會(huì)被展開(kāi)為如下的形式:
<CustomInput :modelValue="searchText" @update:modelValue="newValue => searchText = newValue" />
在子組件中寫(xiě)法是:
export default defineComponent({ name:"CustomInput", props:{ modelValue:String, // v-model綁定的屬性值 }, setup(props, {emit}) { const updateValue = (e: KeyboardEvent) => { emit("update:modelValue",targetValue); // 傳遞的方法 } } }
也就是說(shuō)vue3中,value改成了modelValue,input方法了改成update:modelValue
再看個(gè)例子
子組件:
<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中雙向綁定多個(gè)值
例子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參數(shù)
默認(rèn)情況下,v-model 在組件上都是使用 modelValue 作為 prop,并以 update:modelValue 作為對(duì)應(yīng)的事件。我們可以通過(guò)給 v-model 指定一個(gè)參數(shù)來(lái)更改這些名字:
<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>
也就是說(shuō),我們最終的使用方法是:
<ChildComponent v-model:title="title" /> // 或者 <ChildComponent :title="title" @update:title = "title = $event" />
再看個(gè)例子
父組件:
<template> <div id="app"> <h1>Vue3中v-model的變化</h1> <input type="text" v-model="name"/> <p>{{ name }}</p> <!-- Vue2的寫(xiě)法 --> <!-- v-model實(shí)際上就是:value和@input的語(yǔ)法糖 --> <!-- 雙向綁定多個(gè)屬性的時(shí)候可以使用.sync關(guān)鍵字 --> <CustomInput v-model="age" :name.sync="name"/> <!-- Vue3的寫(xiě)法 --> <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的寫(xiě)法 --> <input type="text" :value="value" @input="onInput" /> <input type="text" :value="name" @input="onNameInput" /> <!-- Vue3的寫(xiě)法 --> <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的寫(xiě)法 props: ["value", "name"], // Vue3的寫(xiě)法,直接接收綁定的參數(shù) props: ["age", "name"], // Vue3雙向綁定單個(gè)屬性時(shí),可以使用modelValue來(lái)接收參數(shù)并更新,對(duì)應(yīng)的觸發(fā)事件為update:modelValue props: ["modelValue"], methods: { onInput(e) { // Vue2的寫(xiě)法 // 觸發(fā)的事件只能是input // e.target.value是字符串需要轉(zhuǎn)換成數(shù)字 this.$emit("input", parseInt(e.target.value)); // Vue3的寫(xiě)法 this.$emit("update:age", e.target.value); }, onNameInput(e) { // 只能用update this.$emit("update:name", e.target.value); }, }, } </script>
好了,到目前為止,我們介紹了vue2中的v-model的使用以及問(wèn)題,vue3中v-model的新的使用語(yǔ)法。趕快去體驗(yàn)vue3的使用吧。
總結(jié)
到此這篇關(guān)于vue2和vue3組件v-model區(qū)別的文章就介紹到這了,更多相關(guān)vue組件v-model區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在Vue2中v-model和.sync區(qū)別解析
- Vue2子組件綁定 v-model,實(shí)現(xiàn)父子組件通信方式
- vue2中如何自定義組件的v-model
- Vue v-model相關(guān)知識(shí)總結(jié)
- vue2 v-model/v-text 中使用過(guò)濾器的方法示例
- vue 2.0組件與v-model詳解
- Vue2.0利用 v-model 實(shí)現(xiàn)組件props雙向綁定的優(yōu)美解決方案
- vue2 如何實(shí)現(xiàn)div contenteditable=“true”(類(lèi)似于v-model)的效果
- vue2與vue3雙向數(shù)據(jù)綁定的區(qū)別說(shuō)明
- vue 2 實(shí)現(xiàn)自定義組件一到多個(gè)v-model雙向數(shù)據(jù)綁定的方法(最新推薦)
相關(guān)文章
Nuxt.js SSR與權(quán)限驗(yàn)證的實(shí)現(xiàn)
這篇文章主要介紹了Nuxt.js SSR與權(quán)限驗(yàn)證的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11vue+element ui el-tooltip動(dòng)態(tài)顯示隱藏問(wèn)題
這篇文章主要介紹了vue+element ui el-tooltip動(dòng)態(tài)顯示隱藏問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue后端傳文件流轉(zhuǎn)化成blob對(duì)象,前端點(diǎn)擊下載返回undefined問(wèn)題
這篇文章主要介紹了vue后端傳文件流轉(zhuǎn)化成blob對(duì)象,前端點(diǎn)擊下載返回undefined問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Vue3?封裝?Element?Plus?Menu?無(wú)限級(jí)菜單組件功能的詳細(xì)代碼
本文分別使用?SFC(模板方式)和?tsx?方式對(duì)?Element?Plus?*el-menu*?組件進(jìn)行二次封裝,實(shí)現(xiàn)配置化的菜單,有了配置化的菜單,后續(xù)便可以根據(jù)路由動(dòng)態(tài)渲染菜單,對(duì)Vue3?無(wú)限級(jí)菜單組件相關(guān)知識(shí)感興趣的朋友一起看看吧2022-09-09Vue實(shí)現(xiàn)動(dòng)態(tài)顯示textarea剩余字?jǐn)?shù)
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)動(dòng)態(tài)顯示textarea剩余文字?jǐn)?shù)量,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05淺談el-table中使用虛擬列表對(duì)對(duì)表格進(jìn)行優(yōu)化
我們會(huì)經(jīng)常使用表格,如果數(shù)據(jù)量大就直接可以分頁(yè),如果多條可能會(huì)影響表格的卡頓,那么應(yīng)該如何進(jìn)行優(yōu)化,感興趣的可以了解一下2021-08-08