props父傳子,$emit子傳父,看下邊代碼,清澈的像少女的眼眸。。。emmmjavascript
Vue.component('child',{
data(){
return {
mymessage:this.message
}
},
template:` <div> <input type="text" v-model="mymessage" @input="passData(mymessage)"> </div> `,
props:['message'],//獲得父組件傳遞過來的數據
methods:{
passData(val){
//觸發父組件中的事件
this.$emit('getChildData',val)
}
}
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
Vue.component('parent',{
template:` <div> <p>this is parent compoent!</p> <child :message="message" v-on:getChildData="getChildData"></child> </div> `,
data(){
return {
message:'張不慫'
}
},
methods:{
//執行子組件觸發的事件
getChildData(val){
console.log(val)
}
}
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
// 掛載
var app=new Vue({
el:'#app',
template:` <div> <parent></parent> </div> `
})
複製代碼
新建一個Vue事件bus對象,而後經過bus.$emit
觸發事件,bus.$on
監聽觸發的事件。vue
Vue.component('brother1',{
data(){
return {
mymessage:'hello brother1'
}
},
template:`
<div>
<p>this is brother1 compoent!</p>
<input type="text" v-model="mymessage"
@input="passData(mymessage)">
</div>
`,
methods:{
passData(val){
//觸發全局事件globalEvent
bus.$emit('globalEvent',val)
}
}
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
Vue.component('brother2',{
template:`
<div>
<p>this is brother2 compoent!</p>
<p>brother1傳遞過來的數據:{{brothermessage}}</p>
</div>
`,
data(){
return {
mymessage:'hello brother2',
brothermessage:''
}
},
mounted(){
//綁定全局事件globalEvent
bus.$on('globalEvent',(val)=>{
this.brothermessage=val;
})
}
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
//中央事件總線
var bus=new Vue();
var app=new Vue({
el:'#app',
template:`
<div>
<brother1></brother1>
<brother2></brother2>
</div>
`
})
複製代碼
父組件中經過provider來提供變量,而後在子組件中經過inject來注入變量。不論子組件有多深,只要調用了inject那麼就能夠注入provider中的數據。而不是侷限於只能從當前父組件的prop屬性來獲取數據,只要在父組件的生命週期內,子組件均可以調用。java
Vue.component('child',{
inject:['parent_var'],//獲得父組件傳遞過來的數據
data(){
return {
mymessage:this.parent_var
}
},
template:`
<div>
{{ message }}
</div>
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
Vue.component('parent',{
template:`
<div>
<child></child>
</div>
`,
provide:{
// 看你想傳遞啥了,這裏不寫固定的緣由是爲了防止限制你們的思惟
/*
好比你能夠把用戶登陸信息存儲在App.vue中,能夠把
provide:{app:this}注入,後續全部組件經過inject:['app'],
就能夠直接經過app.userInfo拿到用戶信息
*/
parent_var:'隨便什麼均可以(能夠是this,能夠是data中的數據)'
},
data(){
return {
message:'hello'
}
}
})
┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┄┅┄┅┄┅┄┅┄*
var app=new Vue({
el:'#app',
template:`
<div>
<parent></parent>
</div>
`
})
複製代碼
$attrs
和$listeners仍是多層的場景,App.vue-->A—>B,若是App直接想給B傳遞數據該怎麼辦?Vue 2.4開始提供了listeners來解決這個問題,可以讓組件App直接傳遞數據給組件B。我將代碼中關鍵點已經標註出, // ******關鍵點*****
vuex
app.vue引入A組件bash
<template>
<div id="app">
{{app}}
// ******關鍵點*****
<A :app="app" @test="doTest"/>
</div>
</template>
<script>
import A from "./components/A";
export default {
name: "App",
data() {
return {
app: "我是App的數據"
};
},
components: {
A
},
methods: {
doTest() {
console.log(this.app)
}
}
};
複製代碼
A.vue引入B組件app
<template>
<div class="hello">
<h6>這裏是A組件</h6>
<p>$attrs: {{$attrs}}</p>
<p>$listeners: {{$listeners}}</p>
// ******關鍵點***** v-bind傳遞的都是$attrs,v-on傳遞的都是$listeners
<B v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import B from "./B";
export default {
name: "A",
props: {
msg: String
},
components: { B },
mounted() {
console.log(this.$listeners);
}
};
</script>
複製代碼
B組件編輯器
<template>
<div class="hello">
<h6>這裏是B組件</h6>
// ******關鍵點*****
<p>$attrs: {{$attrs}}</p>
</div>
</template>
<script>
export default {
name: "B",
props: {
msg: String
},
mounted() {
// ******關鍵點*****
// 爲啥這裏直接能emitApp組件傳遞的test呢?
// 由於在A組件中有一個關鍵操做是 <B v-bind="$attrs" v-on="$listeners"/>
this.$emit("test");
}
};
</script>
複製代碼
$parent
和$children分別是得到父組件和子組件的實例ide
Vue.component('child',{
props:{
value:String, //v-model會自動傳遞一個字段爲value的prop屬性
},
data(){
return {
mymessage:this.value
}
},
methods:{
changeValue(){
this.$parent.message = this.mymessage;//經過如此調用能夠改變父組件的值
}
},
template:`
<div>
<input type="text" v-model="mymessage" @change="changeValue">
</div>
})
Vue.component('parent',{
template:`
<div>
<p>this is parent compoent!</p>
<button @click="changeChildValue">test</button >
<child></child>
</div>
`,
methods:{
changeChildValue(){
this.$children[0].mymessage = 'hello';
}
},
data(){
return {
message:'hello'
}
}
})
var app=new Vue({
el:'#app',
template:`
<div>
<parent></parent>
</div>
`
})
複製代碼
父組件經過v-model傳遞值給子組件時,會自動傳遞一個value的prop屬性,在子組件中經過this.$emit(‘input’,val)自動修改v-model綁定的值post
Vue.component('child',{
props:{
value:String, //v-model會自動傳遞一個字段爲value的prop屬性
},
data(){
return {
mymessage:this.value
}
},
methods:{
changeValue(){
this.$emit('input',this.mymessage); //經過如此調用能夠改變父組件上v-model綁定的值
}
},
template:`
<div>
<input type="text" v-model="mymessage" @change="changeValue">
</div>
})
Vue.component('parent',{
template:`
<div>
<p>this is parent compoent!</p>
<p>{{message}}</p>
<child v-model="message"></child>
</div>
`,
data(){
return {
message:'hello'
}
}
})
var app=new Vue({
el:'#app',
template:`
<div>
<parent></parent>
</div>
`
})
複製代碼
vue1.0中提供了這種方式,但vue2.0中沒有,但不少開源軟件都本身封裝了這種方式,好比min ui、element ui, broadcast是向特定的父組件,觸發事件,dispatch是向特定的子組件觸發事件,本質上這種方式仍是使用遞歸對on和emit的封裝,但在一些基礎組件中卻很實用。注意:全部組件的名稱不能重複!!!ui
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));
}
});
}
function dispatch(componentName, eventName, params) {
var parent = this.$parent;
var name = parent.$options.componentName;
while (parent && (!name && name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.componentName;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
}
export default {
methods: {
dispatch(componentName, eventName, params) {
dispatch.call(this, componentName, eventName, params);
},
broadcast(componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params);
}
}
};
複製代碼
對於vuex再也不作過多的贅述。。。
第二章很是全面的講解了vue炒雞重要的一個技能,組件通訊,我說這一篇全面你們應該沒意見吧?好了就這樣...
以爲對你有幫助,不妨點個
,後續持續輸出這種簡短有效的文章,幫助你用最短的時間內掌握最多的內容,畢竟誰不喜歡一勞永逸不是? ❥(^_-) thank you ~