使用插槽分发内容
在封装vue组件的时候,不少时候就不得不使用到vue的一个内置组件<slot>。slot是插槽的意思,顾名思义,这个<slot>组件的意义是预留一个区域,让其中的DOM结构能够由调用它的组件来渲染。html
假设如今有一个people组件,结构以下:
<template> <div> <strong class="tip">*填写的内容必须真实</strong> <label>姓名</label><input type="text" name="name"> <label>性别</label><input type="text" name="sex"> <button>肯定</button> </div> </template>
当咱们注册这个组件以后,就能够在其余组件中这样子使用
<template> <div> <h3>用户信息</h3> <people> </people> </div> </template>
咱们都很清楚上面的代码最后渲染的样子。
<div> <h3>用户信息</h3> <div> <strong class="tip">*填写的内容必须真实</strong> <label>姓名</label><input type="text" name="name"> <label>性别</label><input type="text" name="sex"> <button>肯定</button> </div> </div>
通常来讲咱们这样子封装<people>组件是没有问题的了。可是有时候咱们在开发中,须要的组件还须要更抽象一点。咱们试想如下,假设咱们的<people>组件的功能是获取用户的信息,点击肯定上传到服务器。若是是按照上面的方式封装这个<people>组件,那么咱们每次调用这个组件就只能让用户输入姓名和性别。假设在另外的场景中,咱们还须要用户输入多一项年龄信息,那咱们的这个<people>组件就不能使用了,就还得须要另一个一个组件。<people2>。而事实上这个<people2>的组件功能逻辑彻底和<people>同样,只是多了一项年龄信息。在这种状况下,就至关于再写了一个重复的组件。那有没有办法可让咱们的<people>组件能够更通用点。这时候摆在咱们面前的问题就是,能不能在调用<people>的时候,能够指定<people>组件应该怎么渲染?<slot>组件就是为了解决这种问题而存在的。vue
咱们改变一下<people>的封装方式:
<template> <div> <strong class="tip">*填写的内容必须真实</strong> <slot>若是调用个人组件没有传入内容,那么就渲染<slot>里面的内容。</slot> </div> </template>
咱们在须要由父组件来渲染的部分使用<slot>插槽,至关于占位。这样咱们就能够在调用的时候,再指定这个<people>组件里面有什么内容:
<template> <div> <h3>用户信息</h3> <people> <label>姓名</label><input type="text" name="name"> <label>性别</label><input type="text" name="sex"> <button>肯定</button> </people> </div> </template> 渲染以后是: <div> <h3>用户信息</h3> <div> <strong class="tip">*填写的内容必须真实</strong> <label>姓名</label><input type="text" name="name"> <label>性别</label><input type="text" name="sex"> <button>肯定</button> </div> </div>
这样子咱们的<people>组件就更为通用了。而且当调用<people>的组件没有指定内容的时候,<peopel>组件里的<slot></slot>内容会渲染。以下图。这也是vue.js<slot>插槽最基本的用法。服务器
除非子组件模板包含至少一个 <slot> 插口,不然父组件的内容将会被丢弃。当子组件模板只有一个没有属性的插槽(匿名插槽)时,父组件传入的整个内容片断将插入到插槽所在的 DOM 位置,并替换掉插槽标签自己。ide
能够经过为<slot>插槽指定name(具名插槽)来指定渲染一个组件中多个插槽中的某一个。ui
<div> <slot name="slot1"></slot> <slot name="slot2"></slot> </div> 调用 <people> <div slot="slot1">slot1的内容</div> <div slot="slot2">slot2的内容</div> </people> 渲染的结果: <div> <div >slot1的内容</div> <div >slot2的内容</div> </div>
这种特殊的插槽能够暴露子组件中的内容,把数据交由父组件来渲染。看下面的例子:code
子组件<child> 的模板 <template> <div> <slot tip='子组件内部的tip'></slot> </div> </template> 父组件中调用: <div> <child> <template slot-scope='props'> <!--在这里可使用child组件暴露在slot中的数据--> <p>{{props.tip}}</p> </template> </child> </div> 渲染的结果为: <div> <div> <p>子组件内部的tip</p> </div> </div>