巧妙運用v-model實現父子元件傳值
v-model介紹
熟悉Vue的小夥伴們都知道v-model
是Vue的一個很大的特色,可以實現雙向資料繫結。但本質上呢,它不過是語法糖,它負責監聽使用者的輸入事件以更新資料。
以下摘取自Vue官方文件
v-model
在內部使用不同的屬性為不同的輸入元素並丟擲不同的事件:
-
text
和textarea
使用value
屬性和input
事件; -
checkbox
和radio
使用checked
屬性和change
事件; -
select
欄位將value
作為 prop 並將change
作為事件。
如何巧妙利用v-model
實現父子元件傳值
通常子元件某個變數更新,並需要告知父元件時,需要子元件觸發事件並父元件監聽該事件。
但是熟悉上面v-model
的實現原理後,我們可以巧妙地運用這一原理
(v-model
在內部使用不同的屬性為不同的輸入元素並丟擲不同的事件)
。
方法總結:
-
1.子元件設
value
為props屬性,並且不主動改變value
值 -
2.子元件通過
this.$emit('input', 'updateValue')
將updateValue
值傳給父元件 -
3.父元件通過
v-model="localValue"
繫結一個本地變數,即可實現子元件value
值與父元件updateValue
值同步更新
舉例
子元件
子元件,包含一個button,並且將value
屬性設為props( 因為v-model
使用的是value
屬性 )。
點選button時,sum值加1,同時通過this.$emit('input', ++sum)
將更新後的值傳給父元件
(前提:傳給父元件的值一定是你想賦給value
的)
<template> <div> <button @click="increase" style="border: 1px solid black">increase</button> </div> </template>
<script> let sum = 0 export default { name: 'vmodel', props: { value: { type: Number, default: 0 } }, methods: { increase () { this.$emit('input', ++sum) console.log('value1', this.value) setTimeout(() => { console.log('value2', this.value) }, 50) } } } </script>
父元件
父元件中,通過v-model
繫結一個本地變數,即可實現子父元件同步更新
<div> <increase v-model="rangeValue"></increase> <p>value:{{rangeValue}}</p> </div>
<script> data () { return { rangeValue: 0 } } </script>
實際上,這個過程是首先子元件通過$emit('input')
更新父元件的本地變數,然後子元件中的value
屬性通過 props 得以更新