入口文件

<template>
  <div v-cloak>
    <tabs v-model="value">
    <pane label="标签一" name="1">
      标签一内容
    </pane>
     <pane label="标签二" name="2">
      标签二内容
    </pane>
     <pane label="标签三" name="3">
      标签三内容
    </pane>
  </tabs>
  </div>
</template>
<script>
import Tabs from '../components/tabs/tabs'
import pane from '../components/tabs/tab'
export default {
  components: {
    Tabs,
    pane
  },
  data () {
    return {
      value: '1'
    }
  }
}
</script>

tabs组件

<template>
<div class="tabs">
  <div class="tabs-bar">
  <!--标签页标题,通过v-for实现循环--!>
    <div :class="tabCls(item)"
          v-for="(item,index) in navList"
        @click = "handleChange(index)" :key="item.name">
    {{item.label}}
    </div>
  </div>
  <div class="tabs-content">
  <!--slot放置pane组件内容--!>
    <slot></slot>
  </div>
</div>
</template>

<script>
export default {
  name: 'Tabs',
  props: {
    value: [String, Number],
    required: true
  },
  data () {
    return {
      currentValue: this.value,
      navList: []
    }
  },
  methods: {
    tabCls (item) {
      return [
        'tabs-tab',
        {
          'tabs-tab-active': item.name === this.currentValue
        }
      ]
    },
    getTabs () {
    //获取pane
      return this.$children.filter(function (item) {
        return item.$options.name === 'pane'
      })
    },
    updateNav () {
    //获取标题,name,并放置到navList数组中
      this.navList = []
      let _this = this
      this.getTabs().forEach(function (pane, index) {
        _this.navList.push({
          label: pane.label,
          name: pane.name || index

        })
        if (!pane.name) pane.name = index
        if (index === 0) {
          if (!_this.currentValue) {
            _this.currentValue = pane.name || index
          }
        }
      })
      this.updateStatus()
    },
    updateStatus () {
      let tabs = this.getTabs()
      let _this = this
      tabs.forEach(function (tab) {
        let b = tab.name === _this.currentValue
        tab.show = b
        return tab.show
      })
    },
    handleChange (index) {
      let nav = this.navList[index]
      let name = nav.name
      this.currentValue = name
      this.$emit('input', name)
      this.$emit('on-click', name)
    }
  },
  watch: {
    value: function (val) {
      this.currentValue = val
    },
    currentValue () {
      this.updateStatus()
    }
  }
}
</script>

<style  scoped>
[v-cloak]{
    display: none;
}
.tabs{
    font-size: 14px;
    color: #657180;
}
.tabs-bar:after{
    content: '';
    display: block;
    width: 100%;
    height: 1px;
    background: #d7dde4;
    margin-top:-1px;
}
.tabs-tab{
    display: inline-block;
    padding: 4px 16px;
    margin-right: 6px;
    background: #fff;
    border: 1px solid #d7dde4;
    cursor: pointer;
    position: relative;
}
.tabs-tab-active{
    color: #3399ff;
    border-top: 1px solid #3399ff;
    border-bottom: 1px solid #3399ff;
}
.tabs-tab-active:before{
    content: '';
    display: block;
    height: 1px;
    background: #3399ff;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}
.tabs-content{
    padding: 8px 0;
}
</style>

pane组件

<template>
  <div class="pane" v-show="show">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'pane',
  props: {
    name: {
      type: String
    },
    label: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      show: true
    }
  },
  methods: {
    updateNav () {
      this.$parent.updateNav()
    }
  },
  watch: {
    label () {
      this.updateNav()
    }
  },
  mounted () {
    this.updateNav()
  },
  computed: {
    active () {
      return false
    }
  }
}
</script>
<style  scoped>
</style>

效果如下图:
这里写图片描述

Logo

前往低代码交流专区

更多推荐