三、深入Vue組件——Vue插槽slot、動態組件


一、插槽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改變后的信息沒變(還是“改變信息之后”)
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM