Vue表單類的父子組件數(shù)據(jù)傳遞示例
使用Vue.js進行項目開發(fā),那必然會使用基于組件的開發(fā)方式,這種方式的確給開發(fā)和維護帶來的一定的便利性,但如果涉及到組件之間的數(shù)據(jù)與狀態(tài)傳遞交互,就是一件麻煩事了,特別是面對有一大堆表單的頁面。
在這里記錄一下我平時常用的處理方式,這篇文章主要記錄父子組件間的數(shù)據(jù)傳遞,非父子組件主要通過Vuex處理,這篇文章暫時不作說明。
與文檔里給的方案一樣,父組件向子組件傳遞數(shù)據(jù)主要通過 props,子組件向父組件傳遞數(shù)據(jù)主要通過觸發(fā)器 $emit(),只是在用法上會有些不同。
1、傳遞基本類型數(shù)據(jù)
當(dāng)子組件內(nèi)容較少時,會直接傳遞基本類型數(shù)據(jù),通常為String, Number, Boolean三種。
先看個例子:
<!-- 父組件 parent.vue -->
<template>
<div class="parent">
<h3>問卷調(diào)查</h3>
<child v-model="form.name"></child>
<div class="">
<p>姓名:{{form.name}}</p>
</div>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: {
child
},
data () {
return {
form: {
name: '請輸入姓名'
}
}
}
}
</script>
<!-- 子組件 child.vue -->
<template>
<div class="child">
<label>
姓名:<input type="text" :value="currentValue" @input="changeName">
</label>
</div>
</template>
<script>
export default {
props: {
// 這個 prop 屬性必須是 valule,因為 v-model 展開所 v-bind 的就是 value
value: ''
},
methods: {
changeName (e) {
// 給input元素的 input 事件綁定一個方法 changeName
// 每次執(zhí)行這個方法的時候都會觸發(fā)自定義事件 input,并且把輸入框的值傳遞進去。
this.$emit('input', e.target.value)
}
}
}
</script>
給子組件的 input 事件綁定一個方法 changeName,每次執(zhí)行這個方法的時候都會觸發(fā)自定義事件 input,并且把輸入框的值傳遞進去。
父組件通過 v-model 指令綁定一個值,來接收子組件傳遞過來的數(shù)據(jù)。但這樣只是父組件響應(yīng)子組件的數(shù)據(jù),如果還要子組件響應(yīng)父組件傳遞的數(shù)據(jù),就需要給子組件定義一個props屬性 value,并且這個屬性必須是 value,不能寫個其它單詞。
v-model 其實就是一個語法糖,詳情可以參考使用自定義事件的表單輸入組件。
2、傳遞引用類型數(shù)據(jù)
當(dāng)子組件里的內(nèi)容比較多時,比如子組件有多個表單元素,如果還像上面那樣給每個表單元素綁定值,那就要寫很多重復(fù)代碼了。所以這個時候通常傳遞的是一個對象,傳值的基本原理不變,不過寫法上會有些不同。
還是先看代碼:
<!-- 父組件 parent.vue -->
<template>
<div class="parent">
<h3>問卷調(diào)查</h3>
<child :formData.sync="form"></child>
<div class="">
<p>姓名:{{form.name}}</p>
</div>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: {
child
},
data () {
return {
form: {
name: '請輸入姓名',
age: '21'
}
}
}
}
</script>
<!-- 子組件 child.vue -->
<template>
<div class="child">
<label>
姓名:<input type="text" v-model="form.name">
</label>
<label>
年齡:<input type="text" v-model="form.age">
</label>
<label>
地點:<input type="text" v-model="form.address">
</label>
</div>
</template>
<script>
export default {
data () {
return {
form: {
name: '',
age: '',
address: ''
}
}
},
props: {
// 這個 prop 屬性接收父組件傳遞進來的值
formData: Object
},
watch: {
// 因為不能直接修改 props 里的屬性,所以不能直接把 formData 通過v-model進行綁定
// 在這里我們需要監(jiān)聽 formData,當(dāng)它發(fā)生變化時,立即將值賦給 data 里的 form
formData: {
immediate: true,
handler (val) {
this.form = val
}
}
},
mounted () {
// props 是單向數(shù)據(jù)流,通過觸發(fā) update 事件綁定 formData,
// 將 data 里的 form 指向父組件通過 formData 綁定的那個對象
// 父組件在綁定 formData 的時候,需要加上 .sync
this.$emit('update:formData', this.form)
}
}
</script>
props 是單向數(shù)據(jù)流,當(dāng)我們需要對 props 內(nèi)的屬性進行雙向綁定時,就需要用到.sync 修飾符,詳情請參考.sync 修飾符,這里不做贅述。
這里需要注意的是,vue 中是不能直接修改 props 的,所以如果我們要向父組件傳值,還是需要通過修改 data 里的值,prop 只是作為父子之間通話的中間人存在。
另外,如果我們想要預(yù)覽父組件最開始傳的數(shù)據(jù),就需要通過 watch 監(jiān)聽 prop 的變化,在子組件初始化的時候就把值傳進去。
注意: 我在子組件里把 this.$emit('update:formData', this.form) 放在 mounted 當(dāng)中的,其原因是為了避免在每個 input 標簽的 input 事件中觸發(fā)自定義事件,但這樣寫的前提是,父子組件都要共用一個對象。
這也就是上面代碼中,父組件中使用 :formData.sync="form" 綁定值時,form 是一個對象,而子組件中的觸發(fā)自定義事件 this.$emit('update:formData', this.form) ,this.form 也得是一個對象。
這里還需要注意的是,如果有多個子組件使用一個對象,那就要避免這種寫法,因為一個組件修改了這個對象的數(shù)據(jù),那么其它子組件也就都跟著改變了。
所以我在用的時候都是給每個子組件分配了一個自己的對象,比如:
data () {
return {
parentObject: {
child_1_obj: {},
child_2_obj: {},
}
}
}
這是在父組件里定義的數(shù)據(jù),當(dāng)然名字不會這樣取了。
結(jié)尾
也沒什么說的了,對 Vue 還是處于使用的階段,對其底層的東西了解還不夠,我也好想讀讀源碼,但總只是想想.....大家覺得有什么不妥的地方盡管說,大家相互交流交流。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue源碼之關(guān)于vm.$delete()/Vue.use()內(nèi)部原理詳解
這篇文章主要介紹了Vue源碼之關(guān)于vm.$delete()/Vue.use()內(nèi)部原理詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05
vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法
這篇文章主要介紹了vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01
vue elementUI tree樹形控件獲取父節(jié)點ID的實例
今天小編就為大家分享一篇vue elementUI tree樹形控件獲取父節(jié)點ID的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
使用Vue與Firebase構(gòu)建實時聊天應(yīng)用的示例代碼
隨著互聯(lián)網(wǎng)通訊技術(shù)的不斷進步,實時聊天應(yīng)用現(xiàn)在已成為我們?nèi)粘I钪胁豢苫蛉钡囊徊糠?無論是社交媒體平臺、工作溝通工具還是客戶支持系統(tǒng),實時聊天都在不斷被需求,今天,我們將介紹如何使用Vue.js與Firebase來構(gòu)建一個簡單而強大的實時聊天應(yīng)用,需要的朋友可以參考下2024-11-11

