zoukankan      html  css  js  c++  java
  • Vue 从入门到进阶之路(十一)

    之前的文章我们说了一下 vue 中组件的原生事件绑定,本章我们来所以下 vue 中的插槽使用。

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child title="<p>你好 世界</p>"></child>
    11 </div>
    12 <script>
    13     Vue.component("child", {
    14         props: ['title'],
    15         template: `
    16             <div>
    17                 {{title}}
    18                 <p>hello world</p>
    19             </div>
    20        `
    21     });
    22     var app = new Vue({
    23         el: '#app',
    24     })
    25 </script>
    26 </body>
    27 </html>

    上面的代码中,我们通过 title="" 形式通过父组件向子组件 child 传递了一个 "<p>你好世界</p>" 的带标签的内容,然后我们在子组件中输出,结果如下:

    显示结果是按字符串展示的,但我们想要的是不带标签的输出结果,在之前的文章中我们说过可以通过 v-html 来进行转义,代码如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child title="<p>你好 世界</p>"></child>
    11 </div>
    12 <script>
    13     Vue.component("child", {
    14         props: ['title'],
    15         template: `
    16             <div>
    17                 <div v-html="title"></div>
    18                 <p>hello world</p>
    19             </div>
    20        `
    21     });
    22     var app = new Vue({
    23         el: '#app',
    24     })
    25 </script>
    26 </body>
    27 </html>

    我们把 template 中的 {{title}} 改成了 v-html 的形式输出,结果如下:

    输出结果没问题,但是当我们看控制台的 HTML 代码时发现外层多加了一个 <div> 标签,这显然不友好,,这时可能有人会想到模板标签 <template v-html="title"> 这样写,但是这样的话在页面上是不会输出内容的。而且如果 <child> 标签内的 title 属性里面的内容并不只是一个 <p> 标签,还有很多其他的内容,例如 "<p>你好 世界<p><p>你好 世界<p><p>你好 世界<p><p>你好 世界<p><p>你好 世界<p><p>你好 世界<p>" 这么长的内容,在代码里也不好看。

    如何解决上面的问题,Vue 官方为我们提供插槽 slot,我们可以将代码改成如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child>
    11         <p>你好 世界</p>
    12     </child>
    13 </div>
    14 <script>
    15     Vue.component("child", {
    16         template: `
    17             <div>
    18                 <slot></slot>
    19                 <p>hello world</p>
    20             </div>
    21        `
    22     });
    23     var app = new Vue({
    24         el: '#app',
    25     })
    26 </script>
    27 </body>
    28 </html>

    我们将 p 标签想要输出的内容直接放在了 <child> 标签内,然后在 template 中添加标签 <slot>,意思就是将 <child> 内的内容通过 slot 插槽插入子组件,结果如下:

    完美解决了我们的问题,而且 <slot> 标签内还可以自定义我们想要输出的内容,如果 <child> 标签内没有内容的话以自定义的内容输出,如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child></child>
    11 </div>
    12 <script>
    13     Vue.component("child", {
    14         template: `
    15             <div>
    16                 <slot>插槽自定义内容</slot>
    17                 <p>hello world</p>
    18             </div>
    19        `
    20     });
    21     var app = new Vue({
    22         el: '#app',
    23     })
    24 </script>
    25 </body>
    26 </html>

    我们在 <child> 标签内没有内容,在 slot 标签内插入了一些内容,在页面显示如下:

    上面的 "插槽自定义内容" 在 <child> 内没有内容时输出,如果有内容则输出 <child> 标签内的内容。

    上面的插槽形式我们可以称之为无名插槽,还有一种插槽叫具名插槽,看以下代码:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child>
    11         <header>我是 header</header>
    12         <footer>我是 footer</footer>
    13     </child>
    14 </div>
    15 <script>
    16     Vue.component("child", {
    17         template: `
    18             <div>
    19                 <slot></slot>
    20                 <p>hello world</p>
    21                 <slot></slot>
    22             </div>
    23        `
    24     });
    25     var app = new Vue({
    26         el: '#app',
    27     })
    28 </script>
    29 </body>
    30 </html>

    我们想要一种效果,就是自定义插槽的内容位置,假设上的代码中 <header> 标签内的内容为头部信息,<footer> 标签内的内容为底部信息,我们想让它们分别输出在 template 模板中 p 标签的上下,结果如下:

    输出内容显然不是我们想要的结果,我们每用一次 <slot> 标签就会在页面输出一次,那该如何解决这个问题呢,我们可以使用具名插槽来为我们的插槽定义名称,如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>vue</title>
     6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     7 </head>
     8 <body>
     9 <div id="app">
    10     <child>
    11         <header slot="header">我是 header</header>
    12         <footer slot="footer">我是 footer</footer>
    13     </child>
    14 </div>
    15 <script>
    16     Vue.component("child", {
    17         template: `
    18             <div>
    19                 <slot name="header"></slot>
    20                 <p>hello world</p>
    21                 <slot name="footer"></slot>
    22             </div>
    23        `
    24     });
    25     var app = new Vue({
    26         el: '#app',
    27     })
    28 </script>
    29 </body>
    30 </html>

    在上面的代码中,我们分别为 <header> <footer> 标签添加 slot 属性,然后在 template 中的 <slot> 标签内以 name 属性来分别对应标签 <header> <footer> 内的 slot 属性值,这样就将指定的内容输出,结果如下:

    完美解决我们的问题。

  • 相关阅读:
    WPF xaml中列表依赖属性的定义
    查询英语单词
    WPF 界面如何绑定Command
    C# 获取当前屏幕的宽高和位置
    WPF 列表开启虚拟化的方式
    WPF MVVM UI分离之《交互与数据分离》
    WPF TextBlock IsTextTrimmed 判断文本是否超出
    局部变量表中Slot复用对垃圾回收的影响详解
    ArrayList中的Iterator详解
    oracle
  • 原文地址:https://www.cnblogs.com/weijiutao/p/10683465.html
Copyright © 2011-2022 走看看