探討一下子父組件之間的傳值通信問題:
首先是環境搭建:
打開git ,運行 npm install --global vue-cli 這是安裝vue的命令行
vue init webpack vue-demo 這是vue基于webpack的模板項目
cd vue-demo 進入vue-demo文件夾
npm install 安裝package.json中依賴的node_modules
npm run dev 運行該項目
接著我們進入Demo,首先我們可以刪除掉模板項目中src/components/Hello.vue,然后在App.vue中刪除對于Hello子組件的注冊和使用還有一些其他無關緊要的東西,此時的App.vue應為這樣:
一.父組件向子組件傳值
1.創建子組件,在src/components/文件夾下新建一個Child.vue
2.Child.vue的中創建props,然后創建一個名為message的屬性
3.在App.vue中注冊Child組件,并在template中加入child標簽,標簽中添加message屬性并賦值
4.保存修改的文件,查看瀏覽器
5.我們依然可以對message的值進行v-bind動態綁定:
此時瀏覽器中
父組件向子組件傳值成功
總結一下:
子組件在props中創建一個屬性,用以接收父組件傳過來的值;
父組件中注冊子組件;
在子組件標簽中添加子組件props中創建的屬性;
把需要傳給子組件的值賦給該屬性。
注意事項:在利用props實現傳值的過程中理論上是要實現單向傳遞,即父組件改變相關參數的值,子組件也相應變化,但是子組件對參數的改變不應該影響父組件。但是當props中接收的是父組件傳遞的引用類型(對象或者是數組)時,在子組件中對數據改變時,父組件中的數據也會相應的改變,因為兩者是指向的同一地址內存。如果不想子組件的改變影響父組件可以利用深拷貝,將接受的數據進行深拷貝后在子組件中使用,而不直接操作接受的數據。深拷貝可以直接利用ES6中的obj=Object。assign({},myMessage)(在computed中定義),這樣子組件的改動將不會影響到父組件。
二.子組件向父組件傳值利用事件機制
子組件通過this.$emit()派發事件,父組件利用v-on對事件進行監聽,實現參數的傳遞。
1.在子組件中創建一個按鈕,給按鈕綁定一個點擊事件
2.在響應該點擊事件的函數中使用$emit來觸發一個自定義事件,并傳遞一個參數:
3.在父組件中的子標簽中監聽該自定義事件并添加一個響應該事件的處理方法:
同時當有組件嵌套時則需要利用該機制一層一層的觸發到指定層,不然直接在頂層監聽子組件的子組件的事件是監聽不到的,需要先向父組件派發,父組件在向上層觸發。
4.保存修改的文件,在瀏覽器中點擊按鈕
子組件向父組件傳值成功
總結一下:
子組件中需要以某種方式例如點擊事件的方法來觸發一個自定義事件;
將需要傳的值作為$emit的第二個參數,該值將作為實參傳給響應自定義事件的方法;
在父組件中注冊子組件并在子組件標簽上綁定對自定義事件的監聽。
example2:
子組件:
this.$emit('changeCart',event.target)/*向父組件派發事件,同時傳遞參數event.target,后面的參數的個數不限*/
父組件:
<v-cartcontrol :food="food" v-on:changeCart="changeCart"></v-cartcontrol>
三、利用ref屬性可以獲取到dom元素或者是子組件,從而可以調用子組件的方法(注意2.0版本用ref取代了el)
1、當ref直接定義在dom元素上時,則通過this.$refs.name可以獲取到dom對dom進行原生的操作:
<divclass="foods-wrapper" ref="foods-wrapper">
通過this.$refs獲取到dom進行操作(注意ref屬性的命名不能用駝峰,同時獲取的時候也是)
let menuList=this.$refs['menu-wrapper'].getElementsByClassName('menu-list-hook');//此處如果用this.$refs["menuWrapper"]將獲取不到元素
2、通過在引用的子組件上使用ref屬性實現父組件調用子組件的方法以及屬性
在父組件中引用子組件并定義ref
<v-food ref="selectfood"></v-food>
調用定義在子組件中的方法show
this.$refs.selectfood.show();//同時也可以調用子組件中的屬性
在通信中,無論是子組件向父組件傳值還是父組件向子組件傳值,他們都有一個共同點就是有中間介質,子向父的介質是自定義事件,父向子的介質是props中的屬性。抓準這兩點對于父子通信就好理解了。