tab标签栏 类似于浏览器的tab栏直接用

    技术2023-08-02  74

    效果 组件是直接封装好的

    <template> <div class="tabPage flex" id="tabPage"> <div class="leftTab cur" @click="leftClick"><i class="el-icon-arrow-left"></i></div> <div class="tabMain " id="tabItem" style=""> <div class="tabItem" v-for="item in $store.state.tabPageBox" :class="{isActive:item.isActive}" @click="chooseThis(item)"> <span class="yuanTab"></span> <span class="name">{{item.meta.title}}</span> <i class="el-icon-close" @click="closeClick(item)" v-if="item.meta.title!='首页'"></i> </div> </div> <div class="rightTab cur" @click="rightClick"><i class="el-icon-arrow-right"></i></div> <el-dropdown class="closeTab cur" trigger="click" @command="closeAll"> <span class="el-dropdown-link"> <i class="el-icon-circle-close"></i> </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item command="关闭所有">关闭所有</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </template> <script> export default { components: { }, data() { return { plusWidth:0,//记录实际宽度和本该有的宽度的差值 可以滚动的次数 num:300, //滑动距离 ccRight:1, //第几次右滑动 ccLeft:1, //第几次左滑动 }; }, methods: { // 点击tab 选择 chooseThis(val){ if(val.isActive){ return false; } let arr=JSON.parse(JSON.stringify(this.$store.state.tabPageBox)); for(let i in arr){ // 遍历 if(arr[i].meta.title==val.meta.title){ //改变状态 arr[i].isActive=true; } } this.$store.commit("setTabPageBox",arr) ; this.$router.push(val.path) }, // 关闭当前 closeClick(val){ let arr=JSON.parse(JSON.stringify(this.$store.state.tabPageBox)); for(let i in arr){ // 遍历 if(arr[i].meta.title==val.meta.title){ //删除数组里的对应的 arr.splice(i,1); } } // 判断当前是否操作的是否是选中状态 if(val.isActive){ arr[0].isActive=true; this.$store.commit("setTabPageBox",arr) ; this.$router.push("/") }else{ this.$store.commit("setTabPageBox",arr) ; } }, // 关闭所有 closeAll(val){ if(val=='关闭所有'){ let arr=[{ path: '/index/homePage/homePage', name: '首页', isActive:true, meta: { title: "首页"}, }] this.$store.commit("setTabPageBox",arr) ; this.$router.push("/"); // 滑动重置 this.ccRight=1; document.getElementById('tabItem').style.marginLeft=0; } }, // 移动 leftClick(){ // 获取父级总宽度 offsetWidth let fatherWidth=document.getElementById('tabPage').offsetWidth; let sonWidth=fatherWidth-88; //88是左右图标的 总宽度 // 获取实际的子级宽度 let curSonWidth=document.getElementById('tabItem').offsetWidth; // 比较子级的宽度和实际的区别 if(curSonWidth-sonWidth>0){ // 超过了宽度可以滚动 this.plusWidth=Math.ceil((curSonWidth-sonWidth)/this.num); //+100是为了滑动之后右边流出距离 1此滑动300 if(this.ccRight!=1){ document.getElementById('tabItem').style.marginLeft='-'+this.num*(this.ccRight-2)+'px'; this.ccRight--; } } }, // 右边 rightClick(){ // 获取父级总宽度 offsetWidth let fatherWidth=document.getElementById('tabPage').offsetWidth; let sonWidth=fatherWidth-88; //88是左右图标的 总宽度 // 获取实际的子级宽度 let curSonWidth=document.getElementById('tabItem').offsetWidth; // 比较子级的宽度和实际的区别 if(curSonWidth-sonWidth>0){ // 超过了宽度可以滚动 this.plusWidth=Math.ceil((curSonWidth-sonWidth)/this.num); //+100是为了滑动之后右边流出距离 1此滑动300 if(this.plusWidth>=this.ccRight){ document.getElementById('tabItem').style.marginLeft='-'+this.num*this.ccRight+'px'; this.ccRight++; } } } }, mounted(){ // 监听窗口变化 const that = this window.onresize = () => { return (() => { // 滑动重置 this.ccRight=1; document.getElementById('tabItem').style.marginLeft=0; })() } }, created(){ if(this.$store.state.tabPageBox.length==0){ let arr=[{ path: '/index/homePage/homePage', name: '首页', isActive:true, meta: { title: "首页"}, }] this.$store.commit("setTabPageBox",arr) } }, watch: { $route(toPage,from){ let arr=JSON.parse(JSON.stringify(this.$store.state.tabPageBox)) let newOpen=true; //控制是否新打开页面 for(let i in arr){ // 全部取消选中 arr[i].isActive=false; // 遍历 if(arr[i].meta.title==toPage.meta.title){ //说明此页面已打开过 arr[i].isActive=true; newOpen=false; } } if(newOpen){ let obj={ path: toPage.path, name: toPage.name, isActive:true, meta: { title: toPage.meta.title}, } obj.isActive=true; arr.push(obj) } this.$store.commit("setTabPageBox",arr) }, }, } </script> <style lang="scss" scoped> .tabPage{ height: 40px; width: 100%; position: relative; } .leftTab{ position: absolute; left: 0; top: 1px; height: 38px; width: 28px; text-align: center; line-height: 38px; font-size: 18px; background: #fff; i{ color:#000 } &:hover{ i{ color:$blue } } } .tabMain{ white-space: nowrap; cursor: pointer; padding-left: 33px; margin:5px 0; transition: margin-left .5s; .tabItem{ display: inline-block; margin-right:4px; padding:0 12px; height: 30px; line-height: 30px; background: #fff; border-radius: 4px; } .el-icon-close{ margin-left:16px } .el-icon-close:hover{ cursor: pointer; color:$blue; } .yuanTab{ vertical-align: -1px; display: inline-block; width: 12px; height: 12px; border-radius: 100px; background: #E8EAEC; margin-right: 8px; } } .isActive .yuanTab{ background: $blue; } .rightTab{ position: absolute; right: 33px; top: 1px; height: 38px; width: 28px; text-align: center; line-height: 38px; font-size: 18px; background: #fff; i{ color:#000 } &:hover{ i{ color:$blue } } } .closeTab{ position: absolute; right: 0px; top: 1px; height: 38px; width: 32px; text-align: center; line-height: 38px; font-size: 18px; background: #fff; i{ color:#000 } &:hover{ i{ color:$blue } } } </style>

    store的代码

    const state={ tabPageBox:[] } const mutations={ setTabPageBox(state,tabPageBox){ console.log(tabPageBox) state.tabPageBox = tabPageBox; }, }

    实现的效果 效果1

    1)点击切换 2)关闭标签页 3)右边x关闭所有 4)点击新页面 标签页自动增加,已存在会自动跳转到存在的标签上

    效果二

    1)左右动画滚动 2)窗口变化 自动重置

    Processed: 0.009, SQL: 9