本文实例为大家分享了vue+elementui实现选项卡功的具体代码,供大家参考,具体内容如下
用法:首先自己先在项目中定义三个组件(顶部TopNav,左侧LeftAside,中间Main),这方法三两句话描述不清
我就上我用过的一个项目代码实例(但是这个有点缺陷,没有做像一键清空选项卡,关闭左右侧选项卡的方法)
TopNav
<template>
<el-menu class="el-menu-demo" mode="horizontal" background-color="#334157" text-color="#fff" active-text-color="#fff">
<el-button class="buttonimg">
<img class="showimg" :src="collapsed?imgshow:imgsq" @click="doToggle()">
<!-- :src="collapsed?imgshow:imgsq" @click="doToggle()" -->
</el-button>
<el-submenu index="2" class="submenu">
<template slot="title">当前用户【{{username}}】身份认证:{{usertype}}</template>
<el-menu-item index="2-1">设置</el-menu-item>
<el-menu-item index="2-2" @click="mya()">个人中心</el-menu-item>
<el-menu-item @click="exit()" index="2-3">退出</el-menu-item>
</el-submenu>
</el-menu>
</template>
<script>
export default {
name: 'LeftAside',
data: function() {
return {
collapsed: false, //是否折叠
imgshow: require('../assets/img/show.webp'),
imgsq: require('../assets/img/sq.webp'),
username:sessionStorage.getItem("username"),
usertype:sessionStorage.getItem("deptment")
};
},
methods: {
doToggle() {
this.collapsed = !this.collapsed;
console.log("TopNav的collapsed=%s", this.collapsed);
this.$emit('top-click', this.collapsed);
},
exit() {
this.$confirm('亲,请不要走,留下好不好?', '提示', {
confirmButtonText: '残忍离开',
cancelButtonText: '留下~',
type: 'warning'
}).then(() => {
this.$router.push('/');
}).catch(() => {});
},
mya(){
/* this.$router.push('/userCenter'); */
/* this.$router.push('/system/UserCenter'); */
}
}
}
</script>
<style scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
border: none;
}
.submenu {
float: right;
}
.buttonimg {
height: 60px;
background-color: transparent;
border: none;
}
.showimg {
width: 26px;
height: 26px;
position: absolute;
top: 17px;
left: 17px;
}
.showimg:active {
border: none;
}
</style>
LeftAside
<template>
<el-menu router :default-active="$route.path" class="el-menu-vertical-demo" background-color="#334157" text-color="#fff"
active-text-color="#ffd04b" :collapse="leftCollapsed">
<!-- <el-menu default-active="2" :collapse="collapsed" collapse-transition router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b"> -->
<div class="logobox">
<img class="logoimg" src="../assets/img/logo.webp" alt="">
</div>
<!--
第一级菜单
el-submenu属性:
index:用于菜单折叠,不能重复
key:菜单项的唯一标识,不可重复
-->
<el-menu-item index="/Home" key="Home">
<i class="el-icon-house"></i>
<span slot="title">首页</span>
</el-menu-item>
<!-- <el-menu-item index="/Page1" key="Page1">
<i class="el-icon-menu"></i>
<span slot="title">Page1</span>
</el-menu-item>
<el-menu-item index="/Page2" key="Page2">
<i class="el-icon-menu"></i>
<span slot="title">Page2</span>
</el-menu-item> -->
<el-submenu v-for="root in treenode" :index="'index-'+root.dictId" :key="'key-'+root.dictId">
<template slot="title">
<i :class="root.dictIcon"></i>
<span slot="title">{{root.dictText}}</span>
</template>
<!-- 第二级菜单 -->
<!--
el-menu-item属性:
index:用于跳转页面,不能重复
key:菜单项的唯一标识,不可重复
-->
<el-menu-item @click="addTab(node.dictUrl,node.dictText)" v-for="node in root.children" :index="node.dictUrl"
:key="'key-'+node.dictId">
<i class="el-icon-menu"></i>
<span slot="title">{{node.dictText}}</span>
</el-menu-item>
</el-submenu>
</el-menu>
</template>
<script>
export default {
name: 'LeftAside',
props: ['leftCollapsed'],
data: function() {
return {
treenode: ''
};
},
methods: {
addTab: function(url, text) {
console.log(url, text);
//调用vuex中的addTab方法,将点击的菜单对应的组件信息添加到已打开的openTabs中
this.$store.commit('addTab', {
title: text, //Tab页签标题
name: url //组件的路由
});
//设置当前Tab面板为选中状态
this.$store.commit('setTabActive', url);
}
},
created() {
//获取请求路径
/* let url = this.axios.urls.SYSTEM_TREENODE; */
let url = this.axios.urls.SYSTEM_QUERY;
/* ,{username:sessionStorage.getItem("username")} */
console.log(url);
//发送axios请求
this.axios.post(url, {
username: sessionStorage.getItem("username")
}).then(resp => {
console.log(resp.data);
this.treenode = resp.data.data;
}).catch(resp => {});
//设置首页默认显示
// this.$router.push('/Home');
}
}
</script>
Main
<template style="background-color:floralwhite">
<el-container class="main-container">
<el-aside :class="openCollapse">
<LeftAside :open-collapsed="collapsed"></LeftAside>
</el-aside>
//选项卡控件
<el-container>
<el-header class="main-header">
<TopNav @click-collapse="topClick"></TopNav>
</el-header>
<el-main class="main-center">
<el-tabs class="tabs-panel-fit" v-model="activeTab" type="border-card" closable @tab-remove="removeTab">
<el-tab-pane v-for="item in openTabs" :key="item.name" :label="item.title" :name="item.name">
<component :is="item.content"></component>
</el-tab-pane>
</el-tabs>
</el-main>
//时钟效果
<div id="app" style="margin-left: 200px;margin-top: -400px;font-size: 30px;">
{{date}}
</div>
</el-container>
</el-container>
</template>
<script>
import TopNav from '@/components/TopNav'
import LeftAside from '@/components/LeftAside'
export default {
name: 'Main',
data: function() {
return {
collapsed: false,
date: new Date()
};
},
methods: {
topClick: function(collapsed) {
this.collapsed = collapsed;
},
removeTab: function(targetName) {
//获取所有已打开的Tabs选项卡
let tabs = this.$store.getters.openTabs;
//获取当前激活的Tab选项卡
let activeName = this.$store.getters.activeTab;
//判断当前激活的Tab选项卡和当前被关闭的Tab选项卡是否相同
if (activeName === targetName) {
//遍历已打开的选项卡
tabs.forEach((tab, index) => {
//判断是否相同,并获取就近需要被激活选项卡
if (tab.name === targetName) {
let nextTab = tabs[index + 1] || tabs[index - 1];
if (nextTab) {
activeName = nextTab.name;
}
}
});
}
//激活选项卡
this.$store.commit('setTabActive', activeName);
//删除Tab
this.$store.commit('delTab', tabs.filter(tab => tab.name !== targetName));
}
},
components: {
TopNav,
LeftAside
},
computed: {//计算属性
openCollapse: function() {
return !this.collapsed ? 'main-aside' : 'main-aside-collapsed'
},
openTabs: function() {
let openTabs = this.$store.getters.openTabs;
let tabs = [];
if (null == openTabs)
return tabs;
else {
for (let tab of openTabs) {
let component = resolve => require.ensure([], () => resolve(require('@/views' + tab.name + '.vue')));
tabs.push({
title: tab.title,
name: tab.name,
content: component
});
}
return tabs;
}
},
activeTab: {
get() {
return this.$store.getters.activeTab;
},
set(val) {
this.$store.commit('setTabActive', val);
}
}
},
//展示时钟的方法
mounted() {//挂载完成
console.log(this.$route.path);
if (this.$route.path == '/Home') {
this.$store.commit('addTab', {
title: '首页',
name: '/Home'
});
this.$store.commit('setTabActive', '/Home');
}
let _this = this; // 声明一个变量指向Vue实例this,保证作用域一致
this.timer = setInterval(() => {
_this.date = new Date(); // 修改数据date
}, 1000)
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer); // 在Vue实例销毁前,清除我们的定时器
}
}
}
</script>
<style>
.main-container {
height: 100%;
width: 100%;
box-sizing: border-box;
}
.main-aside-collapsed {
/* 在CSS中,通过对某一样式声明! important ,可以更改默认的CSS样式优先级规则,使该条样式属性声明具有最高优先级 */
width: 64px !important;
height: 100%;
background-color: #334157;
margin: 0px;
}
.main-aside {
width: 240px !important;
height: 100%;
background-color: #334157;
margin: 0px;
}
.main-header,
.main-center {
padding: 0px;
border-left: 2px solid #333;
height: 100%;
object-fit: fill;
}
.div-pagination {
margin: 10px 0px;
width: 100%;
}
/* 设置tabs内容面板100%填充父容器 */
.tabs-panel-fit {
margin: 0;
padding: 0;
/* background-color:#1F2D3D; */
width: 100%;
height: 100%;
object-fit: fill;
}
/* 设置tabs内容面板的内边距为0 */
.el-tabs--border-card>.el-tabs__content {
padding: 0;
}
/* 设置tab的表框效果(重要) */
.el-tabs.el-tabs--border-card {
box-shadow: none;
border-bottom: none;
border: 0;
}
/*设置选项卡中第一个首页选项卡不能关闭*/
.el-tabs>.el-tabs__header .el-tabs__item:first-child>span {
display: none;
}
/* elementUI dialog弹出框样式优化 */
.el-dialog {
position: absolute;
top: 50%;
left: 50%;
margin: 0 !important;
transform: translate(-50%, -50%);
max-height: calc(100% - 30px);
max-width: calc(100% - 30px);
display: flex;
flex-direction: column;
/* 圆角效果 */
border-radius: 0.4em;
}
.el-dialog>.el-dialog__body {
overflow: auto;
}
.el-dialog__header {
background-color: #F5F7FA;
border-bottom: 1px solid #ccc;
font-size: 14px;
font-weight: bold;
padding: 15px 20px 15px;
/* 圆角效果 */
border-radius: 0.4em 0.4em 0em 0em;
}
.el-dialog__body {
padding: 20px 15px;
}
.el-dialog__footer {
background-color: #F5F7FA;
border-top: 1px solid #ccc;
padding: 15px;
/* 圆角效果 */
border-radius: 0em 0em 0.4em 0.4em;
}
.el-form>.el-form-item:last-child {
margin-bottom: 0px;
}
/* 更改table表格的高亮背景色*/
/* .el-table tr.current-row>td {
background: #FFF68F;
} */
.el-table .el-table__body tr:hover>td{
background: #FFF68F;
font-weight:bold;
color:#000000;
}
/* 分页组件 */
/* .div-pagination {
margin: 10px 0px;
width: 100%;
} */
</style>