v-model 雙向繫結原理 及其在 Vue2 和 Vue3 中的區別
阿新 • • 發佈:2021-11-24
場景
總結一波 v-model 原理,先說結論:v-model 本身是 v-bind 和 v-on 結合在一起的語法糖,是用於原生標籤(如input、textarea...
)和自定義元件上的一個簡化包裝,在 vue2 中 props 接收的 value,事件為 $emit(事件);在 vue3 中接收的 modelValue,事件為 $emit('update:modelValue')。原生的 v-model 會自動識別標籤屬性和事件。下面說實現。
步驟
以下程式碼實現全部是在工程化 vue3 中實現,但在 vue3 中也是支援 vue2 寫法的,只不過會有坑
- 實現一個基本的語法糖
// index.vue <template> <div class="test-vc"> <input :value="vc" type="text" placeholder="請輸入內容" @input="vc = $event.target.value" /> <div> 輸入的文字內容:{{ vc }} </div> </div> </template> <script> export default { name: 'Test', data() { return { vc: '' }; } }; </script> <style> .test-vc { width: 200px; height: 200px; padding: 16px; margin: 20px auto 0; border: 1px solid #ddd; border-radius: 4px; } </style>
- 完結版-在子元件上實現雙向繫結(vue3 && vue2)
// 子元件程式碼 <template> <div class="test-child"> 子元件 <input type="text" placeholder="請輸入內容" @input="onInput" /> 子元件輸入內容:{{ modelValue }} </div> </template> <script> export default { name: 'ChangeChild', props: { // 如果是 vue2 這裡 modelValue 換成 value,方法內還有一處 modelValue: { type: String, default: '' } }, data() { return {}; }, methods: { onInput(event) { // 如果是 vue2 這裡 update:modelValue 換成 input this.$emit('update:modelValue', event.target.value); } } }; </script> <style> .test-child { margin-top: 20px; } </style> // 父元件程式碼 <template> <div class="test-vc"> <input :value="vc" type="text" placeholder="請輸入內容" @input="vc = $event.target.value" /> <div> 輸入的文字內容:{{ vc }} </div> <ChangeChild v-model="vd" /> </div> </template> <script> import ChangeChild from './ChangeChild.vue'; export default { name: 'Test', components: { ChangeChild }, data() { return { vc: '', vd: '' }; } }; </script> <style> .test-vc { width: 200px; height: 200px; padding: 16px; margin: 20px auto 0; border: 1px solid #ddd; border-radius: 4px; } </style>