元件間通信:(父子、兄弟元件資料的傳遞方式)
一、父元件向子元件傳遞:
1、常見方式:利用屬性傳遞資料
$attrs表示元件中未被注冊的屬性;可以利用其進行傳值;配合v-bind可以将所有屬性傳遞給另一個元件;

//根資料傳給元件,通過父元件傳給子元件:
var vm = new Vue({
el: "#app",
data: {
content: '我是内容',
title: '我是标題'
},
components: {
myContent: {
// props: ['title', 'content'], //這種方法注冊的'content'隻是用來傳值,沒用實際作用
props: ['title'],
created () {//$attrs表示元件中未被注冊的屬性;可以利用其進行傳值;
console.log(this.$attrs)
},
inheritAttrs: false, //設為false,沒有被注冊的屬性不會顯示在行間;(本身有的不會消除)
// template: `<div>
// <h3>{{ title }}</h3>
// <my-p :content="content"></my-p>
// </div>`,
template: `<div>
<h3>{{ title }}</h3>
<my-p v-bind="$attrs"></my-p>
</div>`,
components: {
myP: {
props: ['content'],
template: `<p>{{ content }}</p>`
}
}
}
}
})
2、$attrs、
$children:
一般情況下能不用不用,應急時使用(傳遞較麻煩)
//根資料直接父元件用一部分、子元件用一部分:
var vm1 = new Vue({
el: "#app1",
data: {
content: '我是内容',
title: '我是标題'
},
components: {
myContent: {
created () { //$parent表示父元件的執行個體;
console.log(this.$parent);
this.title = this.$parent.title
},
mounted () { //$childre表示子元件的執行個體;
console.log(this.$children)
},
template: `<div>
<h3>{{ title }}</h3>
<my-p> {{ title }}</my-p>
</div>`,
components: {
myP: {
created () {
this.content = this.$parent.$parent.content;
},
template: `<p>{{ content }}</p>`
}
}
}
}
})
3、provide:{}提供值,inject:[]接收值;(一般不用)
//父元件提供值,子元件可以取到;
var vm2 = new Vue({
el: "#app2",
provide: {
content: '我是内容',
title: '我是标題'
},
components: {
myContent: {
inject: ['title'],
template: `<div>
<h3>{{ title }}</h3>
<my-p> {{ title }}</my-p>
</div>`,
components: {
myP: {
inject: ['content'],
template: `<p>{{ content }}</p>`
}
}
}
}
})
二、子向父傳遞:
1、$children 方式擷取到子元件的執行個體,進行操作(不推薦)
2、$refs:拿到子元件的引用;可以dom上,也可以放到元件上;
const vm3 = new Vue({
el: "#app3",
mounted () {
console.log(this.$refs.dom); //放到dom上;
//這裡的dom元素如果初始時有多個且一樣,隻會列印最後一個;v-for生成的dom會全不列印在[]中;
console.log(this.$refs.cmp); //放到元件上;this.$refs.cmp拿到子元件裡的執行個體;再拿到裡面的資料;
console.log(this.$refs.cmp.msg);
this.$refs.cmp.cmpFunc()
},
components: {
myCmp: {
data () {
return {
msg: 'hello'
}
},
methods: {
cmpFunc () {
console.log('cmp')
}
},
template: `<div> i am a cmp </div>`
}
}
})
3、傳遞函數方式:通過在子元件中執行父元件的函數,向父元件傳遞資料
方法一:将父元件中的函數當做屬性傳給子元件執行;
方法二:利用 l i s t e n e r s : 能 夠 把 通 過 v − o n 綁 定 的 事 件 放 到 listeners:能夠把通過v-on綁定的事件放到 listeners:能夠把通過v−on綁定的事件放到listeners裡面來;
方法三:利用$emit(’’, );主動觸發元件v-on綁定的事件;第二個值可傳參用;
//注意:
//當事件綁定很多時,利用v-on給元件内某個dom綁定事件監聽(注意通過v-on方法不能傳參)
//$listeners與$attrs相似有一個v-on屬性,可以将該元件通過v-on綁定的事件傳遞給另一個元件;
//$listeners和$emit()不僅能觸發系統自帶的事件,也可以觸發自定義事件;
const vm4 = new Vue({
el: "#app4",
methods: {
func (data) {
console.log(data);
},
down (){
console.log('down')
}
},
components: {
myCmp: {
// props: ['func'], //方法一
data () {
return {
msg: 'hello'
}
},
methods: {
cmpFunc () {
console.log('cmp');
},
handleClick () {
// this.func(this.msg); //方法一;
// this.$listeners.click(this.msg); //方法二;
this.$emit('click', this.msg); //方法三;
},
handleMouse () {
this.$emit('mousedown', 4545);
}
},
template: `<div> i am a cmp
<button @click="handleClick" @mousedown="handleMouse">點選</button>
<button v-on="$listeners"> click </button>
</div>`
}
}
})
三、兄弟傳遞:
enent bus 事件總線: 一個兄弟組觸發新的vue執行個體事件并将資料傳參,另一個兄弟元件監聽該vue執行個體事件并取值;
this.bus. $emit(’’, )觸發事件;
this.bus. $on(’’, data => {})監聽事件;
Vue.prototype.bus = new Vue(); //vue原型上增加屬性為一個新的vue執行個體;
const vm5 = new Vue({
el: "#app5",
components: {
myContent1: { //一個兄弟組觸發新的vue執行個體事件并将資料傳參,
data () {
return {
content: '我有值'
}
},
methods: {
handleClick () {
console.log(this)
this.bus.$emit('myClick', this.content); //觸發新vue執行個體的事件
}
},
template: `<div> {{ content }}
<button @click="handleClick">送出</button>
</div>`
},
myContent: { //另一個兄弟元件監聽該vue執行個體事件并取值;
data () {
return {
msg: 123
}
},
created () {
this.bus.$on('myClick', data => { //監聽vue執行個體的事件
this.msg = data;
})
},
template: `<div> {{ msg }}</div>`
},
}})