Vue插槽的使用

Posted eyes++

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue插槽的使用相关的知识,希望对你有一定的参考价值。

    在Vue中封装的一个组件如果内容是固定的话往往用处不大,比如需要10个搜索框,每个搜索框结构相似但又有不同,
    如果每个搜索框都单独去封装一个组件往往又不合适,因此封装组件时需要抽取共性,保留不同。
    最好的封装方法就是将共性抽取到组件中,将不同暴露为插槽,一旦预留了插槽,就可以让使用者根据自己需求决定插槽内容
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>

    <!-- 插槽的基本使用 -->
    <div id="app1">
        <cpn><button>按钮插槽</button></cpn>
        <cpn><p>p标签插槽</p></cpn>
        <cpn>
            <i>i标签插槽1</i>
            <i>i标签插槽2</i>
        </cpn>
        <cpn><input type="text" placeholder="输入框插槽"></cpn>
        <cpn></cpn>
    </div>

    <template id="cpn1">
        <div>
            <p>我是组件</p>
            <slot><button>默认插槽</button></slot>
        </div>
    </template>
    <script>
        const app1 = new Vue({
            el: '#app1',
            data: {
            },
            components: {
                cpn: {
                    template: '#cpn1'
                }
            }
        })
    </script><hr>

    <!-- 具名插槽 -->
    <div id="app2">
        <cpn>
            <p>替换无名插槽</p>
            <p slot="center">替换中间插槽</p>
            <button slot="top">替换顶部插槽</button>
        </cpn>
    </div>
    <template id="cpn2">
        <div>
            <slot name="top"><p>顶部</p></slot>
            <slot name="center"><p>中间</p></slot>
            <slot name="bottom"><p>底部</p></slot>
            <slot><p>无名</p></slot>
        </div>
    </template>
    <script>
        const app2 = new Vue({
            el: '#app2',
            data:{
            },
            components: {
                cpn: {
                    template: '#cpn2'
                }
            }
        })
    </script>
</body>
</html>

但这种方法使用还是有局限性的,开发时往往需要由父组件替换插槽标签,但内容由子组件提供,这时候就要用到作用域插槽了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
     <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>

    <!-- 编译的作用域 -->
    <div id="app">
        <cpn v-show="isShow"></cpn> <!--该变量在Vue实例中查找,结果为展示-->
    </div>
    <template id="cpn">
        <div>
            <p>我是子组件</p>
            <p>我是内容</p>
            <button v-show="isShow">按钮</button> <!--该变量在cpn模板中查找,结果为不展示-->
        </div>
    </template>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊',
                isShow: true
            },
            components: {
                cpn: {
                    template: '#cpn',
                    data() {
                        return {
                            isShow: false
                        }
                    }
                }
            }
        })
    </script><hr>

    <!-- 
        作用域插槽的使用
        作用域插槽是父组件替换插槽的标签,但内容由子组件来提供
        先提需求:
            1. 子组件中包括一组数据,比如:pLanguages:['JS','Py','Swift','Go','C++']
            2. 需要在多个界面进行展示:
                某些界面是以水平方向一一展示的
                某些界面是以列表形式展示的
                某些界面直接展示一个数组
            3.内容在子组件,希望父组件告诉我们如何展示,该怎么办?
    -->
    <div id="app2">
        <cpn></cpn> <!--竖着展示-->
        <cpn> <!--横着展示-->
            <!-- 目的是获取子组件里的pLanguages,Vue2.5.x以下要求一定要写template,其作用是拿到pLanguages -->
            <template slot-scope="slot"> <!--slot-scope拿到插槽对象-->
                <span>{{slot.data.join(' - ')}}</span>
            </template>
        </cpn>
    </div>
    <template id="cpn2">
        <div>
            <ul>
                <slot :data="pLanguages"> <!--data命名不作要求-->
                    <li v-for="item in pLanguages">{{item}}</li>
                </slot>
            </ul>
        </div>
    </template>
    <script>
        const app2 = new Vue({
            el: '#app2',
            data: {
            },
            components: {
                cpn: {
                    template: '#cpn2',
                    data() {
                        return {
                            pLanguages:['JS','Py','Swift','Go','C++']
                        }
                    },
                    created() {
                        this.pLanguages.join('-');
                    }
                }
            }
        })
    </script>
</body>
</html>

以上是关于Vue插槽的使用的主要内容,如果未能解决你的问题,请参考以下文章

vue.js-使用插槽分发内容的三个示例

vue----slot插槽

vue 插槽的使用

vue--slot插槽的使用方式

Vue.js 插槽 - 如何在计算属性中检索插槽内容

vue中插槽上手使用