vue-插槽(slot)
0.什么是插槽
插槽(slot)的出现主要是为了父组件向子组件中加入内容。类似一个占位符,我们常说的“一个萝卜一个坑”,slot就是那个坑,在子组件中给你挖好了坑,然后在通过父组件来填坑。
1.默认插槽
我们创建一个vue项目。App.vue作为父组件参考如下:
<template>
<div id="app">
<div>我是父组件APP</div>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
子组件HelloWorld组件,一开始没有引入插槽,参考如下:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
效果图如下:
我们在子组件中加入slot标签:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<!-- 引入插槽 -->
<slot></slot>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
此时刷新页面发现没有效果,因为我们只是挖好了坑,还没有填充内容。我们在父组件中引入子组件时填充内容:
<template>
<div id="app">
<div>我是父组件APP</div>
<HelloWorld msg="Welcome to Your Vue.js App">
<h5>我是在父组件,填充子组件内容</h5>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
效果如下:
这就是基础用法。
2.具名插槽
什么是具名插槽,其实就是给slot起个名字,在父组件调用时,根据名字对应插入信息。
我们在子组件中定义两个具名插槽。
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<!-- 引入插槽 -->
<slot name="type1"></slot>
<slot name="type2"></slot>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
然后在父组件中分别使用具名插槽:
<template>
<div id="app">
<div>我是父组件APP</div>
<HelloWorld msg="Welcome to Your Vue.js App">
<template slot="type1">
<p>type1</p>
</template>
<template slot="type2">
<p>type2</p>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
效果如下:
上面也可以写成下面这种形式:
<template v-slot:type1>
<p>type1</p>
</template>
3.作用域插槽
作用域插槽就是在父组件调用子组件时,由父组件决定显示的具体内容。
我们修改子组件内容:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<slot :obj="info">{{info}}</slot>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
info: "默认信息"
}
}
}
</script>
然后父组件直接使用插槽的话就会显示子组件的默认内容:
<template>
<div id="app">
<div>我是父组件APP</div>
<HelloWorld msg="Welcome to Your Vue.js App">
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
效果:
我们修改子组件:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<slot name='type1' :value1="info1">{{info1}}</slot>
<br>
<slot :value2="info2">{{info2}}</slot>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
info1: "默认信息1",
info2: "默认信息2"
}
}
}
</script>
第一个插槽我们起名了,叫type1,第二个插槽没有没名字,这样就站好了两个坑。
然后我们在父组件里直接填充数据:
<template>
<div id="app">
<div>我是父组件APP</div>
<HelloWorld msg="Welcome to Your Vue.js App">
<!-- 有名字的 -->
<template v-slot:type1>
修改信息1
</template>
<!-- 没有名字默认 -->
<template>
修改信息2
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
效果:
可以看到,填充了数据。
4.简单总结
作用域插槽实际开发用的可能多一些,一般都是初始加载时显示子组件一个默认页面,等待后台数据返回后再填充数据到子组件中。