Vue插槽
-
作用:让父组件可以向子组件指定位置插入内容(可以是HTML结构,也可以是其他组件),这也是一种组件间通信的方式 -
分类:默认插槽、具名插槽、作用域插槽 -
理解:父组件中把子组件写成双标签形式,在双标签里面写上内容,在子组件定义插槽后就会将该内容插入到子组件的指定位置(所在的位置),至于样式,写在父组件或子组件里都可
- 样式写在父组件中:解析后的结构带着样式插入插槽
- 样式写在子组件中:解析后只把结构插入插槽,样式在子组件中控制
-
使用方式: 1. 默认插槽: 父组件中:
<Child> <!-- Child为子组件标签 -->
<div>html结构{{父组件中的数据}}</div>
</Child>
子组件中:
<template>
<div>
<!-- 定义插槽 父组件不传递结构时<slot></slot>中显示默认的内容-->
<slot>插槽默认内容...</slot>
</div>
</template>
复制代码 2. 具名插槽:(父组件数据给子组件) 父组件中:
<Child>
<!-- 写法1:slot='插槽名' 不推荐使用,好像2.6之后的版本被废弃了-->
<template slot-scope="center"> <!-- 如果写多个center也不会覆盖,都会被写到插槽里 -->
<div>html结构1{{父组件的数据直接使用}}</div>
</template>
<!-- 写法2: v-slot:插槽名 推荐使用-->
<template v-slot:footer> <!-- v-slot这种写法只能写在template里,是新的api -->
<div>html结构2{{父组件的数据直接使用}}</div>
</template>
<!--v-slot简写: #插槽名
template中的结构会放到子组件中<slot>的name属性为main的位置-->
<template #main> <!-- #插槽名是 v-slot:插槽名的简单写法 -->
<div>html结构2{{父组件的数据直接使用}}</div>
</template>
</Child>
子组件中:
<template>
<div>
<!-- 定义插槽 name属性区分不同的插槽-->
<slot name="center">插槽默认内容...</slot>
<slot name="footer">插槽默认内容...</slot>
<slot name="main">插槽默认内容...</slot>
</div>
</template>
复制代码 3. 作用域插槽:(子组件数据给父组件)
-
理解:数据在子组件自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Child组件中,但使用数据所遍历出来的结构由App组件决定)把子组件数据给父组件 -
语法: 注:slot-scope是旧api(不推荐使用),v-slot是最新的 父组件中:
<!-- 写法1: slot-scope='scope(这是随便取的名字)' 不推荐使用-->
<Child>
<template slot-scope="scope"> <!-- 或写成slot-scope="{games}解构形式也可以" -->
<!-- 生成的是ul列表 -->
<ul>
<li v-for="g in scope.games" :key="g">{{g}}</li>
</ul>
</template>
</Child>
<!-- 写法2: v-slot=scope 推荐使用-->
<Child>
<template v-slot="scope"> <!-- 或写成v-slot="{games}"解构形式也可以 -->
<h4 v-for="g in scope.games" :key="g">{{g}}</h4>
</template>
</Child>
子组件中:
<template>
<div>
<slot :games="games"></slot> <!--可以传多个值,用的时候scope.xxx就行-->
</div>
</template>
<script>
export default {
name:'Child',
//数据在子组件自身
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽']
}
},
}
</script>
复制代码
4.具名插槽和作用域插槽一起使用:
<!-- 子组件的插槽中: obj是要传递给父组件的值 name是该插槽的名字-->
<slot :obj="{a,b}" name="child">默认要显示的内容</slot>
<!-- 父组件child组件标签的template标签上: -->
<child>
<template v-slot:child="scope"> <!-- 这里如果直接写成v-slot='scope'则不会生效 页面不会展示数据!
<h2>{{ scope.obj }}</h2>
</template>
</child>
```
|