全局指令
This commit is contained in:
parent
b1695084f2
commit
d953f5d7ac
|
|
@ -0,0 +1,22 @@
|
|||
import {permission} from '@/utils/permission'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const {value} = binding
|
||||
if (Array.isArray(value)) {
|
||||
let ishas = false;
|
||||
value.forEach(item => {
|
||||
if (permission(item)) {
|
||||
ishas = true;
|
||||
}
|
||||
})
|
||||
if (!ishas) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
if (!permission(value)) {
|
||||
el.parentNode && el.parentNode.removeChild(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import {ElMessage} from 'element-plus'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
el.$value = binding.value
|
||||
el.handler = () => {
|
||||
const textarea = document.createElement('textarea')
|
||||
textarea.readOnly = true
|
||||
textarea.style.position = 'absolute'
|
||||
textarea.style.left = '-9999px'
|
||||
textarea.value = el.$value
|
||||
document.body.appendChild(textarea)
|
||||
textarea.select()
|
||||
textarea.setSelectionRange(0, textarea.value.length)
|
||||
const result = document.execCommand('Copy')
|
||||
if (result) {
|
||||
ElMessage.success("复制成功")
|
||||
}
|
||||
document.body.removeChild(textarea)
|
||||
}
|
||||
el.addEventListener('click', el.handler)
|
||||
},
|
||||
updated(el, binding) {
|
||||
el.$value = binding.value
|
||||
},
|
||||
unmounted(el) {
|
||||
el.removeEventListener('click', el.handler)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
export default {
|
||||
mounted(el, binding) {
|
||||
let oDiv = el; //当前元素
|
||||
let firstTime: number;
|
||||
let lastTime: number;
|
||||
//禁止选择网页上的文字
|
||||
// document.onselectstart = function() {
|
||||
// return false;
|
||||
// };
|
||||
oDiv.onmousedown = function (e) {
|
||||
//鼠标按下,计算当前元素距离可视区的距离
|
||||
let disX = e.clientX - oDiv.offsetLeft;
|
||||
let disY = e.clientY - oDiv.offsetTop;
|
||||
document.onmousemove = function (e) {
|
||||
oDiv.setAttribute('drag-flag', true);
|
||||
firstTime = new Date().getTime();
|
||||
//通过事件委托,计算移动的距离
|
||||
let l = e.clientX - disX;
|
||||
let t = e.clientY - disY;
|
||||
|
||||
//移动当前元素
|
||||
|
||||
if (t > 0 && t < document.body.clientHeight - 50) {
|
||||
oDiv.style.top = t + "px";
|
||||
}
|
||||
if (l > 0 && l < document.body.clientWidth - 50) {
|
||||
oDiv.style.left = l + "px";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
document.onmouseup = function () {
|
||||
lastTime = new Date().getTime();
|
||||
if ((lastTime - firstTime) > 200) {
|
||||
oDiv.setAttribute('drag-flag', false);
|
||||
}
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
//return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import {rolePermission} from '@/utils/permission'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const {value} = binding
|
||||
if (Array.isArray(value)) {
|
||||
let ishas = false
|
||||
value.forEach(item => {
|
||||
if (rolePermission(item)) {
|
||||
ishas = true
|
||||
}
|
||||
})
|
||||
if (ishas) {
|
||||
el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
if (rolePermission(value)) {
|
||||
el.parentNode.removeChild(el)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import {rolePermission} from '@/utils/permission'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const {value} = binding
|
||||
if (Array.isArray(value)) {
|
||||
let ishas = false;
|
||||
value.forEach(item => {
|
||||
if (rolePermission(item)) {
|
||||
ishas = true;
|
||||
}
|
||||
})
|
||||
if (!ishas) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
if (!rolePermission(value)) {
|
||||
el.parentNode && el.parentNode.removeChild(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import tools from '@/utils/tools'
|
||||
|
||||
var Time = {
|
||||
//获取当前时间戳
|
||||
getUnix: function () {
|
||||
var date = new Date();
|
||||
return date.getTime();
|
||||
},
|
||||
//获取今天0点0分0秒的时间戳
|
||||
getTodayUnix: function () {
|
||||
var date = new Date();
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
return date.getTime();
|
||||
},
|
||||
//获取今年1月1日0点0秒的时间戳
|
||||
getYearUnix: function () {
|
||||
var date = new Date();
|
||||
date.setMonth(0);
|
||||
date.setDate(1);
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
return date.getTime();
|
||||
},
|
||||
//获取标准年月日
|
||||
getLastDate: function (time) {
|
||||
var date = new Date(time);
|
||||
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
|
||||
return date.getFullYear() + '-' + month + '-' + day;
|
||||
},
|
||||
//转换时间
|
||||
getFormateTime: function (timestamp) {
|
||||
timestamp = new Date(timestamp)
|
||||
var now = this.getUnix();
|
||||
var today = this.getTodayUnix();
|
||||
//var year = this.getYearUnix();
|
||||
var timer = (now - timestamp) / 1000;
|
||||
var tip = '';
|
||||
|
||||
if (timer <= 0) {
|
||||
tip = '刚刚';
|
||||
} else if (Math.floor(timer / 60) <= 0) {
|
||||
tip = '刚刚';
|
||||
} else if (timer < 3600) {
|
||||
tip = Math.floor(timer / 60) + '分钟前';
|
||||
} else if (timer >= 3600 && (timestamp - today >= 0)) {
|
||||
tip = Math.floor(timer / 3600) + '小时前';
|
||||
} else if (timer / 86400 <= 31) {
|
||||
tip = Math.ceil(timer / 86400) + '天前';
|
||||
} else {
|
||||
tip = this.getLastDate(timestamp);
|
||||
}
|
||||
return tip;
|
||||
}
|
||||
}
|
||||
|
||||
export default (el, binding) => {
|
||||
let {value, modifiers} = binding
|
||||
if (!value) {
|
||||
return false
|
||||
}
|
||||
if (value.toString().length == 10) {
|
||||
value = value * 1000
|
||||
}
|
||||
if (modifiers.tip) {
|
||||
el.innerHTML = Time.getFormateTime(value)
|
||||
el.__timeout__ = setInterval(() => {
|
||||
el.innerHTML = Time.getFormateTime(value)
|
||||
}, 60000)
|
||||
} else {
|
||||
const format = el.getAttribute('format') || undefined
|
||||
el.innerHTML = tools.dateFormat(value, format)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,35 +4,36 @@
|
|||
</div>
|
||||
<template v-for="navMenu in navMenus" v-bind:key="navMenu">
|
||||
<el-menu-item v-if="!hasChildren(navMenu)" :index="navMenu.path">
|
||||
<a v-if="navMenu.meta&&navMenu.meta.type=='link'" :href="navMenu.path" target="_blank" @click.stop='()=>{}'></a>
|
||||
<el-icon v-if="navMenu.meta&&navMenu.meta.icon"><component :is="navMenu.meta.icon || 'el-icon-menu'"/></el-icon>
|
||||
<a v-if="navMenu.meta&&navMenu.meta.type=='link'" :href="navMenu.path" target="_blank"
|
||||
@click.stop='()=>{}'></a>
|
||||
<el-icon v-if="navMenu.meta&&navMenu.meta.icon">
|
||||
<component :is="navMenu.meta.icon || 'el-icon-menu'"/>
|
||||
</el-icon>
|
||||
<template #title>
|
||||
<span>{{navMenu.meta.title}}</span>
|
||||
<span v-if="navMenu.meta.tag" class="menu-tag">{{navMenu.meta.tag}}</span>
|
||||
<span>{{ navMenu.meta.title }}</span>
|
||||
<span v-if="navMenu.meta.tag" class="menu-tag">{{ navMenu.meta.tag }}</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
<el-sub-menu v-else :index="navMenu.path">
|
||||
<template #title>
|
||||
<el-icon v-if="navMenu.meta&&navMenu.meta.icon"><component :is="navMenu.meta.icon || 'el-icon-menu'"/></el-icon>
|
||||
<span>{{navMenu.meta.title}}</span>
|
||||
<span v-if="navMenu.meta.tag" class="menu-tag">{{navMenu.meta.tag}}</span>
|
||||
<el-icon v-if="navMenu.meta&&navMenu.meta.icon">
|
||||
<component :is="navMenu.meta.icon || 'el-icon-menu'"/>
|
||||
</el-icon>
|
||||
<span>{{ navMenu.meta.title }}</span>
|
||||
<span v-if="navMenu.meta.tag" class="menu-tag">{{ navMenu.meta.tag }}</span>
|
||||
</template>
|
||||
<NavMenu :navMenus="navMenu.children"></NavMenu>
|
||||
</el-sub-menu>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NavMenu',
|
||||
props: ['navMenus'],
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
hasChildren(item) {
|
||||
return item.children && !item.children.every(item => item.meta.hidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
<script setup name="NavMenu">
|
||||
import {defineProps} from 'vue';
|
||||
|
||||
const props = defineProps(['navMenus']);
|
||||
|
||||
function hasChildren(item) {
|
||||
return item.children && !item.children.every(item => item.meta.hidden)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,20 @@
|
|||
<template>
|
||||
<div ref="" class="mobile-nav-button" @click="showMobileNav($event)" v-drag draggable="false"><el-icon><el-icon-menu /></el-icon></div>
|
||||
<div ref="" class="mobile-nav-button" @click="showMobileNav($event)" v-drag draggable="false">
|
||||
<el-icon>
|
||||
<el-icon-menu/>
|
||||
</el-icon>
|
||||
</div>
|
||||
|
||||
<el-drawer ref="mobileNavBox" title="移动端菜单" :size="240" v-model="nav" direction="ltr" :with-header="false" destroy-on-close>
|
||||
<el-drawer ref="mobileNavBox" title="移动端菜单" :size="240" v-model="nav" direction="ltr" :with-header="false"
|
||||
destroy-on-close>
|
||||
<el-container class="mobile-nav">
|
||||
<el-header>
|
||||
<div class="logo-bar"><img class="logo" src="/images/logo.png"><span>{{ $CONFIG.APP_NAME }}</span></div>
|
||||
<div class="logo-bar"><img class="logo" src="/images/logo.png"><span>{{ config.APP_NAME }}</span></div>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<el-scrollbar>
|
||||
<el-menu :default-active="$route.meta.active || $route.fullPath" @select="select" router background-color="#212d3d" text-color="#fff" active-text-color="#409EFF">
|
||||
<el-menu :default-active="route.meta.active || route.fullPath" @select="select" router
|
||||
background-color="#212d3d" text-color="#fff" active-text-color="#409EFF">
|
||||
<NavMenu :navMenus="menu"></NavMenu>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
|
|
@ -18,119 +24,107 @@
|
|||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavMenu from './NavMenu.vue';
|
||||
<script setup>
|
||||
import NavMenu from './NavMenu.vue';
|
||||
import {ref, getCurrentInstance} from "vue";
|
||||
import {getMenu} from "@/utils/route"
|
||||
import config from "@/config/index";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NavMenu
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nav: false,
|
||||
menu: []
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
const {proxy} = getCurrentInstance()
|
||||
const route = useRoute();
|
||||
|
||||
},
|
||||
created() {
|
||||
var menu = this.$router.getMenu()
|
||||
this.menu = this.filterUrl(menu)
|
||||
},
|
||||
let nav = ref(false)
|
||||
let menu = getMenu()
|
||||
|
||||
watch: {
|
||||
menu = filterUrl(menu)
|
||||
|
||||
},
|
||||
methods: {
|
||||
showMobileNav(e){
|
||||
var isdrag = e.currentTarget.getAttribute('drag-flag')
|
||||
if (isdrag == 'true') {
|
||||
return false;
|
||||
}else{
|
||||
this.nav = true;
|
||||
}
|
||||
|
||||
},
|
||||
select(){
|
||||
this.$refs.mobileNavBox.handleClose()
|
||||
},
|
||||
//转换外部链接的路由
|
||||
filterUrl(map){
|
||||
var newMap = []
|
||||
map && map.forEach(item => {
|
||||
item.meta = item.meta?item.meta:{};
|
||||
//处理隐藏
|
||||
if(item.meta.hidden || item.meta.type=="button"){
|
||||
return false
|
||||
}
|
||||
//处理http
|
||||
if(item.meta.type=='iframe'){
|
||||
item.path = `/i/${item.name}`;
|
||||
}
|
||||
//递归循环
|
||||
if(item.children&&item.children.length > 0){
|
||||
item.children = this.filterUrl(item.children);
|
||||
}
|
||||
newMap.push(item)
|
||||
})
|
||||
return newMap;
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
drag(el){
|
||||
let oDiv = el; //当前元素
|
||||
let firstTime='',lastTime='';
|
||||
//禁止选择网页上的文字
|
||||
// document.onselectstart = function() {
|
||||
// return false;
|
||||
// };
|
||||
oDiv.onmousedown = function(e){
|
||||
//鼠标按下,计算当前元素距离可视区的距离
|
||||
let disX = e.clientX - oDiv.offsetLeft;
|
||||
let disY = e.clientY - oDiv.offsetTop;
|
||||
document.onmousemove = function(e){
|
||||
oDiv.setAttribute('drag-flag', true);
|
||||
firstTime = new Date().getTime();
|
||||
//通过事件委托,计算移动的距离
|
||||
let l = e.clientX - disX;
|
||||
let t = e.clientY - disY;
|
||||
|
||||
//移动当前元素
|
||||
|
||||
if(t > 0 && t < document.body.clientHeight - 50){
|
||||
oDiv.style.top = t + "px";
|
||||
}
|
||||
if(l > 0 && l < document.body.clientWidth - 50){
|
||||
oDiv.style.left = l + "px";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
document.onmouseup = function(){
|
||||
lastTime = new Date().getTime();
|
||||
if( (lastTime - firstTime)>200 ){
|
||||
oDiv.setAttribute('drag-flag', false);
|
||||
}
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
//return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
function showMobileNav(e) {
|
||||
var isdrag = e.currentTarget.getAttribute('drag-flag')
|
||||
if (isdrag == 'true') {
|
||||
return false;
|
||||
} else {
|
||||
nav.value = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function select() {
|
||||
proxy.$refs.mobileNavBox.handleClose()
|
||||
}
|
||||
|
||||
//转换外部链接的路由
|
||||
function filterUrl(map) {
|
||||
var newMap = []
|
||||
map && map.forEach(item => {
|
||||
item.meta = item.meta ? item.meta : {};
|
||||
//处理隐藏
|
||||
if (item.meta.hidden || item.meta.type == "button") {
|
||||
return false
|
||||
}
|
||||
//处理http
|
||||
if (item.meta.type == 'iframe') {
|
||||
item.path = `/i/${item.name}`;
|
||||
}
|
||||
//递归循环
|
||||
if (item.children && item.children.length > 0) {
|
||||
item.children = filterUrl(item.children);
|
||||
}
|
||||
newMap.push(item)
|
||||
})
|
||||
return newMap;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mobile-nav-button {position: fixed;bottom:10px;left:10px;z-index: 10;width: 50px;height: 50px;background: #409EFF;box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 1);border-radius: 50%;display: flex;align-items: center;justify-content: center;}
|
||||
.mobile-nav-button i {color: #fff;font-size: 20px;}
|
||||
.mobile-nav-button {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
z-index: 10;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: #409EFF;
|
||||
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 1);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mobile-nav {background: #212d3d;}
|
||||
.mobile-nav .el-header {background: transparent;border: 0;}
|
||||
.mobile-nav .el-main {padding:0;}
|
||||
.mobile-nav .logo-bar {display: flex;align-items: center;font-weight: bold;font-size: 20px;color: #fff;}
|
||||
.mobile-nav .logo-bar img {width: 30px;margin-right: 10px;}
|
||||
.mobile-nav .el-submenu__title:hover {background: #fff!important;}
|
||||
.mobile-nav-button i {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
background: #212d3d;
|
||||
}
|
||||
|
||||
.mobile-nav .el-header {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.mobile-nav .el-main {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mobile-nav .logo-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mobile-nav .logo-bar img {
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mobile-nav .el-submenu__title:hover {
|
||||
background: #fff !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ onMounted(() => {
|
|||
})
|
||||
|
||||
watch(route, (e) => {
|
||||
console.log(111)
|
||||
addViewTags(e);
|
||||
//判断标签容器是否出现滚动条
|
||||
nextTick(() => {
|
||||
|
|
@ -92,7 +93,7 @@ watch(route, (e) => {
|
|||
let targetTag = tags.querySelector(".active")
|
||||
targetTag.scrollIntoView()
|
||||
//显示提示
|
||||
if (!tipDisplayed) {
|
||||
if (!tipDisplayed.value) {
|
||||
proxy.$msgbox({
|
||||
type: 'warning',
|
||||
center: true,
|
||||
|
|
@ -100,14 +101,13 @@ watch(route, (e) => {
|
|||
message: '当前标签数量过多,可通过鼠标滚轴滚动标签栏。关闭标签数量可减少系统性能消耗。',
|
||||
confirmButtonText: '知道了'
|
||||
})
|
||||
tipDisplayed = true
|
||||
tipDisplayed.value = true
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
watch(() => contextMenuVisible, (value) => {
|
||||
watch(contextMenuVisible, (value) => {
|
||||
var cm = function (e) {
|
||||
let sp = document.getElementById("contextmenu");
|
||||
if (sp && !sp.contains(e.target)) {
|
||||
|
|
@ -173,7 +173,7 @@ function closeSelectedTag(tag, autoPushLatestView = true) {
|
|||
//tag右键
|
||||
function openContextMenu(e, tag) {
|
||||
contextMenuItem = tag;
|
||||
contextMenuVisible = true;
|
||||
contextMenuVisible.value = true;
|
||||
left.value = e.clientX + 1;
|
||||
top.value = e.clientY + 1;
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ function openWindow() {
|
|||
closeSelectedTag(nowTag)
|
||||
}
|
||||
window.open(url);
|
||||
contextMenuVisible = false
|
||||
contextMenuVisible.value = false
|
||||
}
|
||||
|
||||
//横向滚动
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@
|
|||
<el-breadcrumb separator-icon="el-icon-arrow-right" class="hidden-sm-and-down">
|
||||
<transition-group name="breadcrumb">
|
||||
<template v-for="item in breadList" :key="item.title">
|
||||
<el-breadcrumb-item v-if="item.path!='/' && !item.meta.hiddenBreadcrumb" :key="item.meta.title"><el-icon class="icon" v-if="item.meta.icon"><component :is="item.meta.icon" /></el-icon>{{item.meta.title}}</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-if="item.path!='/' && !item.meta.hiddenBreadcrumb"
|
||||
:key="item.meta.title">
|
||||
<el-icon class="icon" v-if="item.meta.icon">
|
||||
<component :is="item.meta.icon"/>
|
||||
</el-icon>
|
||||
{{ item.meta.title }}
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
|
|
@ -16,34 +22,46 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
breadList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getBreadcrumb();
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getBreadcrumb();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb(){
|
||||
let matched = this.$route.meta.breadcrumb;
|
||||
this.breadList = matched;
|
||||
}
|
||||
}
|
||||
}
|
||||
<script setup>
|
||||
import {ref, watch} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
let breadList = ref([])
|
||||
|
||||
getBreadcrumb();
|
||||
|
||||
watch(route, () => {
|
||||
getBreadcrumb()
|
||||
})
|
||||
|
||||
function getBreadcrumb() {
|
||||
breadList.value = route.meta.breadcrumb;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-breadcrumb {margin-left: 15px;}
|
||||
.el-breadcrumb .el-breadcrumb__inner .icon {font-size: 14px;margin-right: 5px;float: left;}
|
||||
.breadcrumb-enter-active,.breadcrumb-leave-active {transition: all 0.3s;}
|
||||
.breadcrumb-enter-from,.breadcrumb-leave-active {opacity: 0;transform: translateX(20px);}
|
||||
.breadcrumb-leave-active {position: absolute;}
|
||||
.el-breadcrumb {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.el-breadcrumb .el-breadcrumb__inner .icon {
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.breadcrumb-enter-active, .breadcrumb-leave-active {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.breadcrumb-enter-from, .breadcrumb-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.breadcrumb-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
14
src/pi.ts
14
src/pi.ts
|
|
@ -1,10 +1,24 @@
|
|||
import * as elIcons from '@element-plus/icons-vue'
|
||||
import {App} from "vue";
|
||||
import * as piIcons from '@assets/icons'
|
||||
import auth from './directives/auth'
|
||||
import role from './directives/role'
|
||||
import excludeRole from './directives/excludeRole'
|
||||
import time from './directives/time'
|
||||
import copy from './directives/copy'
|
||||
import drag from './directives/drag'
|
||||
import errorHandler from "@/utils/errorHandler";
|
||||
|
||||
export default {
|
||||
install(app: App) {
|
||||
//注册全局指令
|
||||
app.directive('auth', auth)
|
||||
app.directive('role', role)
|
||||
app.directive('exclude-role', excludeRole)
|
||||
app.directive('time', time)
|
||||
app.directive('copy', copy)
|
||||
app.directive('drag', drag)
|
||||
|
||||
//统一注册el-icon图标
|
||||
for (let icon in elIcons) {
|
||||
app.component(`ElIcon${icon}`, elIcons[icon])
|
||||
|
|
|
|||
|
|
@ -2,32 +2,29 @@
|
|||
* 全局代码错误捕捉
|
||||
* 比如 null.length 就会被捕捉到
|
||||
*/
|
||||
import {nextTick} from "vue";
|
||||
|
||||
export default (error, vm)=>{
|
||||
//过滤HTTP请求错误
|
||||
if(error.status || error.status==0){
|
||||
return false
|
||||
}
|
||||
|
||||
// var errorMap = {
|
||||
// InternalError: "Javascript引擎内部错误",
|
||||
// ReferenceError: "未找到对象",
|
||||
// TypeError: "使用了错误的类型或对象",
|
||||
// RangeError: "使用内置对象时,参数超范围",
|
||||
// SyntaxError: "语法错误",
|
||||
// EvalError: "错误的使用了Eval",
|
||||
// URIError: "URI错误"
|
||||
// }
|
||||
// var errorName = errorMap[error.name] || "未知错误"
|
||||
var errorMap = {
|
||||
InternalError: "Javascript引擎内部错误",
|
||||
ReferenceError: "未找到对象",
|
||||
TypeError: "使用了错误的类型或对象",
|
||||
RangeError: "使用内置对象时,参数超范围",
|
||||
SyntaxError: "语法错误",
|
||||
EvalError: "错误的使用了Eval",
|
||||
URIError: "URI错误"
|
||||
}
|
||||
var errorName = errorMap[error.name] || "未知错误"
|
||||
|
||||
console.error(`[PI error]: ${error}`);
|
||||
//throw error;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
// vm.$notify.error({
|
||||
// title: errorName,
|
||||
// message: error
|
||||
// });
|
||||
vm.$notify.error({
|
||||
title: errorName,
|
||||
message: error
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import tools from '@/utils/tools';
|
||||
|
||||
export function permission(data) {
|
||||
let permissions = tools.data.get("PERMISSIONS");
|
||||
if (!permissions) {
|
||||
return false;
|
||||
}
|
||||
return permissions.includes(data);
|
||||
}
|
||||
|
||||
export function noPermission(data) {
|
||||
return !permission(data);
|
||||
}
|
||||
|
||||
export function rolePermission(data) {
|
||||
let roles = tools.data.get("ROLE");
|
||||
if (!roles) {
|
||||
return false;
|
||||
}
|
||||
return roles.includes(data);
|
||||
}
|
||||
|
||||
export function noRolePermission(data) {
|
||||
return !rolePermission(data);
|
||||
}
|
||||
|
|
@ -102,6 +102,32 @@ const tools = {
|
|||
element.webkitRequestFullscreen();
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 复制对象 */
|
||||
objCopy: function (obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
},
|
||||
/* 日期格式化 */
|
||||
dateFormat: function (date, fmt='yyyy-MM-dd hh:mm:ss') {
|
||||
date = new Date(date)
|
||||
var o = {
|
||||
"M+" : date.getMonth()+1, //月份
|
||||
"d+" : date.getDate(), //日
|
||||
"h+" : date.getHours(), //小时
|
||||
"m+" : date.getMinutes(), //分
|
||||
"s+" : date.getSeconds(), //秒
|
||||
"q+" : Math.floor((date.getMonth()+3)/3), //季度
|
||||
"S" : date.getMilliseconds() //毫秒
|
||||
};
|
||||
if(/(y+)/.test(fmt)) {
|
||||
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
|
||||
}
|
||||
for(var k in o) {
|
||||
if(new RegExp("("+ k +")").test(fmt)){
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue