1、什么是插槽
Vue 实现了一套内容分发的 API,什么是内容分发?
看例子 =>eg:
一个父组件引用一个子组件
<!-- 父组件 -->
<template>
<div id="app">
<HelloWorld >
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<!-- 子组件 -->
<template>
<div class="hello">
<h1>i am helloworld component</h1>
</div>
</template>
显示结果:
然后你会发现,你使用的这个子组件<Helloworld></HelloWorld>也是一个双标签,能不能在里面放点东西,会不会显示?然后你就要使用插槽来进行内容分发
<!-- 父组件 -->
<template>
<div id="app">
<HelloWorld >
<!-- 这里加了一行文字 -->
我加了一个行文字可以显示吗
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<!-- 子组件 -->
<template>
<div class="hello">
<h1>i am helloworld component</h1>
<!-- 加个个默认插槽 -->
<!-- 如果不在子组件加上插槽,那么调用子组件时候在双标签里面写什么用没用 -->
<slot></slot>
</div>
</template>
再看一下结果:这样你写的那行文字就会出现,
2、为什么要用插槽,什么情况下要用插槽
用插槽,就是为了内容分发,这种情况其实很常见,我们需要在的调用的子组件里面添加一些内容,但是我们又不希望内容写死在子组件里面,通过使用插槽,我们就可以像正常使用普通的标签<div></div>这样往里面放东西并且可以显示出来。
3、插槽的用法
(1)普通插槽
普通插槽就是子组件里面放置一个<slot></slot>标签即可,在父组件调用子组件双标签时候里面写什么都会被放进子组件的slot显示出来,可以参考标题1里面的例子使用
(2)具名插槽:用template标签和slot属性的属性值和子组件的slot标签的name属性对应
通过例子说明 => eg:
<!-- 父组件-->
<template>
<div id="app">
<HelloWorld >
<!-- 父组件的slot属性的red就对应子组件的name也是red的slot标签 -->
<!-- 如果都没有对应,那就放去默认插槽里面,如果没有默认插槽则内容不会分发,就不会出现-->
<template slot="red">
我这里对应红色的插槽
</template>
<template slot="blue">
我是对应蓝色的插槽
</template>
我是默认插槽
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<!-- 子组件-->
<template>
<div class="hello">
<h1>i am helloworld component</h1>
<slot name="red">
</slot>
<div style="width:100%;height:10px;background:red"></div>
<slot name="blue"></slot>
<div style="width:100%;height:10px;background:blue"></div>
<slot></slot>
</div>
</template>
(3)作用域插槽 =>作用域插槽很好的作用就是可以让父组件很简单的获取到子组件的数据
情况一:只使用默认插槽
<!-- 父组件 -->
<template>
<div id="app">
<!--当子组件的插槽只是默认插槽时候,可以在组件直接给属性 v-slot:default=“”
v-slot是固定,
default是对应插槽的name属性值,就是具名插槽,默认时候就直接给个default
“”双引号的名字随便填写,是给自己使用的
-->
<HelloWorld v-slot:default="test">
{{test}}
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<!-- 子组件 -->
<template>
<div class="hello">
<!-- 属性名=“属性值” -->
<!-- 上面的test获取的就是一个完整的key-val对象 -->
<slot sonObj="我是子组件"></slot>
</div>
</template>
<script>
结果:
情况二:如果用的是具名插槽,那么在父组件v-slot就不可以直接写在引用的子组件那里,如下
<template>
<div id="app">
<!-- 就不可以写在hellworld这个标签的属性里面了 -->
<HelloWorld v-slot:default="test">
{{test}}
</HelloWorld>
</div>
</template>
那么应该怎么写,应该基于<template>来写上属性,如下例子 => eg:
<!--父组件 -->
<template>
<div id="app">
<HelloWorld>
<!--这里就要把slot写在template里面了 v-slot冒号后面最好都写,默认的插槽最好就写上defult,也便于用了多个插槽不会因为没写而导致作用域错乱 -->
<template v-slot:one="one">
{{one}}
</template>
<template v-slot:two="two">
{{two}}
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
}
}
</script>
<!--子组件 -->
<template>
<div class="hello">
<!-- 这就是具名插槽 -->
<slot name="one" v-bind:duixiang="arrOne"></slot>
<slot name="two" v-bind:color="arrTwo"></slot>
</div>
</template>
<script>
export default {
data() {
return {
arrOne: ["red", "blue", "purple", "pink"],
arrTwo: ["joe", "cindy", "mike", "judy"]
};
}
};
</script>
结果如下: