• 技术文章 >web前端 >Vue.js

    深入理解Vue中的插槽、内容分发、具名插槽

    青灯夜游青灯夜游2022-10-12 19:43:32转载230
    本篇文章给大家分享Vue进阶技巧,深入理解下Vue中的插槽、内容分发、具名插槽,希望对大家有所帮助。

    大前端零基础入门到就业:进入学习

    插槽 Slots简介

    Vue中组件的数据可以通过props进行传递,或者通过事件的方式进行获取传递,但当需要接收模板内容(任意合法的模板内容,代码片段、Vue组件)时,就需要使用插槽来实现了。当然也可以通过函数式编程间接实现;【相关推荐:vuejs视频教程

    1.png

    // 父元素传入插槽内容
    FancyButton('Click me!')
    
    // FancyButton 在自己的模板中渲染插槽内容
    function FancyButton(slotContent) {
        return `<button class="fancy-btn">
          ${slotContent}
        </button>`
    }

    slot-scope浅析

    常规的slot可以用于自定义组件的模板,但只是限制于固定的模板,无法自定义内部的具体的某一项,即常规的slot无法实现对组件循环体的每一项进行不同的内容分发,此时可以通过slot-scope进行实现,本质上和slot一样,不同点在于可以进行参数传递

    //普通的组件定义
    <ul>
        <li v-for="book in books" :key="book.id">
        {{ book.name }}
        </li>
    </ul>
    
    
    //slot-scope组件定义
    <ul>
        <li v-for="book in books" :key="book.id">
            <slot :book="book" name="bookInfo">
                <!-- 默认内容 -->
                {{ book.name }}
            </slot>
        </li>
    </ul>
    
    //父组件使用
    <book-list :books="books">
        <template slot-scope="slotProps" slot="bookInfo">
            <span v-if="slotProps.book.sale">限时优惠</span>
            {{ slotProps.book.name }}
        </template>
    </book-list>

    使用slot-scope时,当父组件使用该API,对应的插槽会替换模板中的slot进行展示

    常用API浅析

    具名插槽

    在组件中定义多个插槽出口可以兼容多个不同需求的兼容性,使得多个插槽内容传入到各自的插槽出口中;当插槽中配置了name属性时,此插槽就被称为具名插槽(named slots),没有提供name的插槽会隐式命名为「default」

    2.png

    <Com>
        <!-- 隐式的默认插槽 -->
        <!-- <p>A paragraph for the main content.</p>
        <p>And another one.</p> -->
        <template #default>
            <p>A paragraph for the main content.</p>
            <p>And another one.</p>
        </template>
        <template #footer>
            <p>Here's some contact info</p>
        </template>
    </Com>
    作用域插槽

    普通的插槽,是无法获取其他作用域下的数据的,即父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域
    但在某些情况下,插槽中的内容想要同时使用父组件和子组件内的数据,可以通过像组件传递数据props那样,让子组件在渲染时将一部分数据提供给插槽,这样在组件外部(父组件)中就可以使用子组件中的数据了-通过slot的方式

    子组件传入插槽的 props 作为了 v-slot 指令的值,可以在插槽内的表达式中访问,其中name是Vue特意保留的attribute,不会作为props进行传递

    //子组件
    <template> 
        <slot :shopInfo="shopInfo" :userInfo="userInfo"></slot> 
    </template>
    <cpm>
        <!-- 不显示 -->
        <div>555</div>
        <!-- 不显示 -->
        <div slot-scope="scope">
            <div>{{scope.name}}</div>
        </div>
        <!-- 显示 -->
        <div slot-scope="scope">
            <div>{{scope}}</div>
            <div>{{scope.name}}</div>
            <div>{{scope.age}}</div>
        </div>
    </cpm>
    // data: {
    //     shapes: [
    //         { name: 'Square', sides: 4 },
    //         { name: 'Hexagon', sides: 6 },
    //         { name: 'Triangle', sides: 3 }
    //     ],
    //     colors: [
    //         { name: 'Yellow', hex: '#F4D03F', },
    //         { name: 'Green', hex: '#229954' },
    //         { name: 'Purple', hex: '#9B59B6' }
    //     ]
    // }
    <my-list title="Shapes" :items="shapes">
        <template scope="shape">
            <div>{{ shape.name }} <small>({{ shape.sides }} sides)</small></div>
        </template>
    </my-list>
    <my-list title="Colors" :items="colors">
        <template scope="color">
            <div>
                <div class="swatch" :style="{ background: color.hex }"></div>
                {{ color.name }}
            </div>
        </template>
    </my-list>
    <div id="my-list">
        <div class="title">{{ title }}</div>
        <div class="list">
            <div v-for="scope in items">
                <slot v-bind="scope"></slot>
            </div>
        </div>
    </div>
    
    
    Vue.component('my-list', {
        template: '#my-list',
        props: [ 'title', 'items' ]
    });
    递归组件

    递归组件就是指组件在模板中调用自己,由于是组件自身调用,就不能像常规组件定义一样,可以省略组件的name配置,组件的递归需要依赖于自身的name配置(name还用于遍历组件的name选项来查找组件的实例);

    <template>
        <div>
            <my-component :count="count + 1" v-if="count
            <= 5"></my-component>
        </div>
    </template>
    <script>
    export default {
        name:'my-component',
        props: {
            count: {
                type: Number,
                default: 1
            }
        }
    }
    </script>
    动态组件

    有时候我们需要根据一些条件,动态的切换/选择某个组件,在函数式组件中,没有上下文的概念,常用于程序化的在多个组件中选择一个,可以间接的解决动态切换组件的需求,缺点是基于js对象进行开发,不方便开发;
    Vue官方提供了一个内置组件<component>和is的属性,用来解决上述的问题

    <component :is="component"></component>
    //component 就是js import进的组件实例,其值可以是标签名、组件名、直接绑定一个对象等

    拓展

    components的第二种写法

    常规的组件components是直接通过引用定义好的组件进行展示的,也可以直接在当前组件内定义,然后通过配置components进行渲染

    <div id="app">
        <cpn v-show="isShow"></cpn>
    </div>
    <template id="com">
        <div>
            <h2>Lbxin</h2>
            <p>class - 11</p>
        </div>
    </template>
    <script>
    var app = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        components: {
            cpn: {
                template: '#com',
                data() {
                    isShow: false
                }
            }
        }
    })
    </script>

    Web Component <slot> 简介

    HTML的slot元素,是Web Components技术套件的一部分,是Web组件内的一个占位符,该占位符可以在后期使用自己的标记语言进行填充,这样可以创建单独的DOM树,并将其与其他的组件组合在一起 -- MDN

    常见的填充Web组件的shadow DOM的模板有template和slot

    如常见的video标签,其内部的一些控制器和按钮等都是通过Shandow DOM进行维护的,开发者可以通过这个API进行自己独立的逻辑控制

    (学习视频分享:web前端开发编程基础视频

    以上就是深入理解Vue中的插槽、内容分发、具名插槽的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:Vue
    上一篇:手把手带你使用Vue实现一个图片水平瀑布流插件 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 手把手教你使用webpack实现vue-cli• Vue计算属性与侦听器和过滤器超详细介绍• 聊聊vue3中优雅使用 jsx/tsx 的方法• Vue中什么是修饰符?常见的修饰符总结• 手把手带你使用Vue实现一个图片水平瀑布流插件
    1/1

    PHP中文网