Vue 进阶系列丨插槽

662723b01e1ebbdc9451d32e1dde4f22.png

Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!


2013年7月28日,尤雨溪第一次在 GItHub 上为 Vue.js 提交代码;2015年10月26日,Vue.js 1.0.0版本发布;2016年10月1日,Vue.js 2.0发布。

最早的 Vue.js 只做视图层,没有路由, 没有状态管理,也没有官方的构建工具,只有一个库,放到网页里就可以直接用了。

后来,Vue.js 慢慢开始加入了一些官方的辅助工具,比如路由(Router)、状态管理方案(Vuex)和构建工具(Vue-cli)等。此时,Vue.js 的定位是:The Progressive Framework。翻译成中文,就是渐进式框架。

Vue.js2.0 引入了很多特性,比如虚拟 DOM,支持 JSX 和 TypeScript,支持流式服务端渲染,提供了跨平台的能力等。Vue.js 在国内的用户有阿里巴巴、百度、腾讯、新浪、网易、滴滴出行、360、美团等等。

Vue 已是一名前端工程师必备的技能,现在就让我们开始深入学习 Vue.js 内部的核心技术原理吧!


什么是插槽

先举个生活中的小例子,生活中电源插座大家肯定不陌生,每个插座上面都有很多个电源插口,我们可以将很多电器都连接到插座上,当然,插座上也可能只有一个插口。

在 Vue.js 中,插座就相当于一个组件,插口就相当于我们这里的插槽,我们可以将任何组件(也就是DOM元素)通过插槽添加到组件中。这样可以做到内容分发,让我们的组件可以混合使用。


怎么用插槽

在 Vue.js 中,插槽的使用分两种,单个插槽和具名插槽。

  • 单个插槽

在子组件内部通过一个 <slot> 元素就可以开启一个插槽,通过在父组件中,向子组件标签内部插入内容,就可以将这些内容替换掉子组件的 <slot> 标签及它的内容。只看文字可能理解的不是很深,举个例子:

<div>
  <helloworld>
    <span>父组件向子组件插槽内插入的内容</span>
  </helloworld>
</div>
<script>
  Vue.component('helloworld',{
    template:`
      <div>
        <slot>
          插槽内部默认内容
        </slot>
      </div>
    `
  }) 
</script>

上方代码最终显示内容为:父组件向子组件插槽内插入的内容

上方代码最终渲染出来的结果是:

<div>
  <span>父组件向子组件插槽内插入的内容</span>
</div>

在子组件 helloworld 中,定义了一个插槽,当父组件调用子组件的时候,没有向子组件标签内部传入数据的时候,会展示子组件插槽内的默认内容。当向子组件标签内部插入数据的时候,就会将插入的内容,替换掉子组件 <slot>标签以及标签内所有内容。

  • 具名插槽

上方我们展示了一个插槽的情况,当有多个插槽的时候,我们插入的内容不知道他会插入到那个插槽内部,这个时候就要使用具名插槽了。用来指定插入的内容插入到指定的插槽上。举例如下:

<div>
  <helloworld>
    <span slot="top">上面</span>
    <span>父组件向子组件插槽内插入的内容</span>
    <span slot="bottom">下面</span>
  </helloworld>
</div>
<script>
  Vue.component('helloworld',{
    template:`
      <div>
        <slot name="top"></slot>
        <slot></slot>
        <slot name="bottom"></slot>
      </div>
    `
  }) 
</script>

上方代码最终渲染结果如下:

<div>
    <span>上面</span>
    <span>父组件向子组件插槽内插入的内容</span>
    <span>下面</span>
</div>

我们定义了三个插槽,分别是具名插槽 top,没有 name 特性的默认插槽,还有具名插槽 bottom。在父组件中,通过 slot 选项来指定当前内容插入到子组件的哪一个插槽中,如果没有 slot 选项,插入到默认插槽。


编译作用域

在讲编译作用域之前,先举个小例子:

<div>
  <helloworld v-show="isShow">
    {{name}}
  </helloworld>
</div>

上方的 name,绑定的是父组件的数据,上方的 isShow,也是父组件的数据。

Vue.component('helloworld',{
  template:`
    <div v-show="isShow">
      {{name}}
    </div>
  `,
  data(){
    return{
      name:'',
      isShow:true
    }
  }
})

上方的 name,绑定的是子组件 helloworld 中的数据,上方的 isShow,也是子组件的数据。

引用官网说的一句话就是,父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。


作用域插槽的使用

作用域插槽,就是可以让我们在父组件中使用插槽时,插槽的数据可以来自子组件。举个例子:

<div>
  <helloworld>
    <template slot="props">
      <p>{{props.name}}</p>
    </template>
  </helloworld>
</div>
<script>
  Vue.component('helloworld',{
    template:`
      <div>
        <slot name="子组件向插槽传递的数据"></slot>
      </div>
    `
  }) 
</script>

上方代码最终渲染结果如下:

<div>
  <p name="子组件向插槽传递的数据"></p>
</div>

通过在父组件中,使用 template 元素,并且指定了 scope="props" 特性,然后子组件通过类似父子组件传值的形式,向插槽内部传递数据,这样我们就可以在父组件插槽中使用子组件的数据了。



访问插槽

最后,我们可以通过 $slot 访问插槽中的内容。

<div>
  <helloworld>
    <span slot="top">上面</span>
    <span>父组件向子组件插槽内插入的内容</span>
    <span slot="bottom">下面</span>
  </helloworld>
</div>
<script>
  Vue.component('helloworld',{
    template:`
      <div>
        <slot name="top"></slot>
        <slot></slot>
        <slot name="bottom"></slot>
      </div>
    `,
    mounted(){
      // 具名插槽top的内容
      console.log(this.$slots.top)  
      // 非具名插槽的内容
      console.log(this.$slots.default)
      // 具名插槽bottom的内容
      console.log(this.$slots.bottom)
    }
  }) 
</script>

Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!

e0a225c11cab7f6fb451ae6b0f2c4d2e.png

叶阳辉

HFun 前端攻城狮

往期精彩:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值