vue重要知识点(插槽)

179 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,[携手创作,共同成长,8月更文活动奖品大升级!| 掘金·日新计划 - 掘金 (juejin.cn))

vue插槽

1、什么是插槽

插槽就是vue为组件封装者提供的,允许开发者在封装组件时把不确定的,有特殊要求的部分定义为插槽(),就相当于我们想要插入内容的占位符。

2、我们要清楚插槽使用的场景

在我们实际开发的过程中,插槽一般在设计组件的时候用到,当我们发现几个页面大部分结构相同,只有局部的地方不一样,那么就可以设计一个基础组件,不一样的地方就需要用到插槽。

3、插槽的几种类型(具体的使用方法,以及使用场景在下面会有详细介绍)

  1. 匿名插槽
  2. 具名插槽
  3. 作用域插槽

4、匿名插槽使用方式及其相关介绍

又名默认插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个默认插槽。

在这里我们创建一个组件,名字就叫Chid.vue,里面就是一个简单的a标签,进行页面的跳转。

<template>
    <div>
        <a :href="url">  //a标签的href属性里面的值是父组件传递过来的
            掘金
        </a>
    </div>
</template>
<script>
export default {
    props:['url']
}
</script>
<style scoped></style>

这里是我们的主页面,引入组件Chid,components进行注册然后就可以直接使用

<template>
    <div>
        <h1>插槽</h1>
        <Child url="https://juejin.cn/"></Child>
    </div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
    components:{
        Child
    },
    data() {
        return {
            
        }
    },
}
</script>

当然到这里页面功能是已经实现的,但是我们想要改变a标签里面的文字内容,这个有几种方式:1.直接改变组件里面的文字内容(这种方式是不优雅的,有违背创建组件的初衷) 2.就是在定义一个属性通过父组件传递文字内容(这种方式对简单的组件是可行的) 3. 就是通过插槽的方式去实现(今天主要介绍这一种)

如何实现:

在我们的组件a标签里面不直接写内容了,而是通过标签充当一个占位符的作用,接收父组件的值进行渲染

组件Chid.vue
<template>
    <div>
        <a :href="url">  //a标签的href属性里面的值是父组件传递过来的
            <slot></slot> //插槽的位置,在开始标签和结束标签之间
        </a>
    </div>
</template>
<script>
export default {
    props:['url']
}
</script>
<style scoped></style>
​
//主页面里面
<template>
    <div>
        <h1>插槽</h1>
        <Child url="https://juejin.cn/"> //这里在组件开始标签和结束标签之间写入插槽所需要的内容
            掘金
        </Child>
    </div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
    components:{
        Child
    },
    data() {
        return {
            
        }
    },
}
</script>

5、具名插槽使用方式及其相关介绍

具名插槽,即具有名字的插槽,在默认插槽基础上指定插槽的名字(name = " "),是通过标签里面name属性进行一一对应的,父组件指明放入子组件的哪个插槽,具体的看下面的代码示例

这是组件Chid
<template>
    <div>
        <slot name="title"></slot> //这个就是一个具名插槽,其中里面的name属性值就是对应父组件里面slot属性的
        <slot></slot> //这个没有name属性,就是匿名插槽,当然他也是去对应父组件里面对应的内容
        <slot name="content"></slot>
    </div>
</template>
<script>
export default {
    
}
</script>
<style scoped></style>
​
这是主页面---------------------------------------------------------------------------------
<template>
    <div>
        <Child>
            <div slot="title">  //这里slot="title"就对应组件里面name="title"
                <h2>我是一个大标题</h2>
            </div>
            <div>
                掘金沸点,一起摸鱼
            </div>
            <div slot="content">
                <p>我是文章的内容部分</p>
            </div>
            //当然我们这里需要注意在vue2.6.0+的版本里面写法是稍微有点不同
            <template v-slot:title> //用的是指令加上参数的方式来写,也不能直接写在div标签上,要写在template标签里面
                <h2>我是一个大标题</h2>
            </template>
        </Child>
    </div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
    components:{
        Child
    },
}
</script>

6、作用域插槽使用方式及其相关介绍

一句话来说明就是延伸了子组件的作用域,组件有编译作用域---父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的。

简单看个例子

定义一个子组件,

在这个子组件里面携带数据的是slot,子组件里面携带数据,父组件里面接受数据
<template>
    <div>
        <a :href="url">
            <slot :user="user"></slot> //:user="user"就是插槽所携带的数据
        </a>
    </div>
</template>
<script>
export default {
    props:['url'],
    data() {
        return {
            user:{
                name:'摸鱼吧',
                age:18
            }
        }
    },
}
</script>
<style scoped></style>

这是父组件里面的代码

在父组件中通过slot-scope来接受子组件提供参数

这是错误的示范:
<template>
    <div>
        <h1>插槽</h1>
        <Child url="https://juejin.cn/">
            以{{user.name}}的身份去访问链接   //这里注意在父组件里面直接调用子组件里面的数据是报错的
        </Child>
    </div>
//正确的方式应该是-----------------------------------------------------------------------------------
    <div>
        <h1>插槽</h1>
        <Child url="https://juejin.cn/">
            <template slot-scope="{ user }"> //这里使用了解构赋值,这样就可以正常的访问子组件里面的数据
                以{{user.name}}的身份去访问链接
            </template>
        </Child>
    </div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
    components:{
        Child
    },
    data() {
        return {
            name:'摸鱼者'
        }
    },
}
</script>

\