123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- <template>
- <div>
- <transition-group class="p-tabs" name="tab" tag="div" ref="ptab">
- <div
- class="tab-item"
- v-for="(item, index) in list"
- :key="item.name + item.rountPath || item.jspUrl"
- :class="{
- 'tab-item-active':
- (item.rountPath == undefined
- ? item.jspUrl
- : item.rountPath) == getDefaultActive,
- }"
- @click="handleClick($event, item, index)"
- @contextmenu.prevent="clickright($event, item, index)"
- >
- <!-- <div class="tab-item-shap"></div> -->
- <el-tooltip
- placement="bottom"
- effect="dark"
- :content="item.name || item.functionName"
- :visible-arrow="false"
- :open-delay="1000"
- >
- <div class="text">
- {{ item.name || item.functionName }}
- </div>
- </el-tooltip>
- <i
- class="el-icon-error close"
- @click="handleClose($event, item, index)"
- ></i>
- </div>
- </transition-group>
- <div class="rightCbox" :style="cbox" v-if="rcbStatus">
- <el-card shadow="always">
- <span @click="closetab(1)">关闭其它所有标签</span>
- <span @click="closetab(2)">关闭左侧所有标签</span>
- <span @click="closetab(3)">关闭右侧所有标签</span>
- </el-card>
- </div>
- </div>
- </template>
- <script>
- export default {
- props: {
- list: {
- required: false,
- type: Array,
- default() {
- return [];
- },
- },
- },
- data() {
- return {
- isDrag: false,
- moveX: 0,
- touchX: 0,
- lastTouchX: 0,
- eachWidth: 0,
- offsetWidth: 0,
- scrollWidth: 0,
- mouseDownTime: 0,
- canClick: true,
- scrolling: false,
- cbox: {
- top: 0,
- left: 0,
- },
- rcbStatus: false,
- tabsobj: {},
- };
- },
- computed: {
- getDefaultActive() {
- return this.$store.state.defaultActive;
- },
- },
- mounted() {
- this.initData();
- this.$nextTick(() => {
- document.querySelector("body").addEventListener("click", this.closetab);
- });
- },
- watch: {
- /**
- * 监听默认选中对象值的变化,当菜单切换时自动滚动到指定tab
- * @param {Object} v
- */
- getDefaultActive(v) {
- for (let i = 0; i < this.list.length; i++) {
- if (this.list[i].rountPath == v) {
- this.scrollTo(i);
- }
- }
- },
- },
- updated() {
- this.initData();
- },
- methods: {
- initData() {
- if (this.list.length > 0) {
- this.eachWidth = this.$refs.ptab.$el.children[0].offsetWidth;
- this.offsetWidth = this.$refs.ptab.$el.offsetWidth;
- this.scrollWidth = this.$refs.ptab.$el.scrollWidth;
- let _this = this;
- this.$refs.ptab.$el.onmousedown = (e) => {
- _this.mouseDown(e);
- };
- this.$refs.ptab.$el.onmousemove = (e) => {
- _this.mouseMove(e);
- };
- this.$refs.ptab.$el.onmouseup = (e) => {
- _this.mouseUp(e);
- };
- this.$refs.ptab.$el.onmouseout = (e) => {
- _this.mouseUp(e);
- };
- }
- },
- /**
- * 删除tab元素触发关闭页面的逻辑
- * @param {Object} e 事件对象
- * @param {Object} item 当前点击的tab元素数据
- * @param {Object} index 当前tab的下标
- */
- handleClose(e, item, index) {
- this.$store.commit(
- "removePagesByName",
- (item.rountPath == undefined ? item.jspUrl : item.rountPath).replace(
- "/",
- ""
- )
- );
- e.preventDefault();
- e.stopPropagation();
- let list = [...this.list];
- if (list.length > 1) {
- if (
- (item.rountPath == undefined ? item.jspUrl : item.rountPath) !=
- this.getDefaultActive
- ) {
- list.splice(index, 1);
- this.$store.commit("setTabList", list);
- } else {
- if (list[index - 1]) {
- let rountPath = list[index - 1].hasOwnProperty("rountPath")
- ? list[index - 1].rountPath
- : list[index - 1].jspUrl;
- this.$store.commit("setDefaultActive", rountPath);
- list.splice(index, 1);
- this.$store.commit("setTabList", list);
- this.$router.push(rountPath);
- } else if (list[index + 1]) {
- let rountPath = list[index + 1].hasOwnProperty("rountPath")
- ? list[index + 1].rountPath
- : list[index + 1].jspUrl;
- this.$store.commit("setDefaultActive", rountPath);
- list.splice(index, 1);
- this.$store.commit("setTabList", list);
- this.$router.push(rountPath);
- } else {
- list.splice(index, 1);
- this.$store.commit("setTabList", list);
- this.$router.push("/");
- }
- }
- }
- },
- /**
- * 点击tab触发的事件
- * @param {Object} item 事件对象
- * @param {Object} index 点击的tab对象的下标
- */
- handleClick(e, item, index) {
- e.preventDefault();
- if (this.canClick) {
- let clickTime = new Date().getTime();
- if (clickTime - this.mouseDownTime < 500) {
- if (item.rountPath != undefined) {
- if (this.getDefaultActive != item.rountPath) {
- this.$store.commit("setDefaultActive", item.rountPath);
- this.scrollTo(index);
- this.$router.push(item.rountPath);
- }
- } else {
- if (this.getDefaultActive != item.jspUrl) {
- this.$store.commit("setDefaultActive", item.jspUrl);
- this.scrollTo(index);
- this.$router.push(item.jspUrl);
- }
- }
- }
- }
- this.canClick = true;
- },
- /**
- * 自动滚动到指定下标的tab对象
- * @param {Object} index 目标对象的下标
- * @param {Object} callback 滚动完毕触发的回调
- */
- scrollTo(index, callback) {
- let _from = Math.abs(this.lastTouchX);
- let _this = this;
- if (this.scrolling == false) {
- if (this.isDrag == false) {
- if (this.offsetWidth < this.scrollWidth) {
- let to = Math.abs(index * (this.eachWidth + 20));
- let interval = (to - _from) / 20;
- let grow = false;
- if (to > _from) {
- grow = true;
- } else {
- grow = false;
- }
- let runScroll = () => {
- let rn = setTimeout(() => {
- _this.$refs.ptab.$el.scrollLeft = _from;
- _this.lastTouchX = _from * -1;
- _from += interval;
- if (grow) {
- if (_from < to) {
- runScroll();
- return;
- } else {
- _from = to;
- this.scrolling = false;
- if (callback) {
- callback();
- }
- }
- } else {
- if (_from > to) {
- runScroll();
- return;
- } else {
- _from = to;
- this.scrolling = false;
- if (callback) {
- callback();
- }
- }
- }
- _this.$refs.ptab.$el.scrollLeft = _from;
- _this.lastTouchX = _from * -1;
- clearTimeout(rn);
- }, 16);
- };
- this.scrolling = true;
- runScroll();
- }
- }
- }
- },
- mouseDown(e) {
- this.touchX = e.clientX;
- this.isDrag = true;
- this.mouseDownTime = new Date().getTime();
- },
- mouseMove(e) {
- if (this.isDrag && this.offsetWidth < this.scrollWidth) {
- this.moveX = e.clientX;
- let scrollLeft = this.moveX - this.touchX + this.lastTouchX;
- this.$refs.ptab.$el.scrollLeft = scrollLeft * -1;
- this.canClick = false;
- } else {
- this.moveX = 0;
- this.touchX = 0;
- }
- },
- mouseUp() {
- this.isDrag = false;
- if (this.moveX == 0) {
- this.touchX = 0;
- }
- this.lastTouchX = this.moveX - this.touchX + this.lastTouchX;
- if (this.lastTouchX <= this.offsetWidth - this.scrollWidth) {
- this.lastTouchX = this.offsetWidth - this.scrollWidth;
- }
- if (this.lastTouchX >= 0) {
- this.lastTouchX = 0;
- }
- },
- clickright(event, item, index) {
- this.tabsobj = item;
- this.rcbStatus = true;
- if (event.clientX + 200 > document.body.clientWidth) {
- this.cbox.left = event.clientX - 168 + "px";
- } else {
- this.cbox.left = event.clientX + "px";
- }
- this.cbox.top = event.clientY + "px";
- },
- closetab(v) {
- if (this.rcbStatus) {
- this.rcbStatus = false;
- let list = [];
- if (v == 1) {
- list.push(this.tabsobj);
- this.$store.commit("setTabList", list);
- this.$router.push(this.tabsobj.rountPath);
- } else if (v == 2) {
- for (let i = 0; i < this.$store.state.tabList.length; i++) {
- if (
- this.$store.state.tabList[i].name == this.tabsobj.name ||
- list.length > 0
- ) {
- list.push(this.$store.state.tabList[i]);
- }
- }
- this.$store.commit("setTabList", list);
- this.$router.push(this.tabsobj.rountPath);
- } else if (v == 3) {
- for (let i = 0; i < this.$store.state.tabList.length; i++) {
- list.push(this.$store.state.tabList[i]);
- if (this.$store.state.tabList[i].name == this.tabsobj.name) {
- this.$store.commit("setTabList", list);
- this.$router.push(this.tabsobj.rountPath);
- return;
- }
- }
- }
- }
- },
- },
- };
- </script>
- <style scoped="scoped" lang="scss">
- .rightCbox {
- position: absolute;
- z-index: 1000;
- .el-card__body {
- padding: 0 !important;
- }
- span {
- display: block;
- padding: 5px 10px;
- }
- span:hover {
- color: #409eff;
- background: #f4f4f4;
- cursor: pointer;
- }
- }
- .tab-move {
- transition: 0.5s;
- }
- .tab-enter-active {
- opacity: 1;
- transition: 0.5s;
- position: absolute;
- }
- .tab-leave-active {
- opacity: 0;
- transition: 0.5s;
- position: absolute !important;
- }
- .tab-leave {
- opacity: 1;
- }
- .tab-enter {
- opacity: 0;
- }
- .p-tabs {
- box-sizing: border-box;
- width: 100%;
- height: 38px;
- white-space: nowrap;
- overflow: hidden;
- margin-top: 15px;
- // padding-left: 40px;
- .tab-item {
- display: inline-block;
- height: 38px;
- line-height: 38px;
- color: black;
- position: relative;
- width: 134px;
- overflow: hidden;
- border-radius: 0px 5px 0px 0px;
- margin-left: 15px;
- cursor: pointer;
- .tab-item-shap {
- position: absolute;
- width: 100%;
- height: 38px;
- transition: 0.3s;
- background: rgba(255, 255, 255, 0.4);
- border-radius: 5px 5px 0px 0px;
- transform: skew(-30deg);
- left: 20px;
- }
- .text {
- text-align: center;
- overflow-x: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- // padding: 0px 16px;
- font-size: 14px;
- letter-spacing: 0;
- position: absolute;
- width: 100%;
- height: 38px;
- text-align: center;
- background-color: white;
- }
- .close {
- font-size: 12px;
- position: absolute;
- right: 3px;
- top: 3px;
- color: #fff;
- }
- .close:hover {
- color: #107cff;
- }
- }
- .tab-item:hover {
- .tab-item-shap {
- background: rgba(255, 255, 255, 0.7);
- }
- }
- .tab-item-active {
- .skew {
- background: #fff;
- }
- .tab-item-shap {
- background: #fff;
- font-family: PingFangSC-Regular;
- font-size: 14px;
- letter-spacing: 0;
- }
- .text {
- text-align: center;
- overflow-x: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- // padding: 0px 16px;
- color: #107cff;
- }
- .close {
- color: #107cff;
- }
- }
- .tab-item-active:hover {
- .tab-item-shap {
- background: rgba(255, 255, 255, 1);
- }
- }
- }
- </style>
|