vue自定義元件實現v-model雙向繫結
阿新 • • 發佈:2018-11-11
vue中父子元件通訊,都是單項的,直接在子元件中修改prop傳的值vue也會給出一個警告,接下來就用一個小列子一步一步實現了vue自定義的元件實現v-model雙向繫結,父元件值變了子元件也會跟著變,子元件中傳過來的值變了,父元件值也會跟著變化。如有錯誤的地方歡迎評論指出
父級元件
<template>
<div>
<p>我是父級元件</p>
<p>父級元件內容:{{ text }}</p>
<p><button @click="onChange">改變內容< /button></p>
<hr>
<child v-model="text"></child>
</div>
</template>
<script>
import Child from './child'
export default {
components: {
Child
},
data() {
return {
text: '我是父級元件的內容'
}
},
methods: {
onChange() {
this .text = '我是由父級元件觸發改變了內容'
}
}
}
</script>
<style scoped>
</style>
子元件
<template>
<div>
<p>我是子元件</p>
<p>子元件內容:{{ value }}</p>
<p><button @click="onChange">改變內容</button></p>
</div>
</template>
< script>
export default {
props: {
//此處一定要用value
value: {
type: String
}
},
methods: {
onChange() {
this.value = '我是由子元件觸發改變了內容'
}
}
}
</script>
<style scoped>
</style>
預覽
這時候我們點選父級元件中的改變內容按鈕,發現一切正常,沒有問題
然後我們再點選子元件中的改變內容按鈕,發現父級元件沒變化,子元件雖然變了,但是vue給出了警告,因為是單向資料流,子元件不應該直接修改prop傳的值。難道就沒喲辦法了嗎,辦法肯定是有的,繼續往下看。
只需要將程式碼稍微改造下,如下,在data中頂一個myValue
值,指向prop傳過來的value
,點選按鈕改變內容的時候,改變myValue
的值,這樣vue就不會給出警告了。
<template>
<div>
<p>我是子元件</p>
<p>子元件內容:{{ myValue }}</p>
<p><button @click="onChange">改變內容</button></p>
</div>
</template>
<script>
export default {
props: {
//此處一定要用value
value: {
type: String
}
},
data() {
return {
myValue: this.value
}
},
methods: {
onChange() {
this.myValue = '我是由子元件觸發改變了內容'
}
}
}
</script>
<style scoped>
</style>
此時還沒完,發現子元件的內容變了,父級元件的內容卻沒有變化,點選父級元件的改變內容按鈕後,子元件的內容也沒變化,繼續對程式碼進行改造
最終改造後的程式碼如下,重點是加個watch,監聽父元件傳過來的value
和子元件的myValue
<template>
<div>
<p>我是子元件</p>
<p>子元件內容:{{ myValue }}</p>
<p><button @click="onChange">改變內容</button></p>
</div>
</template>
<script>
export default {
props: {
//此處一定要用value
value: {
type: String
}
},
data() {
return {
myValue: this.value
}
},
methods: {
onChange() {
this.myValue = '我是由子元件觸發改變了內容'
}
},
watch: {
//監聽prop傳的value,如果父級有變化了,將子元件的myValue也跟著變,達到父變子變的效果
value(newVal) {
this.myValue = newVal
},
//監聽myValue,如果子元件中的內容變化了,通知父級元件,將新的值告訴父級元件,我更新了,父級元件接受到值後頁就跟著變了
//參考官網:https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model
myValue(newVal) {
this.$emit('input', newVal)
}
}
}
</script>
<style scoped>
</style>
看下動態效果圖,父變子變,子變父變,也沒有報錯警告。
甚至還可以加個input框,也是沒有問題的