• Vue插槽


    1、编译作用域:

          官方的解释是父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译

        例如:

             Son.vue

    1. <template>
    2. <div>
    3. <h2>子组件</h2>
    4. <p>西安邮电大学</p>
    5. </div>
    6. </template>
    7. <script>
    8. export default {
    9. name: "Son",
    10. data(){
    11. return {
    12. isShow : true
    13. }
    14. }
    15. }
    16. </script>

                Father.vue

    1. <template>
    2. <div>
    3. <son v-show="isShow"></son>
    4. </div>
    5. </template>
    6. <script>
    7. import Son from "@/components/Son";
    8. export default {
    9. name: "Father",
    10. data(){
    11. return {
    12. isShow: true
    13. }
    14. },
    15. components: {Son}
    16. }
    17. </script>

           最终的结果是:父组件中的isShow为true,子组件的内容会显示;这是因为:使用的时候,子组件的使用过程是在父组件中出现的,作用域就是父组件,使用的属性也是属于父组件的属性。因此,isShow使用的父组件中的属性,而不是子组件的属性。

    2、什么是插槽(slot)?

          插槽(slot)将父组件的内容与子组件的模板相混合,从而弥补了视图的不足。如果父组件没有插入内容,那么 slot 的内容就作为默认出现;若父组件插入了内容,则 slot 的内容将被插入的内容替换掉。

    3、为什么要使用插槽slot

          插槽的目的在于使组件更具有扩展性例如,电脑预留的usb接口,可以用来连接多种外部设备,耳机、音响、U盘等等,使得更具有扩展性。插槽slot的作用正是如此,例如,组件中的一个地方,默认情况下为button,而在使用的时候,有需求需扩展为span,扩展为input,这时候就需要使用到插槽。

          组件的封装方式(抽取共性,保留不同):就是将共性抽取到组件中,将不同暴露为插槽。一旦预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。是搜索框,还是文字,还是菜单。由调用者自己来决定。

    4、插槽的使用

         (1)匿名插槽(默认插槽):<slot></slot>,有且只有一个

         Son.vue

    1. <template>
    2. <div>
    3. <h2>子组件</h2>
    4. <p>西安邮电大学</p>
    5. <slot></slot> <!-- 插槽 -->
    6. </div>
    7. </template>
    8. <script>
    9. export default {
    10. name: "Son"
    11. }
    12. </script>

             Father.vue

    1. <template>
    2. <div>
    3. <son>
    4. <button>演示按钮</button> <!-- 放在插槽位置 -->
    5. </son>
    6. <son></son>
    7. </div>
    8. </template>
    9. <script>
    10. import Son from "@/components/Son";
    11. export default {
    12. name: "Father",
    13. components: {Son}
    14. }
    15. </script>

             (2)具名插槽

               当子组件的功能复杂时,子组件的插槽可能并非是一个。比如封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?这时候,就需要给slot指定一个name属性,也就是具名插槽。

               Son.vue

    1. <template>
    2. <div>
    3. <slot name="top"></slot><!-- 插槽 -->
    4. <h2>子组件</h2>
    5. <slot name="center"></slot><!-- 插槽 -->
    6. <p>西安邮电大学</p>
    7. <slot name="bottom"></slot><!-- 插槽 -->
    8. </div>
    9. </template>
    10. <script>
    11. export default {
    12. name: "Son"
    13. }
    14. </script>

               Father.vue

    1. <template>
    2. <son>
    3. <template v-slot:top>
    4. <button>插槽演示</button>
    5. </template>
    6. <template v-slot:center>
    7. <input type="text"/>
    8. </template>
    9. <template #bottom> <!--具名插槽的简写-->
    10. <p>Vue3中插槽</p>
    11. </template>
    12. <template v-slot:default> <!--默认插槽-->
    13. <select>
    14. <option>A</option>
    15. <option>B</option>
    16. <option>C</option>
    17. </select>
    18. </template>
    19. </son>
    20. </template>
    21. <script>
    22. import Son from "@/components/Son";
    23. export default {
    24. name: "Father",
    25. components: {Son}
    26. }
    27. </script>

              

    (3)作用域插槽

        父组件在使用的时候可以替换slot插槽中的显示页面结构,但展示的数据还是来源于子组件。

        例如:有一个需求,子组件中包括一组数据,比如:Languages: [‘JavaScript’, ‘Python’, ‘Swift’, ‘Go’, ‘C++’]

    需要在多个界面进行展示:

             A、某些界面以水平方向展示

             B、某些界面以列表方式展示

        Son.vue

    1. <template>
    2. <div>
    3. <h2>子组件</h2>
    4. <p>西安邮电大学</p>
    5. <slot :language="languageList"></slot>
    6. </div>
    7. </template>
    8. <script>
    9. export default {
    10. name: "Son",
    11. data(){
    12. return {
    13. languageList:['JavaScript','Python','Swift','Go','C++']
    14. }
    15. }
    16. }
    17. </script>

            Father.vue

    1. <template>
    2. <div>
    3. <!--展示结构1:水平方向展示-->
    4. <son>
    5. <template slot-scope="slotProps">
    6. <h2>{{ slotProps.language.join('--')}}</h2>
    7. </template>
    8. </son>
    9. <!--展示结构2:列表形式展示-->
    10. <son>
    11. <template slot-scope="slotProps">
    12. <ul>
    13. <li v-for="(item,index) in slotProps.language" :key="index">{{ item }}</li>
    14. </ul>
    15. </template>
    16. </son>
    17. </div>
    18. </template>
    19. <script>
    20. import Son from "@/components/Son";
    21. export default {
    22. name: "Father",
    23. components: {Son}
    24. }
    25. </script>

    5、v-slot指令

         在 Vue2.6.0 中,为插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在使用的特性

        (1)匿名插槽(默认插槽default)中使用v-slot指令

          Son.vue

    1. <template>
    2. <div>
    3. <h2>子组件</h2>
    4. <p>西安邮电大学</p>
    5. <slot></slot>
    6. </div>
    7. </template>
    8. <script>
    9. export default {
    10. name: "Son"
    11. }
    12. </script>

           Father.vue

    1. <template>
    2. <div>
    3. <son>
    4. <template v-slot:default>
    5. <button>匿名插槽演示</button>
    6. </template>
    7. </son>
    8. </div>
    9. </template>
    10. <script>
    11. import Son from "@/components/Son";
    12. export default {
    13. name: "Father",
    14. components: {Son}
    15. }
    16. </script>

        (2)具名插槽中使用v-slot指令

            Son.vue

    1. <template>
    2. <div>
    3. <slot name="top"></slot>
    4. <h2>子组件</h2>
    5. <slot name="center"></slot>
    6. <p>西安邮电大学</p>
    7. <slot name="bottom"></slot>
    8. </div>
    9. </template>
    10. <script>
    11. export default {
    12. name: "Son"
    13. }
    14. </script>

            Father.vue

    1. <template>
    2. <div>
    3. <son>
    4. <template v-slot:center>
    5. <button>具名插槽演示</button>
    6. </template>
    7. </son>
    8. </div>
    9. </template>
    10. <script>
    11. import Son from "@/components/Son";
    12. export default {
    13. name: "Father",
    14. components: {Son}
    15. }
    16. </script>

            (3)作用域插槽中使用v-slot指令

                Son.vue

    1. <template>
    2. <div>
    3. <h2>子组件</h2>
    4. <p>西安邮电大学</p>
    5. <slot :language="languageList" name="xy"></slot>
    6. <slot :language="languageList" name="zf"></slot>
    7. </div>
    8. </template>
    9. <script>
    10. export default {
    11. name: "Son",
    12. data(){
    13. return {
    14. languageList:['JavaScript','Python','Swift','Go','C++']
    15. }
    16. }
    17. }
    18. </script>

              Father.vue

    1. <template>
    2. <div>
    3. <!--展示结构1:水平方向展示-->
    4. <son>
    5. <template v-slot:zf="slotProps">
    6. <h2>{{ slotProps.language.join('--')}}</h2>
    7. </template>
    8. </son>
    9. <!--展示结构2:列表形式展示-->
    10. <son>
    11. <template v-slot:xy="slotProps">
    12. <ul>
    13. <li v-for="(item,index) in slotProps.language" :key="index">{{ item }}</li>
    14. </ul>
    15. </template>
    16. </son>
    17. </div>
    18. </template>
    19. <script>
    20. import Son from "@/components/Son";
    21. export default {
    22. name: "Father",
    23. components: {Son}
    24. }
    25. </script>

  • 相关阅读:
    加密市场“至暗时刻”已经过去,Zebec迎来上涨主升浪
    【我是学生,可以送我么】搭建树莓派4bJTAG调试平台jlink平替版
    【错误记录】Android 编译报错 ( The project uses Gradle version which is incompatible with Android Studio )
    Linux--线程(与进程区别)
    Vue_Bug VUE-ADMIN-TEMPLATE-MASTER electron build后无法登录
    运算符与表达式
    MQ常见的问题(kafka保证消息不丢失)
    linux内核获取本机网卡的统计信息
    Go 开发环境安装之Goland和vscode
    Vatee万腾科技创新之路:Vatee的智能时代掌舵人
  • 原文地址:https://blog.csdn.net/m0_37911706/article/details/125492183