一、插槽slot()
1.1簡單插槽slot
【功能】用於從父組件中,通過子組件寫成雙標簽,向子組件中放入自定的內容
parent.vue
【1】首先把child寫成雙標簽樣式,把要插入的內容放雙標簽中間
【注】如果要控制樣式在父組件中,在子組件中寫樣式都可以
<template>
<div class="parent">
<span>父組件</span>
<Child><!--【1】首先把child寫成雙標簽樣式,把要插入的內容放雙標簽中間-->
<p>插入子組件的內容</p>
</Child>
</div>
</template>
<script>
import Child from './child';
export default{
name:'parent',
components:{
Child,
},
data(){
return{}
},
}
</script>
<style>
</style>
child.vue
【2】在子組件放個slot雙標簽接收父組件在雙標簽中插入的內容
<template>
<div class="child">
<span>子組件</span>
<slot>如果沒有傳遞內容則顯示默認信息</slot> <!--【2】在子組件放個slot雙標簽接收父組件在雙標簽中插入的內容;如果沒有傳遞,則顯示默認的內容,如果傳遞了,則不顯示默認內容-->
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
}
</script>
<style>
</style>
App.vue
不重要
<template>
<div id="app">
<img src="./assets/logo.png">
<Parent /> <!-- 【2】第2步,調用子組件 -->
</div>
</template>
<script>
import Parent from './components/parent' //【1】第1步,引入子組件
export default {
name: 'App',
components: {
Parent //【3】第3步,把組件寫到此處,目的是把它暴露出去
},
data () {//data必須是一個函數,此為標准es6寫法,也可寫成data:function()
return {
msg: 'hello',
}
},
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
效果:如下圖,原寫在父組件的內容,已經插入到子組件中了
1.2具名插槽(多個插槽-控制輸入到子組件的不同位置)
parent.vue
【1】在child雙標簽下寫入對應的內容,在標簽上加個屬性(<p slot=xxx,
>)(xxx為子組件中的 name值<slot name=xxx>
)在標簽中加上想插入的內容
<template>
<div class="parent">
<span>父組件</span>
<Child>
<p slot='top'>插入子組件的內容——上</p>
<p slot='bottom'>插入的內容——下</p>
</Child>
</div>
</template>
<script>
import Child from './child';
export default{
name:'parent',
components:{
Child,
},
data(){
return{}
},
}
</script>
<style>
</style>
child.vue
【1】對slot加個屬性name=xxx,
<template>
<div class="child">
<span>子組件</span>
<slot name="top">后備內容</slot>
<hr />
<slot name="bottom">后備內容2</slot>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
}
</script>
<style>
</style>
1.2.2插入一堆東西到子組件的插槽寫法
只要把所子標簽外面包一個父標簽,把slot='name-value'放在父標簽上即可
parent.vue
其它部分不變;
child.vue不變;
<Child>
<div slot='top'>
<p>插入內容——上</p>
<p>插入內容——上2</p>
<p>插入內容——上3</p>
</div>
<div slot='bottom'>
<p>插入的內容——下</p>
<p>插入的內容——下2</p>
<p>插入的內容——下3</p>
</div>
</Child>
效果:
1.3作用域插槽
用於子組件中的插槽向父組件對應插頭傳遞數據;
官方文檔:https://cn.vuejs.org/v2/guide/components-slots.html#作用域插槽
parent.vue
【1】首先必須要在對應插槽名字的位置加個屬性slot-scope='props';props可隨意寫,【2】處對應即可
【2】用{{props.text}}顯示子組件插槽 傳過來的數據
<template>
<div class="parent">
<span>父組件</span>
<Child>
<div slot='top' slot-scope='props'> <!-- 【1】首先必須要在對應插槽名字的位置加個屬性slot-scope='props'; props可隨意寫 -->
<p>{{props.text}}</p> <!-- 【2】用{{props.text}}顯示子組件插槽 傳過來的數據 -->
</div>
<div slot='bottom' >
<p>插入的數據——下1</p>
<p>插入的內容——下2</p>
<p>插入的內容——下3</p>
</div>
</Child>
</div>
</template>
<script>
import Child from './child';
export default{
name:'parent',
components:{
Child,
},
data(){
return{}
},
}
</script>
<style>
</style>
child.vue
【1】通過在插槽里放一個自定義屬性text='待傳遞的數據'向父組件傳數據
<template>
<div class="child">
<span>子組件</span>
<slot name="top" text='子插槽向父組件傳的數據'>后備內容</slot><!-- 【1】通過在插槽里放一個自定義屬性text='待傳遞的數據'向父組件傳數據 -->
<hr/>
<slot name="bottom">后備內容2</slot>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
}
</script>
<style>
</style>
效果:此即子組件的插槽向,父組件的對應插頭傳遞的數據;
二、動態組件
2.1簡單的動態組件切換寫法
parent.vue
【0】寫1個數據用來指向隨便一個子組件名
【1】動態組件寫法,在內部加上屬性用來綁定數據部分
【2】切換子組件,利用在methods里的changeView函數實現
【3】改變數據里的指向為另一個子組件2,即可在component里實現組件視圖的切換
<template>
<div class="parent">
<span>父組件</span>
<component v-bind:is="currentView"></component><!-- 【1】動態組件寫法,在內部加上屬性用來綁定數據部分 -->
<button v-on:click='changeView'>切換到子組件2視圖</button><!-- 【2】切換子組件,利用在methods里的changeView函數實現 -->
</div>
</template>
<script>
import Child from './child';
import Child2 from './child2';
export default{
name:'parent',
components:{
Child,
Child2,
},
data(){
return{
currentView:"Child" //【0】寫1個數據用來指向隨便一個子組件名
}
},
methods:{
changeView(){
return this.currentView='Child2'//【3】改變數據里的指向為另一個子組件2,即可在component里實現組件視圖的切換
}
}
}
</script>
<style>
</style>
child.vue
<template>
<div class="child">
<span>子組件1</span>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
}
</script>
<style>
</style>
child2.vue
<template>
<div class="child2">
<span>子組件2</span>
</div>
</template>
<script>
export default{
name:'child2',
data(){
return{}
},
}
</script>
<style>
</style>
結果:由子組件1切換到 子組件2.
2.2keep-alive標簽把要來回切換的組件放到緩存中提高性能
keep-alive標簽把要來回切換的組件放到緩存中提高性能,同時保持狀態;
parent.vue
<template>
<div class="parent">
<span>父組件</span>
<keep-alive><!-- 【2.1】把要切換的組件放在此標簽內,可保持它一直被緩存在內存;切換回來時不會新建立一個組件實例;還有一個好處可以保持之前那個組件狀態,選中哪個不會被清除; -->
<component v-bind:is="currentView"></component><!-- 【1】動態組件寫法,在內部加上屬性用來綁定數據部分 -->
</keep-alive>
<button v-on:click='changeView'>切換到子組件2視圖</button><!-- 【2】切換子組件,利用在methods里的changeView函數實現 【2.2】切換也是這里-->
</div>
</template>
<script>
import Child from './child';
import Child2 from './child2';
export default{
name:'parent',
components:{
Child,
Child2,
},
data(){
return{
currentView:"Child",//【0】寫1個數據用來指向隨便一個子組件名
flag:true,//【2.0】設置一個標志
}
},
methods:{
changeView(){
if(this.flag){//【2.3】也是調用這個函數
this.currentView='Child';//【3】改變數據里的指向為另一個子組件2,即可在component里實現組件視圖的切換
this.flag=false;
}else{
this.currentView='Child2';
this.flag=true;
}
}
}
}
</script>
<style>
</style>
child.vue
<template>
<div class="child">
<span>子組件1</span>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{}
},
}
</script>
<style>
</style>
child2.vue
<template>
<div class="child2">
<span>子組件2</span>
</div>
</template>
<script>
export default{
name:'child2',
data(){
return{}
},
}
</script>
<style>
</style>
2.2.1keep-alive保持狀態效果
其它代碼同上例,只有child.vue改變
child.vue
1、在數據里定義一個msg
2、用按鈕改變它,因為parent.vue里用了keep-alive標簽,所以改變后的msg信息不會變回之前
<template>
<div class="child">
<span>子組件1</span>
<p>{{msg}}</p>
<button @click="chMsg">改變信息</button>
</div>
</template>
<script>
export default{
name:'child',
data(){
return{
msg:'信息變之前',
}
},
methods:{
chMsg(){
this.msg='改變信息之后'
}
}
}
</script>
<style>
</style>
結果:
1、先點1號按鈕改變子組件里的msg信息
2、再點2號按鈕切換視圖,再點回來,Msg改變后的信息沒變(還是“改變信息之后”)