掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
對(duì)于vue來(lái)說(shuō),組件是非常常見(jiàn)的,有很多平臺(tái)都封裝了了屬于自己一套的組件,如element ui、we ui等等。同時(shí)組件之間的消息傳遞也是非常重要的,下面是我對(duì)組件之間消息傳遞的各種方式的總結(jié),共有8種方式。如有不足之處,可以留言補(bǔ)充,互相學(xué)習(xí)。

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、壽光ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的壽光網(wǎng)站制作公司
1. props和$emit
這是最最常用的父子組件通信方式,父組件向子組件傳遞數(shù)據(jù)是通過(guò)prop傳遞的,子組件傳遞數(shù)據(jù)給父組件是通過(guò)$emit觸發(fā)事件來(lái)做到的。 實(shí)例:
父組件
- Vue.component('parent',{
- template:`
父組件
- `,
- data(){
- return {
- message:'Hello web秀'
- }
- },
- methods:{
- //執(zhí)行子組件觸發(fā)的事件
- getChildData(val){
- console.log(val)
- }
- }
- })
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
子組件
- Vue.component('child',{
- //得到父組件傳遞過(guò)來(lái)的數(shù)據(jù)
- props:['message'],
- data(){
- return {
- myMessage: this.message
- }
- },
- template:`
- `,
- methods:{
- passData(val){
- //觸發(fā)父組件中的事件
- this.$emit('getChildData',val)
- }
- }
- })
解析:
2. $attrs和$listeners
***種方式處理父子組件之間的數(shù)據(jù)傳輸有一個(gè)問(wèn)題:如果多層嵌套,父組件A下面有子組件B,組件B下面有組件C,這時(shí)如果組件A想傳遞數(shù)據(jù)給組件C怎么辦呢?
如果采用***種方法,我們必須讓組件A通過(guò)prop傳遞消息給組件B,組件B在通過(guò)prop傳遞消息給組件C;要是組件A和組件C之間有更多的組件,那采用這種方式就很復(fù)雜了。從Vue 2.4開(kāi)始,提供了$attrs和$listeners來(lái)解決這個(gè)問(wèn)題,能夠讓組件A之間傳遞消息給組件C。
C組件
- Vue.component('C',{
- template:`
- `,
- methods:{
- passCData(val){
- //觸發(fā)父組件A中的事件
- this.$emit('getCData',val)
- }
- }
- })
B組件
- Vue.component('B',{
- data(){
- return {
- myMessage:this.message
- }
- },
- template:`
- `,
- //得到父組件傳遞過(guò)來(lái)的數(shù)據(jù)
- props:['message'],
- methods:{
- passData(val){
- //觸發(fā)父組件中的事件
- this.$emit('getChildData',val)
- }
- }
- })
A組件
- Vue.component('A',{
- template:`
this is parent compoent!
- :messageC="messageC"
- :message="message"
- v-on:getCData="getCData"
- v-on:getChildData="getChildData(message)">
- `,
- data(){
- return {
- message:'Hello',
- messageC:'Hello c'
- }
- },
- methods:{
- getChildData(val){
- console.log('這是來(lái)自B組件的數(shù)據(jù)')
- },
- //執(zhí)行C子組件觸發(fā)的事件
- getCData(val){
- console.log("這是來(lái)自C組件的數(shù)據(jù):"+val)
- }
- }
- })
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
解析:
3. v-model
父組件通過(guò)v-model傳遞值給子組件時(shí),會(huì)自動(dòng)傳遞一個(gè)value的prop屬性,在子組件中通過(guò)this.$emit(‘input',val)自動(dòng)修改v-model綁定的值
子組件
- Vue.component('child',{
- props:{
- //v-model會(huì)自動(dòng)傳遞一個(gè)字段為value的prop屬性
- value: String,
- },
- data(){
- return {
- myMessage:this.value
- }
- },
- methods:{
- changeValue(){
- //通過(guò)如此調(diào)用可以改變父組件上v-model綁定的值
- this.$emit('input',this.myMessage);
- }
- },
- template:`
- type="text"
- v-model="myMessage"
- @change="changeValue">
- `
- })
父組件
- Vue.component('parent',{
- template:`
this is parent compoent!
{{message}}
- `,
- data(){
- return {
- message:'Hello'
- }
- }
- })
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
4. provide和inject
父組件中通過(guò)provider來(lái)提供變量,然后在子組件中通過(guò)inject來(lái)注入變量。不論子組件有多深,只要調(diào)用了inject那么就可以注入provider中的數(shù)據(jù)。而不是局限于只能從當(dāng)前父組件的prop屬性來(lái)獲取數(shù)據(jù),只要在父組件的生命周期內(nèi),子組件都可以調(diào)用。
子組件
- Vue.component('child',{
- inject:['for'],//得到父組件傳遞過(guò)來(lái)的數(shù)據(jù)
- data(){
- return {
- myMessage: this.for
- }
- },
- template:`
- `
- })
父組件
- Vue.component('parent',{
- template:`
this is parent compoent!
- `,
- provide:{
- for:'test'
- },
- data(){
- return {
- message:'Hello'
- }
- }
- })
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
5. 中央事件總線(xiàn)
上面方式都是處理的父子組件之間的數(shù)據(jù)傳遞,那如果兩個(gè)組件不是父子關(guān)系呢?也就是兄弟組件如何通信?
這種情況下可以使用中央事件總線(xiàn)的方式。新建一個(gè)Vue事件bus對(duì)象,然后通過(guò)bus.$emit觸發(fā)事件,bus.$on監(jiān)聽(tīng)觸發(fā)的事件。
- Vue.component('brother1',{
- data(){
- return {
- myMessage:'Hello brother1'
- }
- },
- template:`
this is brother1 compoent!
- `,
- methods:{
- passData(val){
- //觸發(fā)全局事件globalEvent
- bus.$emit('globalEvent',val)
- }
- }
- })
- Vue.component('brother2',{
- template:`
this is brother2 compoent!
brother1傳遞過(guò)來(lái)的數(shù)據(jù):{{brothermessage}}
- `,
- data(){
- return {
- myMessage:'Hello brother2',
- brothermessage:''
- }
- },
- mounted(){
- //綁定全局事件globalEvent
- bus.$on('globalEvent',(val)=>{
- this.brothermessage=val;
- })
- }
- })
- //中央事件總線(xiàn)
- var bus=new Vue();
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
6. parent和children
- Vue.component('child',{
- props:{
- value:String, //v-model會(huì)自動(dòng)傳遞一個(gè)字段為value的prop屬性
- },
- data(){
- return {
- mymessage:this.value
- }
- },
- methods:{
- changeValue(){
- this.$parent.message = this.mymessage;//通過(guò)如此調(diào)用可以改變父組件的值
- }
- },
- template:`
- })
- Vue.component('parent',{
- template:`
this is parent compoent!
- `,
- methods:{
- changeChildValue(){
- this.$children[0].mymessage = 'hello';
- }//在此我向大家推薦一個(gè)前端全棧開(kāi)發(fā)交流圈:619586920 突破技術(shù)瓶頸,提升思維能力
- },
- data(){
- return {
- message:'hello'
- }
- }
- })
- var app=new Vue({
- el:'#app',
- template:`
- `
- })
7. boradcast和dispatch
vue1.0中提供了這種方式,但vue2.0中沒(méi)有,但很多開(kāi)源軟件都自己封裝了這種方式,比如min ui、element ui和iview等。 比如如下代碼,一般都作為一個(gè)mixins去使用, broadcast是向特定的父組件,觸發(fā)事件,dispatch是向特定的子組件觸發(fā)事件,本質(zhì)上這種方式還是on和on和emit的封裝,但在一些基礎(chǔ)組件中卻很實(shí)用。
- function broadcast(componentName, eventName, params) {
- this.$children.forEach(child => {
- var name = child.$options.componentName;
- if (name === componentName) {
- child.$emit.apply(child, [eventName].concat(params));
- } else {
- broadcast.apply(child, [componentName, eventName].concat(params));
- }
- });
- }
- export default {
- methods: {
- dispatch(componentName, eventName, params) {
- var parent = this.$parent;
- var name = parent.$options.componentName;
- while (parent && (!name || name !== componentName)) {
- parentparent = parent.$parent;
- if (parent) {
- name = parent.$options.componentName;
- }
- }
- if (parent) {
- parent.$emit.apply(parent, [eventName].concat(params));
- }
- },
- broadcast(componentName, eventName, params) {
- broadcast.call(this, componentName, eventName, params);
- }
- }
- };
8. vuex處理組件之間的數(shù)據(jù)交互
如果業(yè)務(wù)邏輯復(fù)雜,很多組件之間需要同時(shí)處理一些公共的數(shù)據(jù),這個(gè)時(shí)候才有上面這一些方法可能不利于項(xiàng)目的維護(hù),vuex的做法就是將這一些公共的數(shù)據(jù)抽離出來(lái),然后其他組件就可以對(duì)這個(gè)公共數(shù)據(jù)進(jìn)行讀寫(xiě)操作,這樣達(dá)到了解耦的目的。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流