Vue中的插槽和具名插槽(vue 2.5已淘汰的语法和vue3.0支持语法对比)

目录

不用插槽slot的我们应该怎么做

vue的插槽slot基本用法了解

具名插槽

没有具名插槽出现的问题

具名插槽vue 2.5语法展示(已被官方废弃且不会出现在Vue 3中)

具名插槽vue 2.6+语法展示(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 #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语法写是一样的。

注意:就像v-on:可以缩写成@一样,v-slot:也可以缩写成#,所以v-slot:footer可以缩写成#footer

一个不带 name 的 <slot></slot>会带有隐含的名字name="default",父组件传的DOM内容如果不写这种v-slot:header具体告知说要找name="header"的插槽,则就会匹配到<slot></slot>不带name的插槽。

注意 v-slot 只能添加在 <template> 上 (只有一种例外情况)

 

文档见这里:具名插槽

 

 

关注、留言,我们一起学习。

 

===============Talk is cheap, show me the code================

 

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页