插槽语法是Vue 实现的内容分发 API,用于复合组件开发。该技术在通用组件库开发中有大量应用。
匿名插槽
// comp
<div><slot></slot> </div>
// parent <comp>hello</comp>
具名插槽
将内容分发到子组件指定位置
// comp2
<div>
<slot></slot>
<slot name="content"></slot>
</div>
// parent <Comp2>
<!-- 默认插槽用default做参数 -->
<template v-slot:default>具名插槽</template>
<!-- 具名插槽用插槽名做参数 -->
<template v-slot:content>内容...</template>
</Comp2>
作用域插槽
分发内容要用到子组件中的数据
// comp3
<div>
<slot :foo="foo"></slot>
</div>
// parent
<Comp3>
<!-- 把v-slot的值指定为作用域上下文对象 -->
<template v-slot:default="slotProps"> 来自子组件数据:{{slotProps.foo}} </template>
</Comp3>
插槽的应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<k-item label='userName:'>
<k-input type='text' readonly></k-input>
<template v-slot:error='{err:{isRed,name}}'>
<p>{{isRed}}</p>
<p>{{name}}</p>
</template>
</k-item>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('k-input', {
inheritAttrs: true,
template: `
<input/>
`
})
Vue.component('k-item', {
data() {
return {
err: {
isRed: true,
name: '父页面数据'
}
}
},
template: `
<div>
<label>{{$attrs.label}}</label>
<slot></slot>
<!--绑定数据 :err='err'否则v-slot:error='err' err获取不到数据-->
<slot name='error' :err='err'>
<!--默认数据:当插槽没有数据时显示默认数据,否则会被传进来当数据覆盖-->
{{err.name}}
</slot>
</div>
`,
})
new Vue({
el: '#app',
created () {
console.log(this.err);
},
})
</script>
</body>
</html>
其他用法:
具名插槽的缩写
2.6.0 新增
跟 v-on
和 v-bind
一样,v-slot
也有缩写,即把参数之前的所有内容 (v-slot:
) 替换为字符 #
。例如 v-slot:header
可以被重写为 #header
:
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
{{ user.firstName }}
</current-user>
如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
网友评论