<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue元件通訊方式</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child-a class="child-a" v-bind:name="name" :skt="lol" scool="www" style="border: 1px green solid" @fire="onFire"
@click.native="handleClick">
</child-a>
</div>
<script>
/**
* Vue元件通訊方式
* 元件關係 root -> child-a -> child-b、child-c
* 1: $emit、v-on、$props 父子通訊
* 2: $emit、$on 事件匯流排,任意元件間通訊
* 3: $attrs、$listeners 父元件和後代元件通訊
* 4: ref、$children、$parent 可以呼叫父子元件的屬性和方法,ref可以獲取DOM例項或元件例項
* 5: inject、provide 祖先元件向其所有子孫後代注入一個依賴
* 6: vuex、路由、本地儲存也可以進行元件間通訊
* */
// 事件匯流排
Vue.prototype.bus = new Vue();
Vue.component("childA", {
inheritAttrs: true, // 是否顯示元件上的屬性,(排除class、style和被props接收的屬性)
provide: {
pre: 'hello world'
},
props: {
name: {
type: String,
defalut: ""
}
},
data: function() {
return {
message: "childA message",
code: "1001",
last: "lastName"
};
},
template: "" +
"<div>{{message}}" +
"<p ref='Ap'>{{name}} {{$parent.start}}</p>" +
"<child-b v-bind='$attrs' v-on='$listeners' ref='Ab'></child-b>" +
"<child-c v-bind='$attrs' v-on='$listeners' ref='Ac' class='child-c-class' style='color: red' first='firstName' :last='last'></child-c>" +
"<button @click='handleClick'>handleAClick</button>" +
"</div>",
methods: {
handleClick: function() {
this.$emit("fire", this.code);
}
},
mounted: function() {
console.log("childA $parent", this.$parent);
console.log("childA $children", this.$children);
console.log("childA $refs", this.$refs);
console.log("childA $attrs", this.$attrs);
console.log("childA $listeners", this.$listeners);
}
});
Vue.component("childB", {
data: function() {
return {
message: "childB message",
code: "1002"
};
},
template: "" +
"<div>{{message}}" +
"<button @click='handleClick'>handleBClick</button>" +
"</div>",
methods: {
handleClick: function() {
this.bus.$emit("bus", this.code);
}
},
mounted: function() {
console.log("childB $attrs", this.$attrs);
console.log("childB $listeners", this.$listeners);
}
});
Vue.component("childC", {
props: {
last: {
type: String,
default: ''
}
},
data: function() {
return {
message: "childC message"
};
},
template: "<div>{{message}} " +
"<child-d v-bind='$attrs' v-on='$listeners'></child-d>" +
"</div>",
beforeCreate: function() {
this.bus.$on("bus", function(e) {
console.log("on bus", e);
});
},
mounted: function() {
console.log("childC $attrs", this.$attrs);
console.log("childC $listeners", this.$listeners);
}
});
Vue.component("childD", {
inject: {
// she: {
// from: 'pre',
// default: 'she !'
// },
pre: {
default: 'she !'
}
},
data: function() {
return {
message: "childD message"
};
},
template: "<div>{{message}}</div>",
mounted: function() {
console.log("childD $listeners", this.$listeners);
console.log("childD $attrs", this.$attrs);
console.log("childD pre", this.pre);
}
});
var app = new Vue({
el: "#app",
data: {
messages: "hello vue !",
name: "name !",
start: "start !",
lol: "lol !"
},
methods: {
onFire: function(e) {
console.log("onFire", e);
},
handleClick: function(e) {
console.log("app handleClick", e);
}
}
});
</script>
</body>
</html>
複製程式碼