vue通訊的N種方式

組件通訊能夠分爲父子組件通訊、非父子組件通訊,能夠是數據的傳遞,也能夠是方法的傳遞,先介紹數據的相互傳遞,再介紹方法的相互傳遞。vue

父組件到子組件傳遞數據:

1、經過props,父組件能夠傳遞動態和靜態數據。vuex

//父組件
<template>
  <div id="app">
  	//第一種靜態數據 <HelloWorld msg="我是父組件的數據"/>
    //第二種動態綁定 <HelloWorld :msg="message"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      message: '我來自父組件'
    }
  },
  components: {
    HelloWorld
  }
}
</script>
複製代碼

//子組件
<template>
  <div class="hello">
    來自父組件的值:{{msg}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['msg']
  //或者 props: { msg: String//指定傳入的類型 }
  //或者 props: { msg: String,default: '默認值' //指定默認值 }
}
</script>複製代碼

2、provide / injectbash

provide 和 inject 主要爲高階插件/組件庫提供用例。並不推薦直接用於應用程序代碼中。而且這對選項須要一塊兒使用,以容許一個祖先組件向其全部子孫後代注入一個依賴,不論組件層次有多深,並在起上下游關係成立的時間裏始終生效。app

//父組件
<template>
   <div>
     <child-dom>
     </child-dom>
   </div>
</template>
<script>
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
       return{

       }
     },
     provide: {
      house: '房子',
      car: '車子',
      money: '¥10000'
    },
     methods:{
      
     },
     components:{childDom},
   }
</script>複製代碼

//子組件
<template>
   <div>
    
   </div>
</template>
<script>

   export default {
     data() {
       return{

       }
     },
     inject: {
	    house: {
	      default: '沒房'
	    },
	    car: {
	      default: '沒車'
	    },
	    money: {
	      default: '¥4500'
	    }
	  },
	  created () {
	    console.log(this.house, this.car, this.money)
	  },
	  methods:{
      
      }
   }
</script>
複製代碼

子組件傳值給父組件

1、經過props的回調dom

//父組件
<template>
  <div id="app">
    <HelloWorld :msg="message"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      
    }
  },
  methods: {
    message: (data)=>{
      console.log('我是父組件的方法,在子組件中被觸發了')
      console.log('來自子組件的值是:'+data)
    }
  },
  components: {
    HelloWorld
  }
}
</script>複製代碼

//子組件
<template>
  <div class="hello" @click="msg('來自子組件的值~~')">
    來自父組件的方法,點我執行
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['msg']
}
</script>複製代碼

2、經過$emit
ide

//父組件
<template>
  <div id="app">
    <HelloWorld @getData="message"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      
    }
  },
  methods: {
    message: (data)=>{
      console.log('來自子組件的值是:'+data)
    }
  },
  components: {
    HelloWorld
  }
}
</script>複製代碼

//子組件
<template>
  <div class="hello" @click="goFun">
    點擊傳值給父組件
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      s: 1111
    }
  },
  methods: {
    goFun(){
      this.$emit('getData',this.s)
    }
  }
}
</script>複製代碼

3、.sync修飾實現雙向綁定
ui

//父組件
<template>
  <div id="app">
    <HelloWorld :show.sync='valueChild'/>
    父組件值:{{valueChild}}
    <button @click="changeValue">點擊</button>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  data(){
    return{
      valueChild:true
    }
  },
  methods: {
    changeValue(){
      console.log('父組件的值被修改:'+this.valueChild)
      this.valueChild =!this.valueChild
    }
  },
  components: {
    HelloWorld
  }
}
</script>複製代碼

//子組件
<template>
  <div>
    <div>
      <p>子組件值:{{show}}</p>
      <button @click.stop="closeDiv">修改</button>
    </div>
    </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  methods: {
    closeDiv() {
      this.$emit('update:show', !this.show); //觸發 input 事件,並傳入新值
    }
  },
  props:['show']
}
</script>複製代碼

關係型組件跨級傳遞(根組件、兒子組件、孫子組件)

1、使用 $attrs 和 $listeners
this

經過 $attrs 將值連續往下傳遞(和props傳遞相似),傳遞過程當中能夠只選擇當前須要的值,組件中能夠經過 inheritAttrs:false 保持當前組件的屬性純淨度。經過 $listeners 能夠在(…子組件)中 this. $emit(「upRocket」,11111)來觸發父組件中的事件,從而達到傳值給父組件的目的。
spa

//父組件
<template>
   <div>
     <child-dom
      :foo="foo"
      :coo="coo"
      @upRocket="reciveRocket"
     >
     </child-dom>
   </div>
</template>
<script>
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
        return {
          foo:"Hello, world",
          coo:"Hello,rui"
        }
     },
     methods:{
       reciveRocket(data){
          console.log("我是根組件,這是接受的孫子組件的數據"+data)
       }
     },
     components:{childDom},
   }
</script>複製代碼

//子組件
<template>
   <div>
      <p>foo:{{foo}}</p>
      <childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
   </div>
</template>
<script>
import childDomChild from './childDomChild';
export default {
 name:'child-dom',
 props:["foo"],
 inheritAttrs:false,
 components:{childDomChild}
}
</script>複製代碼

//孫子組件
<template>
   <div>
      <p>coo:{{coo}}</p> 
      <button @click="startUpRocket">發送數據到根組件</button>   </div>
</template>
<script>

export default {
 name:'child-dom',
 props:["coo"],
 methods: {
     startUpRocket() {
      this.$emit("upRocket");
     }
  }
}
</script>複製代碼

2、$parent $children
插件

其實經過 $ r e f 能夠獲取到子組件中的一些掛載屬性和值, 父組件若是要獲取子組件的方法能夠經過this.$refs.mychild.funName("…");這種方式,給子組件指定ref名稱。同理,經過 $parent $children可直接操做數據和方法。

  • this. $parent查找當前組件的父組件。
  • this.$children查找當前組件的直接子組件,能夠獲取到所有直接子組件, 須要注意$children 並不保證順序,也不是響應式的。能夠經過this.$root.$children[0].$children[0].$children[0].msg連續查找
  • this.$root查找根組件,並能夠配合$children遍歷所有組件

//父組件
<template>
   <div>
    父組件的值:{{msg}}
     <child-dom>
     </child-dom>
     <button @click="change">父組件點擊修改</button>
   </div>
</template>
<script>
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
       return{
        msg: 0
       }
     },
     methods:{
      change(){
        this.msg = this.$children[0].childMsg
        this.$children[0].childMsg = '子組件的值被父組件修改了'
      }
     },
     mounted(){
     
     },
     components:{childDom},
   }
</script>複製代碼

//子組件
<template>
   <div>
      子組件的值:{{childMsg}}
      <button @click="decrease()">子組件點擊修改</button>
   </div>
</template>
<script>
export default {
  name:'child-dom',
  data() {
    return {
      childMsg : 111
    };
  },
  methods: {
    decrease() {
      this.childMsg = this.$parent.msg
      this.$parent.msg = "子組件修改了父組件的值"
    }
  }
}
</script>複製代碼

非關係組件傳值

1、EventBus

適用於小型項目,能夠達到任意組件相互通訊的效果

//組件a
<template>
   <div>
    {{fontCount}}
     <child-dom>
     </child-dom>
   </div>
</template>
<script>
   //import Vue from 'vue'   //export const EventBus = new Vue()
   import { EventBus } from "./assets/bus.js";
   import childDom from "./components/ChildDom.vue";
   export default {
     data() {
       return{
        fontCount: 0
       }
     },
     methods:{
     },
     mounted(){
      EventBus.$on("decreased", ({num}) => {
        this.fontCount -= num
      });
     },
     components:{childDom},
   }
</script>複製代碼

//組件b
<template>
   <div>
      <button @click="decrease()">-</button>
   </div>
</template>
<script>
import { EventBus } from "../assets/bus.js";
export default {
  name:'child-dom',
  data() {
    return {
      num: 1,
      deg:180
    };
  },
  methods: {
    decrease() {
      EventBus.$emit("decreased", {
        num:this.num
      });
    }
  }
}
</script>複製代碼

2、vuex

請移步官方文檔查閱具體內容

相關文章
相關標籤/搜索