一、Vue非父子組件傳值(Bus/總線/發布訂閱模式/觀察者模式)
我們在之前已經知道了父子傳值。父組件傳遞過來了的值,在子組件通過props接受,然后就可以使用了。
也學過了隔代傳值,均是通過props逐層傳遞實現。那么,兄弟節點之間怎么傳值呢? 那就是通過bus啦。

通過bus實現方式如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<child content='Dell'></child>
<child content='Lee'></child>
</div>
<script src="js/vue.js"></script>
<script>
//給每個Vue綁定一個bus屬性,其實他是一個Vue實例
Vue.prototype.bus = new Vue()
Vue.component('child',{
data:function() {
return {
//為了避免直接修改父組件傳過來的值,把父組件的值來一份拷貝
msg:this.content
}
},
props:{
content:String
},
template:'<div @click="handleClick">{{msg}}</div>',
methods:{
handleClick:function(){
//子組件會向父組件觸發change事件,同時把msg傳過去
this.bus.$emit('change',this.msg)
}
},
//這個組件掛載的時候,會執行的一個函數
mounted:function(){
//通過bus監聽change事件,當change事件觸發的時候,進行操作
var this_ = this
this.bus.$on('change',function(message) {
console.log(message)
this_.msg=message
})
}
})
// 1. 創建Vue的實例
let vm = new Vue({
el: '#app',
});
</script>
</body>
</html>
二、Vue中的作用域插槽
slot的作用域插槽使用場景:當我們希望將子組件中slot傳過來的數據,在父組件中用不同方式渲染的時候,就需要使用作用域插槽。
注意:自 2.6.0 起有所更新。已廢棄的使用 slot-scope 特性的語法在這里。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="root">
<child>
<template v-slot="props"><!--定義一個插槽,該插槽必須放在template標簽內-->
<li>{{props.value}}</li> //使用li方式進行渲染
</template>
</child>
<child>
<template v-slot="props">
<h1>{{props.value}}</h1><!--定義不同的渲染方式-->
</template>
</child>
</div>
<script src='js/vue.js'></script>
<script>
Vue.component('child',{
data: function(){
return {
list:[1,2,3,4]
}
},
template: `<div>
<ul>
<slot v-for="value in list" :value=value>//使用slot占位
</slot>
</ul>
</div>`
})
var vm=new Vue({
el: '#root'
})
</script>
</body>
</html>
結果如下:

三、動態組件和v-once
1、 Vue自帶了一個組件<componet></componet>,通過它綁定is屬性,來動態切換組件的顯示與否。
2、我們也可以設定v-once屬性來對頻繁切換的組件進行加速渲染,原理就是先讓組件保存在內存當中,下次渲染時,直接獲取;當然,這種場景一般可以使用v-show來應對頻繁切換渲染的情況。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="root">
<!--component :is='type'></component-->//vue中的動態組件,可以通過綁定is屬性來判斷加載哪個組件
<child-one v-if="type=='child-one'"></child-one>
//這里如果是頻繁切換的情況下,我們可以直接使用v-show來加速頁面的渲染
<child-two v-if="type=='child-two'"></child-two>
<button @click="handleClick">切換</button>
</div>
<script src='js/vue.js'></script>
<script>
Vue.component('child-one',{
//我們可以使用v-once來將這個組件先保存在內存當中,當切換的時候,直接從內存中獲取即可,加快了頁面的渲染速度
template: `<div v-once>child-one</div>`
})
Vue.component('child-two',{
template: `<div v-once>child-two</div>`
})
var vm=new Vue({
el: '#root',
data:{
type:'child-one'
},
methods:{
handleClick:function(){
this.type=this.type==='child-one'?'child-two':'child-one'
}
}
})
</script>
</body>
</html>
