由於對Vue.js很感興趣,並且平時工做的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,並作了總結與輸出。javascript
文章的原地址:https://github.com/answershuto/learnVue。html
在學習過程當中,爲Vue加上了中文的註釋https://github.com/answershuto/learnVue/tree/master/vue-src,但願能夠對其餘想學習Vue源碼的小夥伴有所幫助。vue
可能會有理解存在誤差的地方,歡迎提issue指出,共同窗習,共同進步。java
使用props,父組件可使用props向子組件傳遞數據。github
父組件vue模板father.vuevuex
<template> <child :msg="message"></child> </template> <script> import child from './child.vue'; export default { components: { child }, data () { return { message: 'father message'; } } } </script>
子組件vue模板child.vueapi
<template> <div>{{msg}}</div> </template> <script> export default { props: { msg: { type: String, required: true } } } </script>
使用$children能夠在父組件中訪問子組件。ide
父組件向子組件傳遞事件方法,子組件經過$emit觸發事件,回調給父組件。學習
父組件vue模板father.vue
<template> <child @msgFunc="func"></child> </template> <script> import child from './child.vue'; export default { components: { child }, methods: { func (msg) { console.log(msg); } } } </script>
子組件vue模板child.vue
<template> <button @click="handleClick">點我</button> </template> <script> export default { props: { msg: { type: String, required: true } }, methods () { handleClick () { //........ this.$emit('msgFunc'); } } } </script>
這種方法只能在父組件傳遞一個引用變量時可使用,字面變量沒法達到相應效果。由於飲用變量最終不管是父組件中的數據仍是子組件獲得的props中的數據都是指向同一塊內存地址,因此修改了子組件中props的數據即修改了父組件的數據。
可是並不推薦這麼作,並不建議直接修改props的值,若是數據是用於顯示修改的,在實際開發中我常常會將其放入data中,在須要回傳給父組件的時候再用事件回傳數據。這樣作保持了組件獨立以及解耦,不會由於使用同一份數據而致使數據流異常混亂,只經過特定的接口傳遞數據來達到修改數據的目的,而內部數據狀態由專門的data負責管理。
使用$parent能夠訪問父組件的數據。
非父子組件通訊,Vue官方推薦使用一個Vue實例做爲中央事件總線。
Vue內部有一個事件機制,能夠參考源碼。
$on方法用來監聽一個事件。
$emit用來觸發一個事件。
/*新建一個Vue實例做爲中央事件總嫌*/ let event = new Vue(); /*監聽事件*/ event.$on('eventName', (val) => { //......do something }); /*觸發事件*/ event.$emit('eventName', 'this is a message.');
在Vue1.0中實現了$broadcast與$dispatch兩個方法用來向子組件(或父組件)廣播(或派發),當子組件(或父組件)上監聽了事件並返回true的時候會向爺孫級組件繼續廣播(或派發)事件。可是這個方法在Vue2.0裏面已經被移除了。
以前在學習餓了麼的開源組件庫element的時候發現他們從新實現了broadcast以及dispatch的方法,以mixin的方式引入,具體能夠參考《說說element組件庫broadcast與dispatch》。可是跟Vue1.0的兩個方法實現有略微的不一樣。這兩個方法實現了向子孫組件事件廣播以及向多層級父組件事件派發的功能。可是並不是廣義上的事件廣播,它須要指定一個commentName進行向指定組件名組件定向廣播(派發)事件。
其實這兩個方法內部實現仍是用到的仍是$parent以及$children,用以遍歷子節點或是逐級向上查詢父節點,訪問到指定組件名的時候,調用$emit觸發指定事件。
當應用足夠複雜狀況下,請使用vuex進行數據管理。
做者:染陌
Email:answershuto@gmail.com or answershuto@126.com
Github: https://github.com/answershuto
Blog:http://answershuto.github.io/
知乎主頁:https://www.zhihu.com/people/cao-yang-49/activities
知乎專欄:https://zhuanlan.zhihu.com/ranmo
掘金: https://juejin.im/user/58f87ae844d9040069ca7507
osChina:https://my.oschina.net/u/3161824/blog
轉載請註明出處,謝謝。
歡迎關注個人公衆號