5-组件化高级

一、插槽 slot

为什么使用 slot

slot 翻译为插槽,插槽的目的是让我们原来的设备具备更多的扩展性;

组件的插槽,也是为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么;


1、slot插槽的基本使用

在子组件中,使用特殊的元素 <slot> 就可以为子组件开启一个插槽,该插槽插入什么内容取决于父组件如何使用;

<body>
<div id="app">
  <!--使用默认值-->
  <cpn></cpn>
  <!--替换默认值-->
  <cpn><p>p标签</p></cpn>
  <!--多个值-->
  <cpn>
    <div>
      <h4>Vue</h4>
      <p>slot插槽</p>
    </div>
  </cpn>
</div>

<template id="cpn">
  <div>
    <h3>组件标题</h3>
    <p>组件内容</p>

    <!--插槽, button是插槽中的默认值-->
    <slot><button>按钮</button></slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
 const app = new Vue({
   el: '#app',
   data: {
   },
   components: {
     cpn: {
       template: '#cpn'
     }
   }
 })
</script>
</body>
代码


2、具名插槽

当子组件的功能复杂时,子组件的插槽可能并非是一个,比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边,

那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?这个时候,我们就需要给插槽起一个名字,这就是具名插槽;

具名插槽的使用很简单,只要给 slot 元素一个 name 属性即可:<slot name='myslot'></slot>


<body>
<div id="app">
  <!--默认-->
  <cpn></cpn>
  <!--替换后-->
  <cpn><span slot="left">标题</span></cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"><span>左边</span></slot>
    <slot name="center"><span>中间</span></slot>
    <slot name="right"><span>右边</span></slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {},
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>
</body>
代码

image


3、编译作用域

父组件模板的所有东西,都会在父级作用域内编译

子组件模板的所有东西,都会在子级作用域内编译


<body>
<div id="app">
  <!--这里isShow为true,模板里的内容可以显示-->
  <cpn v-show="isShow"></cpn>
</div>

<template id="cpn">
  <div>
    <h4>子组件</h4>
    <!--这里的isShow为false,按钮不会显示-->
    <button v-show="isShow">按钮</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      isShow: true
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            isShow: false
          }
        }
      }
    }
  })
</script>
</body>
代码


4、作用域插槽

作用域插槽是 slot 一个比较难理解的点,一句话总结就是:

父组件替换插槽的标签,但是内容由子组件来提供;


<body>
<div id="app">
  <!--默认显示-->
  <cpn></cpn>

  <!--要求:中间用‘-’连接显示,使用作用域插槽slot-scope,拿到子组件中的数据-->
  <cpn>
    <template slot-scope="slot">
      <span>{{slot.data.join(' - ')}}</span>  <!--这里的data就是下面模板里自定义的data-->
    </template>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot :data="pLanguage">  <!--此处的'data'可以自己定义-->
      <ul>
        <li v-for="item in pLanguage">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {},
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            pLanguage: ['Java', 'Scala', 'Python', 'Go']
          }
        }
      }
    }
  })
</script>
</body>
代码

image

posted @ 2020-09-10 17:16  米兰的小铁將  阅读(177)  评论(0编辑  收藏  举报