济菏高速业务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

260 lines
10 KiB

<template>
<div class="recent_pages">
<h4><i class="iconfont icon-recent"></i>
<!-- <ContextMenu>最近访问:</ContextMenu> -->
最近访问:
</h4>
<div class="history_buttons">
<div class="btn_left" @click="onLeft" :class="{'disabled' : startIndex <= 0 }"><i
class="iconfont icon-left"></i></div>
<div class="list_box" ref="box">
<div class="list" :style="btnListStyle" ref="btnlist">
<div class="unit" :class="isActive(item) ? 'active' : ''" v-for="item,index in recentPages"
ref="unit">
<p class="btn_main" @click="onClickItem(item)" :key="item.path"
:style="{width:item.title.length*14+'px'}">
{{item.title}}
</p>
<p class="btn_pin" :class="{active:item.isPinned}" @click="onPin(item)"><i></i></p>
<i class="btn_close iconfont icon-guanbi" @click="onRemoveItem(item)"></i>
</div>
</div>
</div>
<div class="btn_right" @click="onRight"
:class="{ 'disabled': lastIndex == -1 || lastIndex >= widthArr.length - 1 }"><i
class="iconfont icon-right"></i></div>
</div>
</div>
</template>
<script>
import { mapMutations, mapState } from 'vuex';
import ContextMenu from './ContextMenu.vue';
export default{
data(){
return {
posiLeft:0, //按钮列表绝对定位的数值
widthBox:0,
widthTotal:0,
lastIndex:-1, //当前能显示的最后一个元素的索引
startIndex:-1, //当前能显示的第一个元素的索引
widthArr:[],
currentIndex : -1
}
},
components:{
ContextMenu
},
computed:{
...mapState("menu", ["recentPages"]),
btnListStyle(){
return {
left : `${this.posiLeft}px`
};
}
},
watch:{
recentPages:{
handler(newV){
this.$nextTick(()=>{
// console.log("触发了Precentage的watch")
this.widthArr = [];
this.widthBox = this.$refs["box"].offsetWidth;
this.widthTotal = this.$refs["btnlist"].offsetWidth;
let temp = 0;
newV.forEach((item,index)=>{
let unitW = this.$refs["unit"][index].offsetWidth;
temp += unitW;
this.widthArr[index] = temp;
if(temp >= this.widthBox && this.lastIndex == -1){
this.lastIndex = index;
}
if(item.active){
this.currentIndex = index;
}
// console.log(this.currentIndex, "currentIndexcurrentIndex")
// console.log(this.startIndex, "startIndexstartIndex")
// console.log(this.lastIndex, "lastIndexlastIndex")
})
if(this.widthTotal > this.widthBox){
if (this.currentIndex >= this.lastIndex) {
this.moveByRight(this.currentIndex);
} else if (this.currentIndex <= this.startIndex) {
this.moveByLeft(this.currentIndex);
}
}
})
},
immediate:true,
deep:true,
},
$route:{
handler(newV){
this.addRecent({
title : newV.meta.title,
path : newV.path
});
},
immediate : true
}
},
mounted(){
},
methods:{
...mapMutations("menu", ["addRecent", "removeRecent","pinRecent"]),
onClickItem(item){
this.$route.path != item.path && this.$router.push(item.path);
},
onPin(item){
this.pinRecent(item);
},
onRemoveItem(item){
this.removeRecent(item);
if(this.$route.path == item.path){
if(this.recentPages.length){
this.$router.push(this.recentPages[this.recentPages.length-1].path)
}else{
this.$router.push("/")
}
}
},
isActive(item) {
return this.$route.path == item.path;
},
onLeft(){
this.moveByLeft();
},
onRight(){
if (this.widthTotal > this.widthBox) {
this.moveByRight();
}
},
moveByLeft(targetIndex){
// console.log("左侧动", this.startIndex, targetIndex);
if (this.startIndex <= 0) {
return
}
if (targetIndex != undefined) {
this.startIndex = targetIndex;
} else {
this.startIndex -= 3;
}
if (this.startIndex < 0) {
this.startIndex = 0;
}
if(this.startIndex == 0){
this.posiLeft = 0;
}else{
this.posiLeft = this.widthArr[this.startIndex-1] * -1;
}
this.calcLastIndex();
// console.log(this.posiLeft , "posiLeft++");
},
moveByRight(targetIndex){
// console.log("右侧动", this.lastIndex, targetIndex);
if(this.lastIndex >= this.widthArr.length - 1){
return
}
if(targetIndex!==undefined){
this.lastIndex = targetIndex;
}else{
this.lastIndex += 3;
}
if(this.lastIndex > this.widthArr.length-1){
this.lastIndex = this.widthArr.length - 1;
}
// console.log(targetIndex, this.widthArr.length , "+++========")
this.posiLeft = this.widthBox - this.widthArr[this.lastIndex];
this.calcStartIndex();
},
calcStartIndex(){
try{
this.widthArr.forEach((item,index)=>{
if(item > -1*this.posiLeft){
this.startIndex = index;
throw new Error('找到startIndex,退出循环')
}
})
}catch(e){
// console.log(e);
}
},
calcLastIndex(){
try{
this.widthArr.forEach((item, index) => {
if (item > (this.widthBox - this.posiLeft)) { //posiLeft是个负值
this.lastIndex = index;
// console.log(this.lastIndex , "this.lastIndex lastIndex lastIndex lastIndex")
throw new Error('找到lastIndex,退出循环')
}
})
}catch(e){
// console.log(e);
}
}
}
}
</script>
<style lang="scss" scoped>
.recent_pages{
display: flex; flex-direction: row; align-items:stretch; padding: 0 20px;
h4{ width: 110px; height: 32px; line-height: 32px; text-align: center; margin: 0; padding: 0; font-weight: bold; color: #3de8ff; display: flex; align-items: center; justify-content: center;
.iconfont{ margin-right: 3px;}
}
.history_buttons {
flex: 1;
display: flex;
flex-direction: row;
.btn_left, .btn_right{ width: 26px; height: 30px; background-color: #048145;background-image: linear-gradient(180deg, #005c79 0%, #009bcc 100%);
border:1px solid #009bcc; border-radius: 4px; display: flex; justify-content: center; align-items: center;
&.disabled{ background-image: linear-gradient(0deg, #999 0%, #777 100%); border:1px solid #999; color: #ccc;}
}
.btn_left{ margin-right: 4px;}
.btn_right{ margin-left: 4px;}
.list_box{ flex: 1; position: relative; width: 0; overflow: hidden; margin:0;
.list{ position: absolute; left: 0; top:0; display: flex; flex-direction: row; transition: all ease-in-out 0.5s;
.unit {
position: relative;
height: 30px;
padding: 0 3px;
.btn_main {
cursor: pointer;
background-image: linear-gradient(180deg, #005c79 0%, #009bcc 100%);
border:1px solid #009bcc;
border-radius: 4px;
height: 28px;
text-align: center;
line-height: 28px; font-weight: bold; font-size: 14px; box-sizing: content-box;
padding: 0 18px 0 12px; word-break: keep-all; white-space: nowrap;
}
&.active {
.btn_main {
background-image: linear-gradient(180deg,#048145 0%, #078b58 100%);
border:1px solid #03a9b1;
}
}
.btn_pin{
position: absolute;
left:0;
bottom:0;
width:16px; height: 10px;
display: flex; align-items: center; justify-content: center;
i{
display: block;
width:6px; height: 6px; border-radius: 3px;
}
&.active i{ background-color: #FA0;}
}
.btn_close {
position: absolute;
right: 6px;
top:8px;
font-size: 12px; color: #3de8ff;
}
}
}
}
}
}
</style>