vue2和vue3組件v-model區(qū)別詳析
前言
單向數(shù)據(jù)流,父組件傳給子組件的數(shù)據(jù),子組件只能展示,不能修改,如果需要修改則需要emit事件讓父組件修改

有些時候,一些組件并不是通過input來進行觸發(fā)事件。也就是說value和input事件在大多數(shù)情況下能夠適用,但是存在value另有含義,或者不能使用input觸發(fā)的情況,這時候我們就不能使用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傳遞的參數(shù)。
2、vue2中雙向綁定單個值(非input 設置model選項)


通過上面的代碼,我們可以看到通過設置model選項,我們就可以直接使用指定的屬性和事件,而不需要必須使用value和input了,value和input可以另外它用了。
3、vue2中雙向綁定多個值
但是這樣的話寫起來很麻煩,而且v-model只能綁定一個值,這樣的話我的組件封裝不是只能改變一個值了,這樣好像也不符合開發(fā)。
所以,再看下vue2文檔

.sync和v-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中就實現(xiàn)了這個功能,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參數(shù)
默認情況下,v-model 在組件上都是使用 modelValue 作為 prop,并以 update:modelValue 作為對應的事件。我們可以通過給 v-model 指定一個參數(shù)來更改這些名字:
<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的寫法,直接接收綁定的參數(shù)
props: ["age", "name"],
// Vue3雙向綁定單個屬性時,可以使用modelValue來接收參數(shù)并更新,對應的觸發(fā)事件為update:modelValue
props: ["modelValue"],
methods: {
onInput(e) {
// Vue2的寫法
// 觸發(fā)的事件只能是input
// e.target.value是字符串需要轉換成數(shù)字
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區(qū)別的文章就介紹到這了,更多相關vue組件v-model區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 在Vue2中v-model和.sync區(qū)別解析
- Vue2子組件綁定 v-model,實現(xiàn)父子組件通信方式
- vue2中如何自定義組件的v-model
- Vue v-model相關知識總結
- vue2 v-model/v-text 中使用過濾器的方法示例
- vue 2.0組件與v-model詳解
- Vue2.0利用 v-model 實現(xiàn)組件props雙向綁定的優(yōu)美解決方案
- vue2 如何實現(xiàn)div contenteditable=“true”(類似于v-model)的效果
- vue2與vue3雙向數(shù)據(jù)綁定的區(qū)別說明
- vue 2 實現(xiàn)自定義組件一到多個v-model雙向數(shù)據(jù)綁定的方法(最新推薦)
相關文章
vue+element ui el-tooltip動態(tài)顯示隱藏問題
這篇文章主要介紹了vue+element ui el-tooltip動態(tài)顯示隱藏問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10
vue后端傳文件流轉化成blob對象,前端點擊下載返回undefined問題
這篇文章主要介紹了vue后端傳文件流轉化成blob對象,前端點擊下載返回undefined問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Vue3?封裝?Element?Plus?Menu?無限級菜單組件功能的詳細代碼
本文分別使用?SFC(模板方式)和?tsx?方式對?Element?Plus?*el-menu*?組件進行二次封裝,實現(xiàn)配置化的菜單,有了配置化的菜單,后續(xù)便可以根據(jù)路由動態(tài)渲染菜單,對Vue3?無限級菜單組件相關知識感興趣的朋友一起看看吧2022-09-09
Vue實現(xiàn)動態(tài)顯示textarea剩余字數(shù)
這篇文章主要為大家詳細介紹了Vue實現(xiàn)動態(tài)顯示textarea剩余文字數(shù)量,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
淺談el-table中使用虛擬列表對對表格進行優(yōu)化
我們會經(jīng)常使用表格,如果數(shù)據(jù)量大就直接可以分頁,如果多條可能會影響表格的卡頓,那么應該如何進行優(yōu)化,感興趣的可以了解一下2021-08-08

