在上一篇博客vue學習筆記(八)組件校驗&通訊中,咱們學會了vue中組件的校驗和父組件向子組件傳遞信息以及子組件通知父組件(父子組件通訊),上一篇博客也提到那是對組件內容的剛剛開始,而本章博客將會重點的講解vue-cli中的組件通訊,畢竟這在之後的開發內容中是很是廣泛使用的。那麼一塊兒來看看本篇博客須要學習的知識點吧!javascript
學會使用vue-cli中父組件向子組件傳遞信息html
學會使用vue-cli中子組件向父組件傳遞信息vue
學會使用vue-cli中非父子組件傳遞信息java
既然提到要使用vue-cli實現組件通訊,那麼確定要有vue-cli的環境,沒有搭建vue-cli環境的園友能夠參考這篇博客使用webstorm搭建vue-cli項目,這篇博客講解的很是透徹,你們能夠先將環境搭建好,而後再來看這篇博客,假設咱們項目搭建好了,項目目錄結構以下jquery
咱們須要在src/components/parent/建立兩個組件ParentComponent.vue和ChildComponent.vue,建立好以後目錄以下web
ParentComponent.vuevue-router
<template> <div> <h1>{{title}}</h1> <!--注意:每一個組件註冊必須有一個根元素--> <Child :message="message"></Child> </div> </template> <script> import Child from './ChildComponent' export default { name: "ParentComponent", data() { return { title:'這是父組件', message: '我是父組件' } }, components:{ Child } } </script> <style scoped> </style>
首先在父組件中定義兩個數據title和message,message是要傳遞給子組件的信息,第二步導入子組件和註冊子組件,第三步將須要傳遞的信息綁定到組件上。vue-cli
總結app
ChildComponent.vuewebstorm
<template> <div> <!--注意每一個組件註冊必須有一個根元素--> <h1>{{title}}</h1> <span>父組件傳遞過來的消息是:{{message}}</span> </div> </template> <script> export default { name: "ChildComponent", props:['message'], //使用props接收父組件傳遞的信息 data(){ return{ title:'這是子組件', } } } </script> <style scoped> </style>
在子組件中咱們使用props來接收父組件傳遞過來的信息,而後進行渲染數據就能夠了。
index.vue
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Hi from '@/components/Test/Hi' import parent from '@/components/parent/ParentComponent' Vue.use(Router) export default new Router({ routes: [ { path:'/', component:parent, name:parent } ] })
結果:
講到這裏使用vue-cli實現父組件向子組件傳遞信息我就講解完了,接下來實現子組件向父組件傳遞信息。
學會了父組件向子組件傳遞信息,接下來就要學習子組件向父組件傳遞信息,一樣咱們仍是使用如上的兩個組件,更新以後的代碼
ParentComponent.vue
<template> <div> <h1>{{title}}</h1> <!--注意:每一個組件註冊必須有一個根元素--> <Child :message="message" @send="getChildMsg"></Child> <h1>來自子組件的消息:{{childMsg}}</h1> </div> </template> <script> import Child from './ChildComponent' export default { name: "ParentComponent", data() { return { title:'這是父組件', message: '我是父組件', childMsg:'' } }, components:{ Child }, methods:{ getChildMsg(data){ this.childMsg=data; } } } </script> <style scoped> </style>
父組件中咱們從新定義了一個新的屬性(childMsg)來接收子組件傳遞過來的消息,能夠知道子組件向父組件傳遞的事件是send,而後調用send來接收子組件傳遞過來的數據
ChildComponent.vue
<template> <div> <!--注意每一個組件註冊必須有一個根元素--> <h1>{{title}}</h1> <span>父組件傳遞過來的消息是:{{message}}</span> <input type="button" value="向父組件傳遞信息" @click="sendMsgToParent"> </div> </template> <script> export default { name: "ChildComponent", props:['message'], //使用props接收父組件傳遞的信息 data(){ return{ title:'這是子組件', fromChildMsg:'我是來自子組件的消息', } }, methods:{ sendMsgToParent(){ this.$emit('send',this.fromChildMsg); } } } </script> <style scoped> </style>
子組件中也是從新定義了一個新的屬性(fromChildMsg),這個屬性是須要傳遞給父組件的,而後經過按鈕的點擊事件使用this.$emit()將事件名稱和數據傳遞給父組件,父組件註冊send方法以後就能夠接收到子組件傳遞過來的消息了
結果:
講到這裏父組件向子組件傳遞信息和子組件向父組件傳遞消息就所有講解完了,能夠說是講解的很是詳細,每一步我寫的都是很是清楚
總結:
在組件通訊中除了有父組件向子組件傳遞信息和子組件向父組件傳遞信息,還有非父子組件通訊,一樣我也會講解的很是詳細。
在src/components新建other目錄和兩個組件分別:BrotherComponent.vue,SisterComponent.vue,以及在src/assets下建立一個event.js文件,建立以後的目錄以下
event.js這個文件中咱們只建立了一個新的Vue實例,之後它就承擔起了組件之間通訊的用來充當總線橋樑了,也就是中央事件總線,爲的就是將BrotherComponent.vue和SisterComponent.vue聯繫起來。
event.js
//方式一 import Vue from 'Vue' export default new Vue /*方式二 let bus=new Vue export default bus */
BrotherComponent.vue
<template> <div> <h1>兄弟組件</h1> <input type="button" @click="sendMsg" value="向姐妹組件傳遞信息"> <sister></sister> </div> </template> <script> //導入總線 import bus from '../../assets/event' //導入姐妹組件 import sister from './SisterComponent' export default { name: "BrotherComponent", data(){ return{ tips:'I am your brother' } }, components:{ sister //註冊界面組件 }, methods:{ sendMsg(){ bus.$emit('send',this.tips); } } } </script> <style scoped> </style>
在這個組件中首先是導入的總線和姐妹組件,而後註冊了姐妹組件,咱們在響應點擊事件的sendMsg函數中用$emit觸發了一個自定義的send事件,並傳遞了一個字符串參數,
這個參數就是須要傳遞個姐妹組件的值。$emit實例方法觸發當前實例(這裏的當前實例就是bus)上的事件,附加參數都會傳給監聽器回調
SisterComponent.vue
<template> <div> <h1>姐妹組件</h1> <span>{{msg}}</span> </div> </template> <script> import bus from '../../assets/event' export default { name: "SisterComponent", data(){ return{ msg:'' } }, methods:{ getMsg(){ bus.$on('send',data=>{ this.msg=data; }) } }, mounted(){ this.getMsg(); } } </script> <style scoped> </style>
在這個組件中,咱們在mounted中,監聽了send,並把傳遞過來的字符串參數傳遞給了$on監聽器的回調函數,mounted:是一個Vue生命週期中的鉤子函數,簡單點說就相似於jquery的ready,Vue會在文檔加載完畢後調用mounted函數,$on:監聽當前實例上的自定義事件(此處當前實例爲bus)。事件能夠由$emit觸發,回調函數會接收全部傳入事件觸發函數($emit)的額外參數
index.js
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Hi from '@/components/Test/Hi' import parent from '@/components/parent/ParentComponent' import brother from '@/components/other/BrotherComponent' Vue.use(Router) export default new Router({ routes: [ { path:'/', component:brother, name:brother } ] })
結果
總結:
講到這裏組件基本通訊方式的已經講解完成了,以後等學習了更高級的內容以後再補充新的組件通訊的方式,一共講解了三種通訊方式,分別是父組件向子組件傳遞信息,子組件向父組件傳遞信息,非父子組件傳遞信息。內容很少講解的也十分詳細,那麼爲了鞏固組件的知識下面也會講解一些示例。
這個版本的任務清單在上一篇博客中已經講解過了,爲何在這裏又要從新提到呢?博主以爲上一篇博客沒有講解的很詳細,並且本篇博客也是還有其它版本的任務清單,因此將這兩個結合起來,學習起來也比較方便。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>普通版任務清單</title> </head> <body> <div id="app"> <input type="text" v-model="newTask" @keyup.enter="addNew" placeholder="請輸入你要完成的任務"/> <todo-item v-for="(item,index) of tasks" :title='item' :index="index" @remove="removeItem"></todo-item> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ newTask:'', tasks:['看一場電影','讀一本書','請朋友吃一頓飯'], }, methods:{ addNew(){ this.tasks.unshift(this.newTask);//向任務清單的最前面添加任務 this.newTask=''; //清空文本框中的內容 }, removeItem(index){ if(confirm('你肯定要刪除嗎?')){ this.tasks.splice(index); } } }, computed:{ }, components:{ 'todoItem':{ props:['title',"index"], template:'<li><span>{{title}}</span><button @click="sendMsg(index)">X</button></li>', methods:{ sendMsg(index){ console.log(index); this.$emit('remove',index); } } } } }) </script> </body> </html>
步驟分析:
普通版的任務清單咱們就結束了,接下來須要實現的是vue-cli中的任務清單,這個任務清單和普通版的沒有多大區別,只不過是換了一種寫法,原理仍是沒有改變的(換湯不換藥),那麼跟隨我一塊兒來瞧瞧吧!
在src/components下新建taks目錄和ParentComponent.vue和ChildComponent.vue兩個組件,創建以後的目錄以下
ParentComponent.vue
<template> <div> <h1>這是父組件</h1> <input type="text" v-model="newTask" @keyup.enter="addNew" placeholder="請輸入你要添加的任務"> <child v-for="(item,index) of tasks" :item="item" :index="index" @remove="removeItem" :key="index"></child> </div> </template> <script> import Child from './ChildComponent' export default { name: "ParentComponent", components:{ Child //註冊子組件 }, data(){ return{ newTask:'', tasks:['買一本書','看一場電影','寫一篇博客'], } }, methods:{ addNew(){ this.tasks.unshift(this.newTask); this.newTask=""; }, removeItem(index){ //刪除任務 if(confirm('你肯定要刪除嗎?')){ this.tasks.splice(index); } } } } </script> <style scoped> </style>
ChildComponent.vue
<template> <div> <li>{{item}}<button @click="sendMsg(index)">X</button></li> </div> </template> <script> export default { name: "ChildComponent", props:['item','index'], data(){ return{ } }, methods:{ sendMsg(index){ this.$emit('remove',index); } } } </script> <style scoped> </style>
index.js
import Vue from 'vue' import Router from 'vue-router' import parent from '@/components/task/ParentComponent' Vue.use(Router) export default new Router({ routes: [ { path:'/', component:parent, name:parent } ] })
vue-cli版本的任務清單咱們也就完成了,總之換湯不換藥,仍是那句老話,父組件向子組件傳遞信息使用props,子組件向父組件傳遞信息使用this.$emit('事件名稱',值1,值2,...)
這個案例和以前的也差很少,原理仍是同樣的,那麼一塊兒來看看吧!
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>普通版蜀國交稅</title> </head> <body> <div id="app"> <h2>{{name}}</h2> <h3>總數:{{total}}</h3> <me-tax @tax="undateTotal" name="趙雲" :unit="unit"></me-tax> <me-tax @tax="undateTotal" name="馬超" :unit="unit"></me-tax> <me-tax @tax="undateTotal" name="張飛" :unit="unit"></me-tax> <me-tax @tax="undateTotal" name="關羽" :unit="unit"></me-tax> <me-tax @tax="undateTotal" name="黃忠" :unit="unit"></me-tax> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('me-tax',{ template:'<button @click="upTax">{{money}}</button>', data(){ return{ money:0, } }, props:['name','unit'], methods:{ upTax(){ this.money+=this.unit; //稅收總和 this.$emit('tax',{name:this.name,money:this.money});// 通知父組件 } } }) let vm=new Vue({ el:'#app', data:{ name:'蜀國交稅', total:0, unit:10, //每次交稅的量 msg:'' }, methods:{ undateTotal(obj){ this.total+=this.unit; this.msg=obj.name+"交稅成功,已交稅"+obj.money; } }, computed:{ } }) </script> </body> </html>
結果
思路分析:
vue-cli版的蜀國交稅的話,咱們一樣按照步驟進行,一步一步來解析
在src/components新建money目錄和UnitTotalComponent.vue,UnitComponentA.vue,UnitComponentB.vue,UnitComponentC.vue,UnitComponentD.vue,UnitComponentE.vue六個組件,目錄結構以下
在這裏咱們將組件拆分了,上面是複製一樣的組件,而這裏是一個文件對應一個組件
UnitTotalComponent.vue
<template> <div> <h1>{{name}}</h1> <h3>總交稅:{{total}}</h3> <A title="張飛" :unit="unit" @tax="updateTotal"></A> <B title="關羽" :unit="unit" @tax="updateTotal"></B> <C title="馬超" :unit="unit" @tax="updateTotal"></C> <D title="趙雲" :unit="unit" @tax="updateTotal"></D> <E title="黃忠" :unit="unit" @tax="updateTotal"></E> <h3>{{msg}}</h3> </div> </template> <script> //導入相應的組件 import A from './UnitComponentA' import B from './UnitComponentB' import C from './UnitComponentC' import D from './UnitComponentD' import E from './UnitComponentE' export default { name: "UnitTotalComponent", data(){ return{ name:'蜀國交稅', total:0, unit:10, //每次交稅的量 msg:'' } }, components:{ //註冊組件 A, B, C, D, E }, methods:{ updateTotal(obj){ this.total+=this.unit; this.msg=obj.name+'交稅成功,已交稅'+obj.money; } } } </script> <style scoped> </style>
UnitComponentA.vue
<template> <div> <button @click="upTax">{{money}}</button> </div> </template> <script> export default { name: "UnitComponentA", props:['title','unit'], methods:{ upTax(){ this.money+=this.unit; this.$emit('tax',{name:this.title,money:this.money}); } }, data(){ return{ money:0, } } } </script> <style scoped> </style>
UnitComponentB.vue
<template> <div> <button @click="upTax">{{money}}</button> </div> </template> <script> export default { name: "UnitComponentB", props:['title','unit'], methods:{ upTax(){ this.money+=this.unit; this.$emit('tax',{name:this.title,money:this.money}); } }, data(){ return{ money:0, } } } </script> <style scoped> </style>
UnitComponentC.vue
<template> <div> <button @click="upTax">{{money}}</button> </div> </template> <script> export default { name: "UnitComponentC", props:['title','unit'], methods:{ upTax(){ this.money+=this.unit; this.$emit('tax',{name:this.title,money:this.money}); } }, data(){ return{ money:0, } } } </script> <style scoped> </style>
UnitComponentD.vue
<template> <div> <button @click="upTax">{{money}}</button> </div> </template> <script> export default { name: "UnitComponentD", props:['title','unit'], methods:{ upTax(){ this.money+=this.unit; this.$emit('tax',{name:this.title,money:this.money}); } }, data(){ return{ money:0, } } } </script> <style scoped> </style>
UnitComponentE.vue
<template> <div> <button @click="upTax">{{money}}</button> </div> </template> <script> export default { name: "UnitComponentE", props:['title','unit'], methods:{ upTax(){ this.money+=this.unit; this.$emit('tax',{name:this.title,money:this.money}); } }, data(){ return{ money:0, } } } </script> <style scoped> </style>
index.js
import Vue from 'vue' import Router from 'vue-router' import total from '@/components/money/UnitTotalComponent' Vue.use(Router) export default new Router({ routes: [ { path:'/', component:total, name:total } ] })
結果
vue的組件通訊到這裏就要告一段落了,該講解的知識點也講解完成了,反正這篇博客你反覆去看總會有收穫的。學習起來並不難,任務清單和蜀國交稅這兩個案例將所學的組件通訊結合了起來,學習起來也很是方便。
本篇博客主要講解了三個知識點,父組件向子組件傳遞信息,子組件向父組件傳遞信息,非父子組件通訊,父組件向子組件傳遞信息主要是經過props進行數據傳遞,子組件向父組件傳遞信息主要是經過this.$emit('事件名',值1,值2,...),非父子組件通訊,先創建中央通訊總線,傳遞數據的一方使用bus.$emit(),接收數據的一方使用bus.$on(),本篇博客已經將組件通訊這一方面的知識講解的很是透徹,後期全部的博客幾乎都會圍繞vue-cli項目的格式進行講解其它的知識點。
原文出處:https://www.cnblogs.com/jjgw/p/11964361.html