之因此使用组件,就是由于组件能够将复杂的页面分割成多个部分,每一个 部分就是一个组件(也是一个vue文件)。要使用这个组件,只须要引入组件文件,并在模版中写入组件标签便可,引入了这个子组件,就至关于引入了这个组件的html模版,例如:html
// App.vue <template> <div id="app"> <Child /> </div> </template>
// Child组件 <template> <div id="child"> <h2>我是Child组件</h2> </div> </template>
渲染以后就是vue
<div id="app"> <div id="child"> <h2>我是Child组件</h2> </div> </div>
父组件想要插入数据到子组件中,无非就是将数据经过属性绑定的形式,而后子组件经过props接收。可是这种方法只能用来传递一些纯数据(字符串,对象和数组),没法传入一段html代码给子组件,slot就是为此而生的数组
在原html中,咱们常常在一个块级标签中插入n个标签,Vue中父组件给子组件插入标签也是这种写法app
// App.vue <template> <div id="app"> <Child> <!-- 在子组件中插入标签 --> <h2>我是插入的h2</h2> </Child> </div> </template>
父组件给子组件插入(传递)一段html标签,子组件须要一个位置进行接收,这个位置就是子组件的slot标签。slot标签的位置就是插入标签的位置code
// 子组件 <template> <div id="child"> <!-- slot标签将被插入的标签替代 --> <slot></slot> <h2>我是Hello组件</h2> </div> </template>
渲染结果:htm
<div id="app"> <div id="child"> <h2>我是插入的h2</h2> <h2>我是Child组件</h2> </div> </div>
这种插槽只有一个,被称为匿名插槽。对象
若是子组件有多个插槽,就须要为每一个插槽添加一个标识,即name属性,方便对号入座ip
<template> <div id="child"> <slot name="top"></slot> <h2>我是Child组件</h2> <slot name="bottom"></slot> </div> </template>
父组件插入标签时 经过设定slot属性,对比slot的name属性值,来关联对应的插槽作用域
<template> <div id="app"> <Child> <!-- 在子组件中插入标签 --> <h2 slot="top">我是插入的h2</h2> <h5 slot="bottom">我是插入的h5</h5> </Child> </div> </template>
渲染结果:字符串
<div id="app"> <div id="child"> <h2>我是插入的h2</h2> <h2>我是Child组件</h2> <h5>我是插入的h5</h5> </div> </div>
PS:插槽能够空着不用,父组件不插入标签元素,插槽就不会被渲染,利用这个特性能够控制子组件的某些空间是否展现对应的元素
插槽和props传参能够同时使用,二者不冲突
slot标签内能够写html代码,若是这个插槽没有被替换,会显示该插槽内的html内容,反之会被替换
<template> <div id="child"> <slot name="top"> <p>我是top插槽没使用的时候展现的内容</p> </slot> <h2>我是Child组件</h2> <slot name="bottom"></slot> </div> </template>
// App.vue <template> <div id="app"> <Child> <h5 slot="bottom">我是插入的h5</h5> </Child> </div> </template>
渲染结果:
<div id="app"> <div id="child"> <p>我是top插槽没使用的时候展现的内容</p> <h2>我是Child组件</h2> <h5>我是插入的h5</h5> </div> </div>
这个功能相似反向props,子组件经过属性绑定的形式,将相应的数据绑定到slot标签中,当父组件要插入标签来替换这个slot时,就能够读取这个绑定在slot标签中的数据
// 子组件 <template> <div id="child"> <!-- 在slot标签中2个数据 --> <slot name="top" :p1="p1" :p2="p2"> </slot> <h2>我是Hello组件</h2> <slot name="bottom"></slot> </div> </template> <script> export default { data () { return { p1: {name: '乔治',age: 4}, p2 :{name: '佩琪',age: 8} } } } </script>
父组件在替代slot的标签中添加 slot-scope属性,表示接受当前slot绑定的数据。slot-scope的值能够随意写,例如slot-scope="xxx"
由于slot标签上可能绑定了多个数据,因此vue将全部的数据都包裹在一个对象内,能够经过这个对象的属性名来访问对应的数据。
// App.vue <template> <div id="app"> <Hello> <template slot-scope="xxx" slot="top"> <p>{{xxx.p1.name}}</p> <p>{{xxx.p1.age}}岁</p> <p>{{xxx.p2.name}}</p> <p>{{xxx.p2.age}}岁</p> </template> <h5 slot="bottom">我是插入的h5</h5> </Hello> </div> </template>
xxx.p1.name => 乔治 xxx.p1.age => 4 xxx.p2.name => 佩琪 xxx.p2.age => 8