目录
具名插槽vue 2.5语法展示(已被官方废弃且不会出现在Vue 3中)
首先来看看插槽的使用场景
不用插槽slot的我们应该怎么做
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>具名插槽
</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child content="<p>lcylcy</p>"></child>
</div>
<script>
Vue.component('child', {
props:['content'],
template:`<div>
<p>hello</p>
<div v-html="this.content"></div>
</div>` // 换成ES6的语法可以换行方便查看
})
var vm = new Vue({
el: "#app",
})
</script>
</body>
</html>
运行结果
DOM结构多了一层div,这并不理想,有人想换成template模板占位符试试?
但是如果你换成如下,则无法渲染,DOM结构根本查看不到内容,页面上值会渲染hello,不会渲染出父组件传来的lcylcy
template:`<div>
<p>hello</p>
<template v-html="this.content"></template>
</div>` // 换成ES6的语法可以换行方便查看
如果父组件传的内容比较少,这种形式还可以接受,但是如果传的内容很多呢?
比如<child content="<p>lcylcy</p>"></child>变成了
<child content="<p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p><p>lcylcy</p>"></child>
这样代码就会很难阅读,有人可能会疑问我把这些标签放在<child><p>lcylcy</p>......</child>之中不就好了?其实这样也是渲染不出来的。
当子组件的内容是根据父组件传递过来的内容进行显示的时候,我们可以不用这种丑语法,vue提供了新的语法slot
vue的插槽slot基本用法了解
<slot>显示的内容就是父组件向子组件插入进来的标签内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽基本用法了解
</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child><h1>llllllllccccyyyy</h1></child>
</div>
<script>
Vue.component('child', {
props:['content'],
template:`<div>
<p>hello</p>
<slot>默认内容</slot>
</div>` // 换成ES6的语法可以换行方便查看
})
var vm = new Vue({
el: "#app"
})
</script>
</body>
</html>
运行结果
我们可以发现在<child></child>中的内容被放到<slot></slot>的位置了,如果父组件在子组件<child></child>里面不放东西,那么就会使用<slot></slot>标签的的默认内容,比如这里去掉<h1>llllllllccccyyyy</h1>,运行结果如下
文档见这里:插槽
具名插槽
没有具名插槽抛出的问题
有header部分、footer部分分别想插入到标签的上下方,结果却写出了如下代码,搞出意料之外的结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽基本用法了解
</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child>
<div class="header">header</div>
<div class="footer">footer</div>
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<slot></slot>
<p>hello</p>
<slot></slot>
</div>` // 换成ES6的语法可以换行方便查看
})
var vm = new Vue({
el: "#app"
})
</script>
</body>
</html>
运行结果
结果上面和下面分别加上了header和footer,哎,这根本不是我们想要的,能不能具体对应上呢?这个是可以的。
具名插槽vue 2.5语法展示(已被官方废弃且不会出现在Vue 3中)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>具名插槽vue2.5以前的使用
</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child>
<div class="header" slot="header">header</div><!-- 向具名插槽提供内容,放到名字是header的插槽 -->
<div class="footer" slot="footer">footer</div><!-- 向具名插槽提供内容,放到名字是footer的插槽 -->
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<slot name="header"></slot>
<p>hello</p>
<slot name=footer></slot>
</div>` // 换成ES6的语法可以换行方便查看
})
var vm = new Vue({
el: "#app"
})
</script>
</body>
</html>
运行结果
子组件的<slot name="xxx">表示接受父组件传来的带有slot="xxx"的DOM内容,这样就能对应上
这样可以一次性能够传递多个区域的DOM结构的内容,子组件可以用具名插槽分别使用对应区域的DOM结构的内容
同样的,具名插槽也有默认值,和之前演示的例子一样,slot写着就会有用,要么显示匹配的值,匹配不上的内容就使用插槽的默认值。
文档见这里:废弃的具名插槽slot语法
具名插槽vue 2.6+语法展示(Vue 3支持)
自 2.6.0 起具名插槽有所更新,上面那一种方式在所有的 2.x 版本中 slot
仍会被支持,但已经被官方废弃且不会出现在 Vue 3 中。
那我们就把上面的例子用2.6.0的新语法写一次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽基本用法了解
</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child>
<template v-slot:header><!-- 注意和废弃语法slot="header"对比 -->
<div class="header">header</div><!-- v-slot不能直接写在标签上,必须写在template,否则渲染不出来 -->
</template>
<template v-slot:footer><!-- 注意和废弃语法slot="footer"对比 -->
<div class="footer">footer</div><!-- v-slot不能直接写在标签上,必须写在template,否则渲染不出来 -->
</template>
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<slot name="header"></slot>
<p>hello</p>
<slot name=footer></slot>
</div>` // 换成ES6的语法可以换行方便查看
})
var vm = new Vue({
el: "#app"
})
</script>
</body>
</html>
运行结果是和上面用2.5语法写是一样的。
一个不带 name
的 <slot></slot>会带有隐含的名字name="default",父组件传的DOM内容如果不写这种v-slot:header具体告知说要找name="header"的插槽,则就会匹配到<slot></slot>不带name的插槽。
注意 v-slot
只能添加在 <template>
上 (只有一种例外情况)
文档见这里:具名插槽
关注、留言,我们一起学习。
===============Talk is cheap, show me the code================