实习时做项目前端页面画了一多半,产品经理突然要求改变页面风格,如果现改有很大的风险会拖慢项目进度,我们项目组前端组长教我们使用具名插槽来直接套入原来模板,改变了整体风格,代码也不用很大变动,就去学习了一下插槽,总结如下(如有不足,还望指正):
插槽介绍
插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
关键字:slot
元素作为承载分发内容的出口,相当于一个占位符,将父组件中想要展示的内容在子组件中使用进行占位。
若一个组件中没有包含元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
怎么使用插槽?
下面看个栗子:
父组件:
<template>
<div>
我是父组件
<childrenOne>
<h1>我是父组件插槽内容</h1>
</childrenOne>
</div>
</template>
子组件:
<template>
<div class="childrenOne">
<div>我是childrenOne组件</div>
<slot></slot>
</div>
</template>
渲染结果是:
我是父组件
我是childrenOne组件
我是父组件插槽内容(h1大小的内容)
在父组件引用的子组件中也可以写入其他组件,一层套一层都是可以的。
插槽的后备内容
指一个插槽的默认内容,在父组件没有提供内容的时候被渲染,若提供内容则被取代。例如:子组件为
<button type="submit">
<slot>Submit</slot>
</button>
现在当在一个父级组件中使用 并且不提供任何插槽内容时:
<submit-button></submit-button>
后备内容“Submit”将会被渲染:
<button type="submit">
Submit
</button>
而要是提供插槽内容,则渲染提供的内容取代后备内容:
<submit-button> <button type="submit">
Save 渲染=> Save
</submit-button> </button>
具名插槽
用于 需要多个插槽的情况,用name属性区分,若< slot>没有name则被认为带有隐含名字default,再向具名插槽提供内容的时候,在< template>元素上使用v-slot指令,以v-slot参数形式提供名称。下面再举个栗子说下具名插槽的使用情况:
子组件 childrenTwo中定义了三个slot标签:
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
父组件中使用该子组件,插槽内容会根据name自动匹配渲染,没有用< template>包裹的内容则会匹配至无name属性的插槽中。无name属性也可给其增加一个值default的name属性。
<childrenTwo>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</childrenTwo>
具名插槽也可将v-slot指令缩写成#,像v-bind缩写为:一样。
作用域插槽
由于父级模板里的所有内容都是在父级作用域中编译的,子模板里的内容都是在子组件作用域中编译的,所以数据访问存在作用域问题,父组件不可以访问子组件的数据,为了让插槽内容能够访问子组件中才有的数据,将需要的特性绑定在插槽上——使用插槽prop。使用如下:
子组件
<template>
<div>
我是作用域插槽的子组件
<slot>{{user.name}}</slot>
</div>
</template>
<script>
name: 'slotthree',
data () {
return {
user: {name: 'Jack', sex: 'boy'}
}
}
</script>
父组件有如下代码,若想在父组件中渲染是不能生效的,因为只有 < slot-three> 组件可以访问到 user,但我们提供的内容是在父级渲染的。:
<slot-three>{{user.sex}}</slot-three>
所以要使用插槽prop,给子组件加上绑定内容就可以正常访问了。
子组件:
<template>
<div>
我是作用域插槽的子组件
<slot :user="user">{{user.name}}</slot>
</div>
</template>
<script>
name: 'slotthree',
data () {
return {
user: {name: 'Jack', sex: 'boy'}
}
}
</script>
父组件:现在在父级作用域中,我们也可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字,例如这里的default:
<template>
<div>
我是作用域插槽
<slot-three>
<template v-slot:default="slotProps">
{{slotProps.user.name}}
</template>
</slot-three>
</div>
</template>
渲染结果:
我是作用域插槽
Jack
当然这里所说的插槽prop是指Vue 2.6.0以后版本所使用的的语法,在此之前都是用slot 和 slot-scope语法,需要了解请访问:旧版slot语法
独占默认插槽的缩写语法
接下来讲一下独占默认插槽的缩写语法:
<slot-three>
<template v-slot:default="slotProps">
{{slotProps.user.name}}
</template>
</slot-three>
可以缩写为:
<slot-three>
<template v-slot="slotProps">
{{slotProps.user.name}}
</template>
</slot-three>
注意:这是一种缩写语法,只能使用于不具名插槽,和具名插槽混用会导致作用域不明确,多个插槽的使用请使用完整的< template>语法
今天的关于插槽分享就到这里,有问题欢迎指正!感谢观看~