Vue插槽
一、插槽是什么?
插槽就是子组件中的提供给父组件使用的一个占位符,用 <slot> </slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的 <slot> </slot>标签。
二、基础用法
1.问题:A组件在外部里面套B组件,B组件内的内容会被覆盖掉
解决:A组件内添加 <slot/> 插槽
2.问题2:A组件在外部套了多个模式(如 组件、HTML等),然后再A组件内加入插槽<slot>,一个插槽就可以显示刚刚套的所有模式,都能显现出来,怎样才能分别接收不同的结构?
解决:给插槽加 name ,一个插槽代表一个结构;外部每个结构外添加<template v-list: ‘name’>;
- 而内部没有名字的插槽用来接收剩余其他没有写v-slot的结构
- 当外部没有剩余结构时,可以在<slot>默认值</slot>添加默认值;也会在外部显现;
- v-slot重名时,后面的会覆盖前面的
- v-slot : default 时,就相当于内部没有名字的slot
- 注意 v-slot 只能写到template 上面;只有接收属性时,才能直接写在组件标签上
v-slot的简写形式为 :#
内部代码如下:
<div class="wrap">
<h1>wrap</h1>
<!-- ul -->
<slot name="list">
<h1>这是默认的list结构</h1>
</slot>
<hr/>
<!-- box -->
<slot name="box"/>
<hr/>
<!-- footer -->
<slot name="footer"/>
<hr/>
<slot>
<!-- 默认显示的值,当外部传入结构时,不作用 -->
<h1>这是slot的默认结构</h1>
</slot>
</div>
外部代码如下:
<Wrap>
<template v-slot:list>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
</template>
<template #box>
<Box/>
</template>
<template v-slot:footer>
<footer>
footer
</footer>
</template>
<template #default>
<h1>test</h1>
</template>
</Wrap>
3.组件作用域
组件标签在哪个vue文件中使用的,那么有用的到的数据就是这个vue文件的数据
4.作用域插槽
非父子组件得由$eventBus进行传值;用插槽的方式是:
如:组件A中的值想要传给组件B
- 组件A内部<slot :v-bind:list = “list”/>进行绑定传值到根组件
<template>
<div class="wrap">
<h1>wrap</h1>
<slot v-bind:data="value" v-bind:list="list"/>
</div>
</template>
<script>
export default {
data(){
return{
value:'wrap value',
list:[1,2,3,4]
}
},
}
</script>
- 根组件中进行接收显示
<template>
<div id="app">
<wrap v-slot:default="propsData">
<h1>{{propsData}}</h1>
</wrap>
</div>
</template>
亦或是这样写:先将组件wrap上的插槽去解构( {} 就是进行解构),结构出来的值再传进box
<!-- v-slot只能写在template标签上,只有需要接收属性时,v-slot才可以直接写在组件标签上 -->
<Wrap v-slot:default="{data}">
<Box :title="data"/>
</Wrap>
-组件A在根组件中去接收组件B的值
<box :title="propsData.data" />
3.访问某个组件的属性和方法 $parent & $children
- 组件B (box)想拿组件A(wrap)的属性值和方法;见代码
<template>
<div class="wrap" :style="{background:bgColor}">
<h1>wrap value:{{value}}</h1>
<slot/>
</div>
</template>
<script>
export default {
data(){
return {
value:'hello',
bgColor:'red'
}
},
methods:{
setBgColor(){
this.bgColor = "#ddd";
}
},
mounted(){
// console.log(this.$children);
}
}
</script>
//box组件
<template>
<div class="box">
<h2>box</h2>
<button @click="modifyAction">按钮</button>
</div>
</template>
<script>
export default {
mounted(){
console.log(this.$parent);
},
methods:{
modifyAction(){
this.$parent.value = 'hi';
this.$parent.setBgColor();
}
}
}
</script>
- 在根组件中访问子组件的属性和方法; 见代码:
<template>
<div id="app">
<Wrap ref="wrap">
</Wrap>
</div>
</template>
<script>
import Wrap from './components/Wrap'
export default {
components: {
Wrap,
},
mounted(){
console.log(this.$refs.wrap);
this.$refs.wrap.value = 'hi!'
this.$refs.wrap.setBgColor();
}
}
</script>