美文网首页
vue自定义Tab组件

vue自定义Tab组件

作者: 漫漫江雪 | 来源:发表于2019-06-14 10:22 被阅读0次

一个普通的tab标签大致的结构通常是如此:

<div class="tabs-container">
    <ul class="tabs">
        <li class="active">Tab1</li>
        <li>Tab2</li>
        <li>Tab3</li>
    </ul>
    <div class="tab-content">
        被激活标签项的内容
    </div>
</div>

转换成vue组件,想象中的样子

<tabs class="tabs-container">
    <tab class="active" :label="'Tab1'">Tab1内容</tab>
    <tab :label="'Tab2'">Tab2内容</tab>
    <tab :label="'Tab3'">Tab3内容</tab>
</tabs>

1. 外层 tabs容器组件 tabs.vue

<template>
  <div class="tab-container">
    <ul class="tab-head">
      <slot></slot>
    </ul>
    <content-container :panels="panels" />
  </div>
</template>

<script>
  import ContentContainer from './content-container.vue' // 用于展示tab内容的组件
  export default {
    name: 'tabs',
    data() {
      return {
        panels: [] // 子组件mounted的时候将自己push到该数组中
      }
    },
    props: {
      value: {
        type: [String, Number],
        required: true
      }
    },
    methods: {
      tabChange(index) {
        this.$emit('tabChange',index)
      }
    },
    components: {
      ContentContainer
    }
  }
</script>

<style scoped>
.tab-container{
  width: 500px;  
}
.tab-head {
  padding: 0 15px;
  border-bottom: 2px solid #ccc;
  font-size: 0;
}
</style>

2. 单个标签项 tab组件 (用了render function) tab.vue

<script>
  export default {
    name: 'tab',
    props: {
      index: {
        type: [String,Number],
        required: true
      },
      label: {
        type: String
      }
    },
    mounted() {
      this.$parent.panels.push(this)
    },
    render(h)  {
      const tab = this.$slots.label || h('span',this.label)  // 如果用name=label的slot,则用slot,否则展示label prop
      return h('li', {
        class: this.classes,
        on: {
          click: this.activeCurTab
        }
      },[ tab ])
    },
    computed: {
      active() {
        return this.index ===this.$parent.value
      },
      classes() {
        return ['tab', this.active? 'active': '']
      } 
    },
    methods: {
      activeCurTab() {
        this.$parent.tabChange(this.index)
      }
    }
  }
</script>

<style lang="scss" scoped>
.tab {
  display: inline-block;
  font-size: 14px;
  padding: 0 10px;
  height: 40px;
  line-height: 38px;
  position: relative;
  bottom: -2px;
  cursor: pointer;
  margin: 0 5px;
  border-bottom: 2px solid rgba(255,255,255,0);
  &.active {
    color: #f60;
    border-bottom: 2px solid #f60;
  }
}
</style>

3. tab内容展示容器组件 content-container.vue

<script>
  export default {
    props: {
      panels: {
        type: Array,
        default: function() {
          return []
        }
      }
    },
    render(h) {
      const contents = this.panels.map(tab => {
        return tab.active? tab.$slots.default: null
      })
      return h('div', {
        class: 'tab-content'
      }, contents)
    }
  }
</script>

<style scoped>
.tab-content {
  margin-top: 8px;
  border: 1px solid #ccc;
  padding: 15px;
  min-height: 100px;
}
</style>

4. 注册为全局组件 (和上面组件同目录的index.js)

import tabs from './tabs.vue'
import tab from './tab.vue'

export default (Vue) => {
  Vue.component(tabs.name, tabs)
  Vue.component(tab.name, tab)
}

接着要在main.js中引入并use一下

import tabs from './components/tabs'
Vue.use(tabs)

5. 使用组件

<template>
  <div class="cus-tab">
    <tabs :value="curTab" @tabChange="tabChange">
      <tab :index="0" :label="'Tab1'">
        <div>
          Tab1的内容
          <notify :content="'自定义组件测试'"></notify>
        </div>
      </tab>
      <tab :index="1" :label="'Tab2'">
        <span slot="label">我是tab2</span>
        <div>Tab2的内容</div>
      </tab>
      <tab :index="2" :label="'Tab3'">
        <div>Tab3的内容</div>
      </tab>
    </tabs>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        curTab: 0 // 当前激活的tab索引
      }
    },
    methods: {
      tabChange(index) {
        this.curTab = index
      }
    }
  }
</script>

6. 效果

tab-component.gif

相关文章

  • Vue如何检查子组件类型

    TabsDemo.vue组件 Tab.vue Tabs.vue 1、检查Tabs组件中子组件Tab的类型 Tabs...

  • 自定义组件相关知识点

    自定义组件的步骤 以tab切换组件为例 创建自定义组件创建components/tab文件夹在tab上右键,新建C...

  • 自定义组件的知识点

    自定义组件的步骤 以tab切换组件为例 创建自定义组件创建components/tab文件夹在tab上右键,新建C...

  • vue自定义Tab组件

    一个普通的tab标签大致的结构通常是如此: 转换成vue组件,想象中的样子 1. 外层 tabs容器组件 tabs...

  • vue自定义组件

    vue自定义组件 1.vue全局组件 Vue.component("组件名",{obj});obj跟vue实例一样...

  • vue+element-ui tab切换

    1.使用vue结合element-ui开发tab切换vue的不同组件,每一个tab切换的都是一个新的组件。 2.创...

  • vue + element-ui 制作tab切换(切换vue组件

    本篇文章使用vue结合element-ui开发tab切换vue的不同组件,每一个tab切换的都是一个新的组件。 1...

  • Vue tab组件

    今天跟大家分享一个tab切换的组件,功能相对完善。话不多说,直接上代码: slot里面是tab的内容。 scrip...

  • uni-app 之组件之间的通讯方式

    首先目录结构如下: test.vue 自定义组件 index.vue 父组件

  • 自定义vue组件

    (1) 自定义组件dialog.vue (2) 页面调用 (3) 弹窗效果展示 拓展:vue自定义组件点击页面其他...

网友评论

      本文标题:vue自定义Tab组件

      本文链接:https://www.haomeiwen.com/subject/yffufctx.html