实现tab左右箭头切换及自适应
<template> <div> <div id="tab1" class="tab"> <div :class="{scroll:scroll,container:1}"> <div class="wrapper"> <header :class="{flex:flex}" :style="{left:left+'px'}"> <div v-for="(item,index) in tabs" :key="index" :class="{item:1,cur:index==curIndex}" @click="setCur(index,$event)">{{ item }}<b /></div> <div class="clear" /> </header> </div> <a class="pre" @click="preNext(1)"><</a> <a class="next" @click="preNext(-1)">></a> </div> <div class="tabody"> <div v-for="(item,index) in tabs" :key="index" :style="{display:index==curIndex?'block':'none'}">{{ item }}</div> </div> </div> </div> </template> <script> export default { name: 'Test', components: { }, data() { return { tabs: ['选项卡1', '选项卡2', '选项卡3', '选项卡4', '选项卡5', '选项卡6', '选项卡7', '选项卡8', '选项卡9'], curIndex: 0, flex: 0, scroll: 0, left: 0 } }, mounted() { var wrapper = this.$el.querySelector('.wrapper') if (wrapper.scrollHeight > wrapper.offsetHeight + 2) { var items = wrapper.querySelectorAll('.item') var w = 0 for (var item of items) { item.setAttribute('left', w); w += item.offsetWidth } this.header = wrapper.querySelector('header').style.width = w + 'px' this.scroll = 1 this.stepWidth = wrapper.clientWidth - 60 this.maxLeft = this.stepWidth - w } else this.flex = 1 }, methods: { /* 获取列表数据 */ setCur(index, e) { this.curIndex = index if (this.scroll) { var el = e.target; var left = parseInt(el.getAttribute('left')) this.isInView(left, left + el.offsetWidth) } }, preNext(dir) { var left = this.left + dir * this.stepWidth if (left < this.maxLeft) left = this.maxLeft else if (left > 0)left = 0 this.left = left }, isInView(left, right) { var left1 = -1 * this.left; var right1 = -1 * (this.left - this.stepWidth) if (left < left1 || left > right1 || right < left1 || right > right1) { if (left < left1) this.left = -left + 2 else this.left = -right + this.stepWidth } } } } </script> <style lang="scss" scoped> #tab1,#tab2{width:400px;margin:20px auto} .tab{border:solid 1px #ccc;} .container{border-bottom:solid 1px #ccc;background:#eee} .wrapper{height:32px;} .scroll{padding:0 30px;position:relative} .scroll .wrapper{overflow:hidden;position:relative;margin-bottom:-1px} .scroll header{width:999999px;position:absolute;transition:all 0.6s cubic-bezier(0.23,1,0.32,1);} a.pre,a.next{display:none} .scroll a.pre,.scroll a.next{position:absolute;left:8px;top:5px;cursor:pointer;background:#eee;display:block} .scroll a.next{left:auto;right:8px} .flex{display:flex;justify-content:center;width:auto} header .item{padding:5px 15px;float:left;cursor:pointer;position:relative;user-select:none} header .item b{display:none;height:0;border-bottom:solid 2px #fff;width:100%;left:0;bottom:-2px;position:absolute} header .cur{background:#fff;border-left:solid 1px #ccc;border-right:solid 1px #ccc;color:#007bffb5;border-top-left-radius:5px;border-top-right-radius:5px;} header .cur b{display:block} .clear{clear:both} .tabody{padding:10px} </style>