vue.js中使用slot
- 什么是组件?
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。 - slot: 组件里面通过插槽分发内容
简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的活
- 默认情况下,父组件在子组件内套的内容,是不显示的。
- 单个slot的使用: 如果要在定义好的组件内部,加上一段html或者文本,可以使用slot将,插入的html代码,在模板中slot位置显示。
父组件
<div id="test">
<test-slot>
<h3>{{name}}</h3>
<p>Something bad happened.</p>
</test-slot>
</div>
子组件
Vue.component("test-slot",{
// 插槽允许有默认内容
template:
`<div>
<strong>Error!</strong>
<slot></slot>
</div>
`,
data:function () {
return {
name:"perry"
}
}
});
new Vue({
el:"#test"
data:{name:"500 error"}
});
结果:
<div>
<strong>Error!</strong>
<h3>500 error</h3>
<p>Something bad happened.</p>
</div>
- 具名slot: 具名插槽比较有意思,在模板制定时非常好用,比如我们要写一个模板包含头尾和内容部分,希望在模板中定义好一部分公共的东西. 具名slot通过name来管理多个slot的解析,其中没有name的slot会被归为default slot放到没有name的节点下面,default slot会无视散落在不同地方的html的位置,都将放到default slot的模板位置中来.
步骤:
将放在子组件里的不同html标签放在不同的位置
父组件在要分发的标签里添加 slot=”name名” 属性
子组件在对应分发的位置的slot标签里,添加name=”name名” 属性,
然后就会将对应的标签放在对应的位置了
Vue.component("slot-name",{
template:
`<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot ></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
});
<slot-name>
<h3>开始</h3>
<p>Default slot内容1</p>
<template slot="header">
<ul>
<li>主页</li>
<li>分诊</li>
<li>护理</li>
<li>病历</li>
</ul>
</template>
<template slot="footer">
<p>结尾</p>
</template>
</slot-name>
运行结果:
- 作用域slot:
例子一:
<children-name>
<span slot="first" @click="tobeknow">12345</span>
<span slot="second">56789</span>
</children-name>
Vue.component('children-name', {
data: function () {
return {
}
},
template: `<button><slot name='first'></slot>为了明确作用范围,<slot name='second'></slot>所以使用button标签</button>`
})
methods下:
tobeknow() {
console.log(11111) //只有点击12345这个区域才会触发事件,其余部分不会触发。
}
例子2:使用slot-scope=‘props’ (用来子组件向父组件传递数据)
作用域插槽必须是template开头和结尾的一个内容,slot-scope是声明要接收的子组件参数都放在哪,放在props里面
所以当子组件做循环,她的某一部分dom结构应该由外部传递进来的时候,使用作用域插槽,使用作用域插槽,子组件可以像父组件插槽传递数据
<div id='root'>
<child>
<template slot-scope='props'>
<h1>{{props.item}}</h1>
</template>
</child>
</div>
<script>
Vue.component('child',{
data:function(){
return {
list:[1,2,3,4,5]
}
},
template:`<div>
<slot v-for='item of list' :item=item></slot>
</div>`
})
var vm = new Vue({
el:'#root'
})
</script>
结论:父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译