何为插槽

当在子组件中添加元素和文本,默认是不会渲染,会直接忽略掉
插槽就是你在模板中写的HTML带入组件中的template中进行渲染

示例

  1. <section id="app">
  2. <my-cmp> 插槽: my-cmp </my-cmp>
  3. </section>
  4. <script >
  5. Vue.component('my-cmp',{
  6. template:`
  7. <slot></slot>
  8. `
  9. })
  10. const vm = new Vue({
  11. el:'#app',
  12. data(){
  13. return{
  14. }
  15. }
  16. })
  17. </script>

页面效果
image.png

后备内容

插槽默认使用子组件中 slot 元素中定义的值
当子组件中添加元素或文本,就是优先使用它们

编译作用域

  1. <section id="app">
  2. <my-cmp> {{ msg }} </my-cmp>
  3. </section>

如上代码,此处打印的值是父组件中的msg的值,还是子组件中的值
结果为打印父组件中的msg的值,
因为这个打印值得位置位于父组件的作用域中
如果想要打印子组件中的msg值如下代码

  1. Vue.component('my-cmp', {
  2. data(){
  3. return{
  4. msg:'my-cmp'
  5. }
  6. },
  7. template: `
  8. <div>
  9. <slot></slot>
  10. <div>{{this.msg}}</div>
  11. </div>
  12. `
  13. })

示例

  1. <section id="app">
  2. <my-cmp> {{ msg }} </my-cmp>
  3. </section>
  4. <script>
  5. Vue.component('my-cmp-children',{
  6. data(){
  7. return{
  8. msg:'my-cmp-children'
  9. }
  10. },
  11. template:`
  12. <div>
  13. <slot></slot>
  14. </div>
  15. `
  16. })
  17. Vue.component('my-cmp', {
  18. data(){
  19. return{
  20. msg:'my-cmp'
  21. }
  22. },
  23. template: `
  24. <div>
  25. <slot></slot>
  26. <my-cmp-children>{{ msg }}</my-cmp-children>
  27. </div>
  28. `
  29. })
  30. const vm = new Vue({
  31. el: '#app',
  32. data() {
  33. return{
  34. msg:'vm'
  35. }
  36. }
  37. })
  38. </script>

页面渲染效果
image.png

具名插槽

当我们需要多个插槽时,就像是每个人都有一个家,你不能把所有人都住一个家里
可是给 slot 起一个名字

  • name 属性:给slot可以起个名字
  • name属性:默认值是default

    1. <slot></slot> 等效于 <slot name="default"></slot>

    子组件中的元素与文本可以使用 v-slot:插槽名字 可简写为#插槽名字
    注意:v-slot只能用在 template组件 上 普通元素无法使用

    示例

    1. <section id="app">
    2. <my-cmp>
    3. <!-- 此处的插槽明使用的缩写 需要版本Vue 2.6.0以上-->
    4. <template #header>
    5. <p>这是头部</p>
    6. </template>
    7. <template #main>
    8. <p>这是main</p>
    9. </template>
    10. <p>这是default</p>
    11. </my-cmp>
    12. </section>
    13. <script>
    14. Vue.component('my-cmp', {
    15. template: `
    16. <div>
    17. <header>
    18. <slot name="header"></slot>
    19. </header>
    20. <main>
    21. <slot name="main"></slot>
    22. </main>
    23. <slot></slot>
    24. </div>
    25. `
    26. })
    27. const vm = new Vue({
    28. el: '#app',
    29. data: {
    30. }
    31. })
    32. </script>

    页面渲染效果
    image.png

    作用域插槽

    作用域插槽就是让插槽访问子组件的数据
    可以将数据绑定 slot 元素上
    插槽可通过 v-slot:插槽名="数据名" 获得数据对象
    注意:默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确

    示例

    1. <section id="app">
    2. <my-cmp v-slot:default="slotProps"> {{ slotProps.msg }} </my-cmp>
    3. <!-- default可不写,解构插槽Prop -->
    4. <my-cmp v-slot="{msg}"> {{ msg }} </my-cmp>
    5. <!-- 动态插槽名 []可以写动态数据 需要版本Vue 2.6.0以上 -->
    6. <my-cmp v-slot:[name]="{msg}"> {{ msg }} </my-cmp>
    7. </section>
    8. <script>
    9. Vue.component('my-cmp', {
    10. data(){
    11. return {
    12. msg:'This is the text !!! '
    13. }
    14. },
    15. template: `
    16. <div>
    17. <slot :msg="msg"></slot>
    18. </div>
    19. `
    20. })
    21. const vm = new Vue({
    22. el: '#app',
    23. data: {
    24. name:'default'
    25. }
    26. })
    27. </script>

    页面渲染效果
    image.png

    废弃了的语法

    带有slot特性的具名插槽

自 2.6.0 起被废弃

  1. <my-cmp>
  2. <template slot="header">
  3. <h1>头部</h1>
  4. </template>
  5. <template>
  6. <p>内容</p>
  7. <p>内容</p>
  8. </template>
  9. <template slot="footer">
  10. <p>底部</p>
  11. </template>
  12. </my-cmp>

带有slot-scope特性的作用域插槽

自 2.6.0 起被废弃

  1. <my-cmp>
  2. <template slot="default" slot-scope="slotProps">
  3. {{ slotProps.user.name }}
  4. </template>
  5. </my-cmp>