'admin-21.08.01:更新修复请查看CHANGELOG.md文件或查看标签'

This commit is contained in:
lyt-Top 2021-08-01 18:30:30 +08:00
parent 1dd6b653e7
commit 28edd79b1c
29 changed files with 523 additions and 383 deletions

2
.env
View File

@ -4,5 +4,5 @@ VITE_PORT = 8888
# open 运行 npm run dev 时自动打开浏览器
VITE_OPEN = false
# public path 配置线上环境路径(打包)
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
VITE_PUBLIC_PATH = /vue-next-admin-preview/

View File

@ -2,6 +2,19 @@
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等适配手机、平板、pc 的后台开源免费模板库vue2.x 请切换 vue-prev-admin 分支)
## 1.0.14
`2021.07.29`
- 🌟 更新 依赖更新最新版本vue、vuex、vue-router,出现问题,请手动降级。版本查看:<a href="https://www.npmjs.com/" target="_blank">vnpm</a>
- 🎯 优化 数据可视化图表演示加载卡顿问题、优化有图表的演示界面
- 🎯 优化 路由参数演示界面
- 🎯 优化 tagsView 操作演示界面由于存在相同路由多标签必须要传全部参数值query 或者 params
- 🎉 新增 开启 TagsView 共用开启时多个路由菜单共用一个详情组件参数为后点击的覆盖前面点击的tagsView 中只会出现一个(不支持同时出现多个 tagsView 标签))。关闭时:(多个路由菜单共用一个详情组件,参数不同,会同时出现多个 tagsView 标签)
- 🐞 修复 tagsView 共用(单标签)时,右键菜单功能点击,参数不对的问题(第 2n+个参数未覆盖第一个参数值)
- 🐞 修复 多 tagsView 标签(参数不同)、单个 tagsView 标签公用(参数不同)所带来的刷新功能、横向自动滚动等问题
- 🐞 修复 处理全屏若干问题,<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/12" target="_blank">pr!12</a>,感谢群友@另一个前端
## 1.0.13
`2021.07.25`

View File

@ -1,6 +1,6 @@
{
"name": "vue-next-admin",
"version": "1.0.13",
"version": "1.0.14",
"scripts": {
"dev": "vite",
"build": "vite build",
@ -8,12 +8,12 @@
},
"dependencies": {
"axios": "^0.21.1",
"countup.js": "^2.0.7",
"countup.js": "^2.0.8",
"cropperjs": "^1.5.12",
"echarts": "^5.1.2",
"echarts-gl": "^2.0.6",
"echarts-gl": "^2.0.7",
"echarts-wordcloud": "^2.0.0",
"element-plus": "^1.0.2-beta.57",
"element-plus": "^1.0.2-beta.65",
"mitt": "^3.0.0",
"nprogress": "^0.2.0",
"print-js": "^1.6.0",
@ -21,34 +21,34 @@
"screenfull": "^5.1.0",
"sortablejs": "^1.14.0",
"splitpanes": "^3.0.4",
"vue": "^3.0.11",
"vue": "^3.1.5",
"vue-clipboard3": "^1.0.1",
"vue-grid-layout": "^3.0.0-beta1",
"vue-i18n": "^9.1.7",
"vue-router": "^4.0.8",
"vue-router": "^4.0.10",
"vue-web-screen-shot": "^1.2.0",
"vuex": "^4.0.1",
"wangeditor": "^4.7.5"
"vuex": "^4.0.2",
"wangeditor": "^4.7.6"
},
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/clipboard": "^2.0.1",
"@types/node": "^16.4.1",
"@types/node": "^16.4.9",
"@types/nprogress": "^0.2.0",
"@types/sortablejs": "^1.10.7",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"@vitejs/plugin-vue": "^1.2.5",
"@typescript-eslint/eslint-plugin": "^4.28.5",
"@typescript-eslint/parser": "^4.28.5",
"@vitejs/plugin-vue": "^1.3.0",
"@vue/compiler-sfc": "^3.1.5",
"dotenv": "^10.0.0",
"eslint": "^7.31.0",
"eslint-plugin-vue": "^7.14.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^7.15.0",
"prettier": "^2.3.2",
"sass": "^1.36.0",
"sass": "^1.37.0",
"sass-loader": "^12.1.0",
"typescript": "^4.3.5",
"vite": "^2.4.3",
"vue-eslint-parser": "^7.9.0"
"vite": "^2.4.4",
"vue-eslint-parser": "^7.10.0"
},
"browserslist": [
"> 1%",

View File

@ -2,6 +2,7 @@
<router-view v-show="getThemeConfig.lockScreenTime !== 0" />
<LockScreen v-if="getThemeConfig.isLockScreen" />
<Setings ref="setingsRef" v-show="getThemeConfig.lockScreenTime !== 0" />
<CloseFull />
</template>
<script lang="ts">
@ -13,9 +14,10 @@ import { Local } from '/@/utils/storage';
import setIntroduction from '/@/utils/setIconfont';
import LockScreen from '/@/layout/lockScreen/index.vue';
import Setings from '/@/layout/navBars/breadcrumb/setings.vue';
import CloseFull from '/@/layout/navBars/breadcrumb/closeFull.vue';
export default defineComponent({
name: 'app',
components: { LockScreen, Setings },
components: { LockScreen, Setings, CloseFull },
setup() {
const { proxy } = getCurrentInstance() as any;
const setingsRef = ref();

View File

@ -107,6 +107,7 @@ export default {
closeOther: 'closeOther',
closeAll: 'closeAll',
fullscreen: 'fullscreen',
closeFullscreen: 'closeFullscreen',
},
notFound: {
foundTitle: 'Wrong address input, please re-enter the address~',
@ -147,6 +148,7 @@ export default {
fourIsTagsviewIcon: 'Open tagsview Icon',
fourIsCacheTagsView: 'Enable tagsview cache',
fourIsSortableTagsView: 'Enable tagsview drag',
fourIsShareTagsView: 'Enable tagsview sharing',
fourIsFooter: 'Open footer',
fourIsGrayscale: 'Grey model',
fourIsInvert: 'Color weak mode',

View File

@ -107,6 +107,7 @@ export default {
closeOther: '关闭其它',
closeAll: '全部关闭',
fullscreen: '当前页全屏',
closeFullscreen: '关闭全屏',
},
notFound: {
foundTitle: '地址输入错误,请重新输入地址~',
@ -147,6 +148,7 @@ export default {
fourIsTagsviewIcon: '开启 Tagsview 图标',
fourIsCacheTagsView: '开启 TagsView 缓存',
fourIsSortableTagsView: '开启 TagsView 拖拽',
fourIsShareTagsView: '开启 TagsView 共用',
fourIsFooter: '开启 Footer',
fourIsGrayscale: '灰色模式',
fourIsInvert: '色弱模式',

View File

@ -107,6 +107,7 @@ export default {
closeOther: '關閉其它',
closeAll: '全部關閉',
fullscreen: '當前頁全屏',
closeFullscreen: '關閉全屏',
},
notFound: {
foundTitle: '地址輸入錯誤,請重新輸入地址~',
@ -147,6 +148,7 @@ export default {
fourIsTagsviewIcon: '開啟 Tagsview 圖標',
fourIsCacheTagsView: '開啟 TagsView 緩存',
fourIsSortableTagsView: '開啟 TagsView 拖拽',
fourIsShareTagsView: '開啟 TagsView 共用',
fourIsFooter: '開啟 Footer',
fourIsGrayscale: '灰色模式',
fourIsInvert: '色弱模式',

View File

@ -1,22 +1,20 @@
<template>
<template v-if="clientWidth > 1000">
<el-aside class="layout-aside" :class="setCollapseWidth" v-show="!isCurrenFullscreen">
<el-aside class="layout-aside" :class="setCollapseWidth" v-show="!isTagsViewCurrenFull">
<Logo v-if="setShowLogo" />
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
<Vertical :menuList="menuList" :class="setCollapseWidth" />
</el-scrollbar>
</el-aside>
</template>
<template v-else>
<el-drawer v-model="getThemeConfig.isCollapse" :with-header="false" direction="ltr" size="220px">
<el-aside class="layout-aside w100 h100">
<Logo v-if="setShowLogo" />
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
<Vertical :menuList="menuList" />
</el-scrollbar>
</el-aside>
</el-drawer>
</template>
<el-drawer v-model="getThemeConfig.isCollapse" :with-header="false" direction="ltr" size="220px" v-else>
<el-aside class="layout-aside w100 h100">
<Logo v-if="setShowLogo" />
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
<Vertical :menuList="menuList" />
</el-scrollbar>
</el-aside>
</el-drawer>
</template>
<script lang="ts">
@ -39,8 +37,8 @@ export default {
return store.state.themeConfig.themeConfig;
});
//
const isCurrenFullscreen = computed(() => {
return store.state.tagsViewRoutes.isCurrenFullscreen;
const isTagsViewCurrenFull = computed(() => {
return store.state.tagsViewRoutes.isTagsViewCurrenFull;
});
// /
const setCollapseWidth = computed(() => {
@ -126,7 +124,7 @@ export default {
setCollapseWidth,
setShowLogo,
getThemeConfig,
isCurrenFullscreen,
isTagsViewCurrenFull,
...toRefs(state),
};
},

View File

@ -1,5 +1,5 @@
<template>
<div class="layout-columns-aside" v-show="!isCurrenFullscreen">
<div class="layout-columns-aside">
<el-scrollbar>
<ul>
<li
@ -70,10 +70,6 @@ export default {
const setColumnsAsidelayout = computed(() => {
return store.state.themeConfig.themeConfig.columnsAsideLayout;
});
//
const isCurrenFullscreen = computed(() => {
return store.state.tagsViewRoutes.isCurrenFullscreen;
});
//
const setColumnsAsideMove = (k: number) => {
state.liIndex = k;
@ -156,7 +152,6 @@ export default {
setColumnsAsideStyle,
setColumnsAsidelayout,
onColumnsAsideMenuClick,
isCurrenFullscreen,
...toRefs(state),
};
},
@ -216,8 +211,8 @@ export default {
position: absolute;
left: 50%;
top: 2px;
height: 50px;
width: 60px;
height: 44px;
width: 65px;
transform: translateX(-50%);
z-index: 0;
transition: 0.3s ease-in-out;
@ -226,6 +221,7 @@ export default {
.columns-card {
@extend .columns-round;
top: 0;
height: 50px;
width: 100%;
border-radius: 0;
}

View File

@ -1,5 +1,5 @@
<template>
<el-header class="layout-header" :height="setHeaderHeight" v-show="!isCurrenFullscreen">
<el-header class="layout-header" :height="setHeaderHeight" v-show="!isTagsViewCurrenFull">
<NavBarsIndex />
</el-header>
</template>
@ -20,12 +20,12 @@ export default {
else return '50px';
});
//
const isCurrenFullscreen = computed(() => {
return store.state.tagsViewRoutes.isCurrenFullscreen;
const isTagsViewCurrenFull = computed(() => {
return store.state.tagsViewRoutes.isTagsViewCurrenFull;
});
return {
setHeaderHeight,
isCurrenFullscreen,
isTagsViewCurrenFull,
};
},
};

View File

@ -0,0 +1,65 @@
<template>
<div class="layout-navbars-close-full" v-if="isTagsViewCurrenFull">
<div class="layout-navbars-close-full-box" :title="$t('message.tagsView.closeFullscreen')" @click="onCloseFullscreen">
<i class="el-icon-close"></i>
</div>
</div>
</template>
<script lang="ts">
import { toRefs, reactive, computed } from 'vue';
import { useStore } from '/@/store/index';
export default {
name: 'layoutCloseFull',
setup() {
const store = useStore();
const state: any = reactive({});
//
const isTagsViewCurrenFull = computed(() => {
return store.state.tagsViewRoutes.isTagsViewCurrenFull;
});
//
const onCloseFullscreen = () => {
store.dispatch('tagsViewRoutes/setCurrenFullscreen', false);
};
return {
isTagsViewCurrenFull,
onCloseFullscreen,
...toRefs(state),
};
},
};
</script>
<style scoped lang="scss">
.layout-navbars-close-full {
position: fixed;
z-index: 9999999999;
right: -30px;
top: -30px;
.layout-navbars-close-full-box {
width: 60px;
height: 60px;
border-radius: 100%;
position: relative;
cursor: pointer;
background: rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
i {
position: absolute;
left: 11px;
top: 35px;
color: #333333;
transition: all 0.3s ease;
}
&:hover {
background: rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
i {
color: var(--color-primary);
transition: all 0.3s ease;
}
}
}
}
</style>

View File

@ -207,6 +207,12 @@
<el-switch v-model="getThemeConfig.isSortableTagsView" @change="onSortableTagsViewChange"></el-switch>
</div>
</div>
<div class="layout-breadcrumb-seting-bar-flex mt15">
<div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsShareTagsView') }}</div>
<div class="layout-breadcrumb-seting-bar-flex-value">
<el-switch v-model="getThemeConfig.isShareTagsView" @change="onShareTagsViewChange"></el-switch>
</div>
</div>
<div class="layout-breadcrumb-seting-bar-flex mt15">
<div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsFooter') }}</div>
<div class="layout-breadcrumb-seting-bar-flex-value">
@ -476,6 +482,11 @@ export default defineComponent({
proxy.mittBus.emit('openOrCloseSortable');
setLocalThemeConfig();
};
// 4 --> TagsView
const onShareTagsViewChange = () => {
proxy.mittBus.emit('openShareTagsView');
setLocalThemeConfig();
};
// 4 --> /
const onAddFilterChange = (attr: string) => {
if (attr === 'grayscale') {
@ -654,6 +665,7 @@ export default defineComponent({
onClassicSplitMenuChange,
onIsBreadcrumbChange,
onSortableTagsViewChange,
onShareTagsViewChange,
onCopyConfigClick,
};
},

View File

@ -225,31 +225,12 @@ export default {
break;
}
};
// F11
const initOnkeydown = () => {
document.onkeydown = (event) => {
var e = event || window.event || arguments.callee.caller.arguments[0];
if (e && e.keyCode === 122 && !state.isScreenfull) {
e.preventDefault();
onScreenfullClick();
}
};
};
//
onMounted(() => {
initOnkeydown();
if (Local.get('themeConfig')) {
initI18n();
initComponentSize();
}
document.onkeydown = (event) => {
var e = event || window.event || arguments.callee.caller.arguments[0];
// F11
if (e && e.keyCode === 122 && !state.isScreenfull) {
e.preventDefault();
onScreenfullClick();
}
};
});
return {
getUserInfos,

View File

@ -46,7 +46,7 @@ export default defineComponent({
icon: 'iconfont icon-fullscreen',
},
],
path: {},
item: {},
});
// x,y
const dropdowns = computed(() => {
@ -54,11 +54,11 @@ export default defineComponent({
});
//
const onCurrentContextmenuClick = (id: number) => {
emit('currentContextmenuClick', { id, path: state.path });
emit('currentContextmenuClick', Object.assign({}, { id }, state.item));
};
//
const openContextmenu = (item: any) => {
state.path = item.path;
state.item = item;
item.meta.isAffix ? (state.dropdownList[1].affix = true) : (state.dropdownList[1].affix = false);
closeContextmenu();
setTimeout(() => {

View File

@ -1,9 +1,5 @@
<template>
<div
class="layout-navbars-tagsview"
:class="{ 'layout-navbars-tagsview-shadow': getThemeConfig.layout === 'classic' }"
v-show="!isCurrenFullscreen"
>
<div class="layout-navbars-tagsview" :class="{ 'layout-navbars-tagsview-shadow': getThemeConfig.layout === 'classic' }">
<el-scrollbar ref="scrollbarRef" @wheel.native.prevent="onHandleScroll">
<ul class="layout-navbars-tagsview-ul" :class="setTagsStyle" ref="tagsUlRef">
<li
@ -11,7 +7,7 @@
:key="k"
class="layout-navbars-tagsview-ul-li"
:data-name="v.name"
:class="{ 'is-active': isActive(v.path) }"
:class="{ 'is-active': isActive(v) }"
@contextmenu.prevent="onContextmenu(v, $event)"
@click="onTagsClick(v, k)"
:ref="
@ -20,21 +16,21 @@
}
"
>
<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont font14" v-if="isActive(v.path)"></i>
<i class="layout-navbars-tagsview-ul-li-iconfont" :class="v.meta.icon" v-if="!isActive(v.path) && getThemeConfig.isTagsviewIcon"></i>
<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont font14" v-if="isActive(v)"></i>
<i class="layout-navbars-tagsview-ul-li-iconfont" :class="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon"></i>
<span>{{ $t(v.meta.title) }}</span>
<template v-if="isActive(v.path)">
<i class="el-icon-refresh-right ml5" @click.stop="refreshCurrentTagsView(v.path)"></i>
<template v-if="isActive(v)">
<i class="el-icon-refresh-right ml5" @click.stop="refreshCurrentTagsView($route.fullPath)"></i>
<i
class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-active"
v-if="!v.meta.isAffix"
@click.stop="closeCurrentTagsView(v.path)"
@click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
></i>
</template>
<i
class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-three"
v-if="!v.meta.isAffix"
@click.stop="closeCurrentTagsView(v.path)"
@click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
></i>
</li>
</ul>
@ -46,9 +42,12 @@
<script lang="ts">
import { toRefs, reactive, onMounted, computed, ref, nextTick, onBeforeUpdate, onBeforeMount, onUnmounted, getCurrentInstance, watch } from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import Sortable from 'sortablejs';
import { ElMessage } from 'element-plus';
import { useStore } from '/@/store/index';
import { Session } from '/@/utils/storage';
import Sortable from 'sortablejs';
import { NextLoading } from '/@/utils/loading';
import { isObjectValueEqual } from '/@/utils/arrayOperation';
import Contextmenu from '/@/layout/navBars/tagsView/contextmenu.vue';
export default {
name: 'layoutTagsView',
@ -63,6 +62,7 @@ export default {
const route = useRoute();
const router = useRouter();
const state: any = reactive({
routeActive: '',
routePath: route.path,
dropdown: { x: '', y: '' },
tagsRefsIndex: 0,
@ -78,66 +78,120 @@ export default {
const getThemeConfig = computed(() => {
return store.state.themeConfig.themeConfig;
});
//
const isCurrenFullscreen = computed(() => {
return store.state.tagsViewRoutes.isCurrenFullscreen;
});
// tagsView
const isActive = (v) => {
if (getThemeConfig.value.isShareTagsView) {
return v.path === state.routePath;
} else {
return v.url === state.routeActive;
}
};
// tagsViewList
const addBrowserSetSession = (tagsViewList: Array<object>) => {
Session.set('tagsViewList', tagsViewList);
};
// vuex tagsViewRoutes
const getTagsViewRoutes = () => {
state.routePath = route.meta.isDynamic ? route.meta.isDynamicPath : route.path;
const getTagsViewRoutes = async () => {
state.routeActive = await setTagsViewHighlight(route);
state.routePath = (await route.meta.isDynamic) ? route.meta.isDynamicPath : route.path;
state.tagsViewList = [];
if (!store.state.themeConfig.themeConfig.isCacheTagsView) Session.remove('tagsViewList');
state.tagsViewRoutesList = store.state.tagsViewRoutes.tagsViewRoutes;
initTagsView();
};
// vuex isAffix
const initTagsView = () => {
if (Session.get('tagsViewList') && store.state.themeConfig.themeConfig.isCacheTagsView) {
state.tagsViewList = Session.get('tagsViewList');
const initTagsView = async () => {
if (Session.get('tagsViewList') && getThemeConfig.value.isCacheTagsView) {
state.tagsViewList = await Session.get('tagsViewList');
} else {
state.tagsViewRoutesList.map((v: any) => {
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
await state.tagsViewRoutesList.map((v: any) => {
if (v.meta.isAffix && !v.meta.isHide) {
v.url = setTagsViewHighlight(v);
state.tagsViewList.push({ ...v });
}
});
addTagsView(route.path, route);
await addTagsView(route.path, route);
}
// (li)
getTagsRefsIndex(route.path);
//
tagsViewmoveToCurrentTag();
getTagsRefsIndex(getThemeConfig.value.isShareTagsView ? state.routePath : state.routeActive);
};
// 1 tagsViewisHide tagsView
const addTagsView = (path: string, to?: any) => {
// https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
let item = '';
if (to && to.meta.isDynamic) {
if (state.tagsViewList.some((v: any) => v.path === to.meta.isDynamicPath)) return false;
item = state.tagsViewRoutesList.find((v: any) => v.path === to.meta.isDynamicPath);
} else {
if (state.tagsViewList.some((v: any) => v.path === path)) return false;
item = state.tagsViewRoutesList.find((v: any) => v.path === path);
// xxx/:id/:name"
const solveAddTagsView = async (path: string, to?: any) => {
let isDynamicPath = to.meta.isDynamic ? to.meta.isDynamicPath : path;
let current = state.tagsViewList.filter(
(v: any) =>
v.path === isDynamicPath &&
isObjectValueEqual(
to.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
to.meta.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
)
);
if (current.length <= 0) {
// Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead.
let findItem = state.tagsViewRoutesList.find((v: any) => v.path === isDynamicPath);
if (findItem.meta.isAffix) return false;
if (findItem.meta.isLink && !findItem.meta.isIframe) return false;
to.meta.isDynamic ? (findItem.params = to.params) : (findItem.query = to.query);
findItem.url = setTagsViewHighlight(findItem);
state.tagsViewList.push({ ...findItem });
addBrowserSetSession(state.tagsViewList);
}
if (item.meta.isLink && !item.meta.isIframe) return false;
if (to && to.meta.isDynamic) item.params = to?.params ? to?.params : route.params;
else item.query = to?.query ? to?.query : route.query;
state.tagsViewList.push({ ...item });
addBrowserSetSession(state.tagsViewList);
};
// tagsViewList Session Storage
const singleAddTagsView = (path: string, to?: any) => {
let isDynamicPath = to.meta.isDynamic ? to.meta.isDynamicPath : path;
state.tagsViewList.forEach((v) => {
if (
v.path === isDynamicPath &&
!isObjectValueEqual(
to.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
to.meta.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
)
) {
to.meta.isDynamic ? (v.params = to.params) : (v.query = to.query);
v.url = setTagsViewHighlight(v);
addBrowserSetSession(state.tagsViewList);
}
});
};
// 1 tagsViewisHide tagsView
const addTagsView = (path: string, to?: any) => {
//
nextTick(async () => {
// https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
let item = '';
if (to && to.meta.isDynamic) {
// xxx/:id/:name" tagsview
if (!getThemeConfig.value.isShareTagsView) await solveAddTagsView(path, to);
else await singleAddTagsView(path, to);
if (state.tagsViewList.some((v: any) => v.path === to.meta.isDynamicPath)) return false;
item = state.tagsViewRoutesList.find((v: any) => v.path === to.meta.isDynamicPath);
} else {
// tagsview
if (!getThemeConfig.value.isShareTagsView) await solveAddTagsView(path, to);
else await singleAddTagsView(path, to);
if (state.tagsViewList.some((v: any) => v.path === path)) return false;
item = state.tagsViewRoutesList.find((v: any) => v.path === path);
}
if (item.meta.isLink && !item.meta.isIframe) return false;
if (to && to.meta.isDynamic) item.params = to?.params ? to?.params : route.params;
else item.query = to?.query ? to?.query : route.query;
item.url = setTagsViewHighlight(item);
await state.tagsViewList.push({ ...item });
await addBrowserSetSession(state.tagsViewList);
});
};
// 2 tagsView
const refreshCurrentTagsView = (path: string) => {
proxy.mittBus.emit('onTagsViewRefreshRouterView', path);
const refreshCurrentTagsView = (fullPath: string) => {
proxy.mittBus.emit('onTagsViewRefreshRouterView', fullPath);
};
// 3 tagsViewisAffix
const closeCurrentTagsView = (path: string) => {
state.tagsViewList.map((v: any, k: number, arr: any) => {
if (!v.meta.isAffix) {
if (v.path === path) {
if (getThemeConfig.value.isShareTagsView ? v.path === path : v.url === path) {
state.tagsViewList.splice(k, 1);
setTimeout(() => {
if (state.tagsViewList.length === k && state.routePath === path) {
if (state.tagsViewList.length === k && getThemeConfig.value.isShareTagsView ? state.routePath === path : state.routeActive === path) {
//
if (arr[arr.length - 1].meta.isDynamic) {
// xxx/:id/:name"
@ -148,7 +202,7 @@ export default {
}
} else {
//
if (state.tagsViewList.length !== k && state.routePath === path) {
if (state.tagsViewList.length !== k && getThemeConfig.value.isShareTagsView ? state.routePath === path : state.routeActive === path) {
if (arr[k].meta.isDynamic) {
// xxx/:id/:name"
router.push({ name: arr[k].name, params: arr[k].params });
@ -173,62 +227,85 @@ export default {
addTagsView(path, route);
};
// 5 tagsViewisAffix
const closeAllTagsView = (path: string) => {
const closeAllTagsView = () => {
state.tagsViewList = [];
state.tagsViewRoutesList.map((v: any) => {
if (v.meta.isAffix && !v.meta.isHide) {
state.tagsViewList.push({ ...v });
if (state.tagsViewList.some((v: any) => v.path === path)) router.push({ path, query: route.query });
else router.push({ path: v.path, query: route.query });
router.push({ path: state.tagsViewList[state.tagsViewList.length - 1].path });
}
});
addBrowserSetSession(state.tagsViewList);
};
// 6
const openCurrenFullscreen = (path: string, currentRouteInfo: object) => {
nextTick(() => {
const { meta, name, params, query } = currentRouteInfo;
if (meta.isDynamic) router.push({ name, params });
else router.push({ path, query });
store.dispatch('tagsViewRoutes/setCurrenFullscreen', 500);
});
const openCurrenFullscreen = async (path: string) => {
const item = state.tagsViewList.find((v: any) => (getThemeConfig.value.isShareTagsView ? v.path === path : v.url === path));
if (item.meta.isDynamic) await router.push({ name: item.name, params: item.params });
else await router.push({ name: item.name, query: item.query });
NextLoading.start();
setTimeout(() => {
nextTick(() => {
store.dispatch('tagsViewRoutes/setCurrenFullscreen', true);
if (store.state.tagsViewRoutes.isTagsViewCurrenFull) {
const element = document.querySelector('.layout-main .layout-view-bg-white') as HTMLElement;
if (!element) return false;
// iframes
if (route.path === '/iframes') element.style.height = `100vh`;
else element.style.height = `calc(100vh - 30px)`;
}
});
}, 1000);
};
// tagsView
const getCurrentRouteItem = (path: string) => {
if (!Session.get('tagsViewList')) return state.tagsViewList.find((v: any) => v.path === path);
return Session.get('tagsViewList').find((v: any) => v.path === path);
// tagsView
const getCurrentRouteItem = (path: string, cParams: { [key: string]: any }) => {
const itemRoute = Session.get('tagsViewList') ? Session.get('tagsViewList') : state.tagsViewList;
return itemRoute.find((v: any) => {
if (
v.path === path &&
isObjectValueEqual(
v.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
cParams && Object.keys(cParams ? cParams : {}).length > 0 ? cParams : null
)
) {
return v;
} else if (v.path === path && Object.keys(cParams ? cParams : {}).length <= 0) {
return v;
}
});
};
//
const onCurrentContextmenuClick = (item) => {
const { id, path } = item;
const currentRouteInfo = getCurrentRouteItem(path);
const { meta, name, params, query } = currentRouteInfo;
switch (id) {
const onCurrentContextmenuClick = async (item) => {
const cParams = item.meta.isDynamic ? item.params : item.query;
if (!getCurrentRouteItem(item.path, cParams)) return ElMessage({ type: 'warning', message: '请正确输入路径及完整参数query、params' });
const { path, name, params, query, meta, url } = getCurrentRouteItem(item.path, cParams);
switch (item.id) {
case 0:
refreshCurrentTagsView(path);
if (meta.isDynamic) router.push({ name, params });
else router.push({ path, query });
//
if (meta.isDynamic) await router.push({ name, params });
else await router.push({ path, query });
refreshCurrentTagsView(route.fullPath);
break;
case 1:
closeCurrentTagsView(path);
//
closeCurrentTagsView(getThemeConfig.value.isShareTagsView ? path : url);
break;
case 2:
if (meta.isDynamic) router.push({ name, params });
else router.push({ path, query });
//
if (meta.isDynamic) await router.push({ name, params });
else await router.push({ path, query });
closeOtherTagsView(path);
break;
case 3:
closeAllTagsView(path);
//
closeAllTagsView();
break;
case 4:
openCurrenFullscreen(path, currentRouteInfo);
//
openCurrenFullscreen(getThemeConfig.value.isShareTagsView ? path : url);
break;
}
};
// https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
const isActive = (path: string) => {
return path === state.routePath;
};
// x,y props
const onContextmenu = (v: any, e: any) => {
const { clientX, clientY } = e;
@ -238,10 +315,20 @@ export default {
};
// tagsView
const onTagsClick = (v: any, k: number) => {
state.routePath = v.path;
state.tagsRefsIndex = k;
router.push(v);
};
// tagsView 使使
const setTagsViewHighlight = (v: any) => {
let params = v.query && Object.keys(v.query).length > 0 ? v.query : v.params;
if (!params || Object.keys(params).length <= 0) return v.path;
let path = '';
for (let i in params) {
path += params[i];
}
// xxx/:id/:name"
return `${v.meta.isDynamic ? v.meta.isDynamicPath : v.path}-${path}`;
};
//
const updateScrollbar = () => {
proxy.$refs.scrollbarRef.update();
@ -304,9 +391,19 @@ export default {
};
// tagsView tagsView
const getTagsRefsIndex = (path: string) => {
if (state.tagsViewList.length > 0) {
state.tagsRefsIndex = state.tagsViewList.findIndex((item: any) => item.path === path);
}
nextTick(async () => {
// await 使 tagsViewList
let tagsViewList = await state.tagsViewList;
state.tagsRefsIndex = tagsViewList.findIndex((v: any) => {
if (getThemeConfig.value.isShareTagsView) {
return v.path === path;
} else {
return v.url === path;
}
});
//
tagsViewmoveToCurrentTag();
});
};
// tagsView
const initSortable = () => {
@ -335,11 +432,6 @@ export default {
else getThemeConfig.value.isSortableTagsView = true;
initSortable();
};
// tagsView
watch(store.state, (val) => {
if (val.tagsViewRoutes.tagsViewRoutes.length === state.tagsViewRoutesList.length) return false;
getTagsViewRoutes();
});
//
onBeforeMount(() => {
// 访
@ -354,6 +446,19 @@ export default {
proxy.mittBus.on('openOrCloseSortable', () => {
initSortable();
});
// TagsView
proxy.mittBus.on('openShareTagsView', () => {
if (getThemeConfig.value.isShareTagsView) {
router.push('/home');
state.tagsViewList = [];
state.tagsViewRoutesList.map((v: any) => {
if (v.meta.isAffix && !v.meta.isHide) {
v.url = setTagsViewHighlight(v);
state.tagsViewList.push({ ...v });
}
});
}
});
});
//
onUnmounted(() => {
@ -361,6 +466,8 @@ export default {
proxy.mittBus.off('onCurrentContextmenuClick');
// /
proxy.mittBus.off('openOrCloseSortable');
// TagsView
proxy.mittBus.off('openShareTagsView');
// resize
window.removeEventListener('resize', onSortableResize);
});
@ -375,11 +482,16 @@ export default {
initSortable();
});
//
onBeforeRouteUpdate((to) => {
onBeforeRouteUpdate(async (to) => {
state.routeActive = setTagsViewHighlight(to);
state.routePath = to.meta.isDynamic ? to.meta.isDynamicPath : to.path;
addTagsView(to.path, to);
getTagsRefsIndex(to.path);
tagsViewmoveToCurrentTag();
await addTagsView(to.path, to);
getTagsRefsIndex(getThemeConfig.value.isShareTagsView ? state.routePath : state.routeActive);
});
// tagsView
watch(store.state, (val) => {
if (val.tagsViewRoutes.tagsViewRoutes.length === state.tagsViewRoutesList.length) return false;
getTagsViewRoutes();
});
return {
isActive,
@ -392,7 +504,6 @@ export default {
tagsUlRef,
onHandleScroll,
getThemeConfig,
isCurrenFullscreen,
setTagsStyle,
refreshCurrentTagsView,
closeCurrentTagsView,

View File

@ -11,7 +11,7 @@
</template>
<script lang="ts">
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick } from 'vue';
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useStore } from '/@/store/index';
export default defineComponent({
@ -40,19 +40,11 @@ export default defineComponent({
//
onBeforeMount(() => {
state.keepAliveNameList = getKeepAliveNames.value;
proxy.mittBus.on('onTagsViewRefreshRouterView', (path: string) => {
// https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
if (route.meta.isDynamic) {
// xxx/:id/:name
if (route.meta.isDynamicPath !== path) return false;
} else {
//
if (route.path !== path) return false;
}
proxy.mittBus.on('onTagsViewRefreshRouterView', (fullPath: string) => {
state.keepAliveNameList = getKeepAliveNames.value.filter((name: string) => route.name !== name);
state.refreshRouterViewKey = route.meta.isDynamic ? route.meta.isDynamicPath : route.path;
state.refreshRouterViewKey = null;
nextTick(() => {
state.refreshRouterViewKey = null;
state.refreshRouterViewKey = fullPath;
state.keepAliveNameList = getKeepAliveNames.value;
});
});
@ -61,6 +53,13 @@ export default defineComponent({
onUnmounted(() => {
proxy.mittBus.off('onTagsViewRefreshRouterView');
});
// tagsView
watch(
() => route.fullPath,
() => {
state.refreshRouterViewKey = route.fullPath;
}
);
return {
getThemeConfig,
getKeepAliveNames,

View File

@ -34,6 +34,7 @@ export interface ThemeConfigState {
isTagsviewIcon: boolean;
isCacheTagsView: boolean;
isSortableTagsView: boolean;
isShareTagsView: boolean;
isFooter: boolean;
isGrayscale: boolean;
isInvert: boolean;
@ -65,7 +66,7 @@ export interface KeepAliveNamesState {
// TagsView 路由列表
export interface TagsViewRoutesState {
tagsViewRoutes: Array<object>;
isCurrenFullscreen: boolean;
isTagsViewCurrenFull: Boolean;
}
// 用户信息

View File

@ -1,7 +1,4 @@
import { Module } from 'vuex';
import { ElMessage } from 'element-plus';
import screenfull from 'screenfull';
import { Local } from '/@/utils/storage';
// 此处加上 `.ts` 后缀报错,具体原因不详
import { TagsViewRoutesState, RootStateTypes } from '/@/store/interface/index';
@ -9,7 +6,7 @@ const tagsViewRoutesModule: Module<TagsViewRoutesState, RootStateTypes> = {
namespaced: true,
state: {
tagsViewRoutes: [],
isCurrenFullscreen: false,
isTagsViewCurrenFull: false,
},
mutations: {
// 设置 TagsView 路由
@ -17,8 +14,8 @@ const tagsViewRoutesModule: Module<TagsViewRoutesState, RootStateTypes> = {
state.tagsViewRoutes = data;
},
// 设置卡片全屏
getCurrenFullscreen(state: any, data: boolean) {
state.isCurrenFullscreen = data;
getCurrenFullscreen(state: any, bool: boolean) {
state.isTagsViewCurrenFull = bool;
},
},
actions: {
@ -27,34 +24,8 @@ const tagsViewRoutesModule: Module<TagsViewRoutesState, RootStateTypes> = {
commit('getTagsViewRoutes', data);
},
// 设置卡片全屏
setCurrenFullscreen({ commit }, timeout: number = 0) {
const screenfulls: any = screenfull;
if (!screenfulls.isEnabled) {
ElMessage.warning('暂不不支持全屏');
return false;
}
setTimeout(() => {
const currenFullscreenChange = () => {
const layoutViewBgWhite = document.querySelector('.layout-view-bg-white') as HTMLElement;
if (screenfulls.isFullscreen) {
commit('getCurrenFullscreen', true);
// 设置全屏时,设置有 `layout-view-bg-white` 类的高度
if (layoutViewBgWhite) layoutViewBgWhite.style.height = `calc(100vh - 30px)`;
} else {
screenfulls.off('change', currenFullscreenChange);
commit('getCurrenFullscreen', false);
if (!layoutViewBgWhite) return false;
const getThemeConfig = Local.get('themeConfig');
if (getThemeConfig) {
let { isTagsview } = getThemeConfig;
if (isTagsview) layoutViewBgWhite.style.height = `calc(100vh - 114px)`;
else layoutViewBgWhite.style.height = `calc(100vh - 80px)`;
}
}
};
screenfulls.on('change', currenFullscreenChange);
screenfulls.toggle();
}, timeout);
setCurrenFullscreen({ commit }, bool: Boolean) {
commit('getCurrenFullscreen', bool);
},
},
};

View File

@ -91,6 +91,8 @@ const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
isCacheTagsView: false,
// 是否开启 TagsView 拖拽
isSortableTagsView: true,
// 是否开启 TagsView 共用
isShareTagsView: false,
// 是否开启 Footer 底部版权信息
isFooter: false,
// 是否开启灰色模式

View File

@ -54,7 +54,7 @@ body,
.el-scrollbar {
width: 100%;
}
// 此字段多次用到删除如需修改请重写覆盖样式
// 此字段多次用到建议不删除如需修改请重写覆盖样式
.layout-view-bg-white {
background: white;
width: 100%;

View File

@ -14,3 +14,28 @@ export function judementSameArr(news: Array<string>, old: Array<string>): boolea
}
return count === leng ? true : false;
}
/**
*
* @param a
* @param b
* @returns true
*/
export function isObjectValueEqual(a: { [key: string]: any }, b: { [key: string]: any }) {
if (!a || !b) return false;
let aProps = Object.getOwnPropertyNames(a);
let bProps = Object.getOwnPropertyNames(b);
if (aProps.length != bProps.length) return false;
for (let i = 0; i < aProps.length; i++) {
let propName = aProps[i];
let propA = a[propName];
let propB = b[propName];
if (!b.hasOwnProperty(propName)) return false;
if (propA instanceof Object) {
if (!isObjectValueEqual(propA, propB)) return false;
} else if (propA !== propB) {
return false;
}
}
return true;
}

View File

@ -202,7 +202,7 @@
</template>
<script lang="ts">
import { toRefs, reactive, computed, onMounted, getCurrentInstance } from 'vue';
import { toRefs, reactive, computed, onMounted, getCurrentInstance, watch, nextTick } from 'vue';
import { useStore } from '/@/store/index';
import ChartHead from '/@/views/chart/head.vue';
import * as echarts from 'echarts';
@ -220,6 +220,7 @@ export default {
dBtnList,
chartData4List,
earth3DBtnList,
myCharts: [],
});
//
const initTagViewHeight = computed(() => {
@ -286,9 +287,7 @@ export default {
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 7
const initChartsSevenDays = () => {
@ -333,9 +332,7 @@ export default {
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 30
const initChartsWarning = () => {
@ -370,9 +367,7 @@ export default {
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initChartsMonitor = () => {
@ -412,9 +407,7 @@ export default {
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 7
const initChartsInvestment = () => {
@ -444,8 +437,14 @@ export default {
],
};
myChart.setOption(option);
state.myCharts.push(myChart);
};
// echarts resize
const initEchartsResize = () => {
window.addEventListener('resize', () => {
myChart.resize();
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
});
};
//
@ -455,7 +454,19 @@ export default {
initChartsWarning();
initChartsMonitor();
initChartsInvestment();
initEchartsResize();
});
// vuex tagsview resize /
watch(
() => store.state.tagsViewRoutes.isTagsViewCurrenFull,
() => {
nextTick(() => {
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
});
}
);
return {
initTagViewHeight,
...toRefs(state),

View File

@ -1,28 +1,10 @@
<template>
<div class="fun-tagsview">
<el-card shadow="hover" header="tagsView 非当前页演示">
<el-form :model="formInline" size="small" label-width="40px" class="tags-view-form">
<el-row :gutter="35">
<el-col :xs="24" :sm="8" :md="8" :lg="6" :xl="4" class="tags-view-form-col">
<el-form-item label="功能">
<el-select v-model="formInline.selectId" placeholder="请选择" class="w100">
<el-option v-for="item in selectOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="6" :xl="4" class="tags-view-form-col">
<el-form-item label="路径">
<el-input v-model="formInline.path" placeholder="路径如:/fun/tagsView"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="6" :xl="4">
<el-form-item class="fun-tagsview-from-item">
<el-button type="primary" @click="onImplementClick" icon="el-icon-thumb">点击执行</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<NoticeBar
text="已删除非当前页 tagsView 演示后续有时间可以再加回来tagsview 支持多标签(参数不同)、单标签共用(参数不同)"
background="#ecf5ff"
color="#409eff"
/>
<el-card shadow="hover" header="tagsView 当前页演示" class="mt15">
<div class="flex-warp">
<div class="flex-warp-item">
@ -57,82 +39,35 @@
<script lang="ts">
import { getCurrentInstance, reactive, toRefs } from 'vue';
import NoticeBar from '/@/components/noticeBar/index.vue';
import { useRoute } from 'vue-router';
export default {
name: 'funTagsView',
components: { NoticeBar },
setup() {
const { proxy } = getCurrentInstance() as any;
const route = useRoute();
const state = reactive({
formInline: {
path: '',
selectId: 0,
},
selectOptions: [
{
value: 0,
label: '刷新当前',
},
{
value: 1,
label: '关闭当前',
},
{
value: 2,
label: '关闭其它',
},
{
value: 3,
label: '关闭全部',
},
{
value: 4,
label: '当前页全屏',
},
],
});
const state = reactive({});
// 0 1 2 3 4
// 1 tagsView
const refreshCurrentTagsView = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: 0,
path: route.path,
});
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 0, ...route }));
};
// 2 tagsView
const closeCurrentTagsView = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: 1,
path: route.path,
});
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 1, ...route }));
};
// 3 tagsView
const closeOtherTagsView = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: 2,
path: route.path,
});
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 2, ...route }));
};
// 4 tagsView
const closeAllTagsView = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: 3,
path: route.path,
});
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 3, ...route }));
};
// 5
const openCurrenFullscreen = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: 4,
path: route.path,
});
};
//
const onImplementClick = () => {
proxy.mittBus.emit('onCurrentContextmenuClick', {
id: state.formInline.selectId,
path: state.formInline.path,
});
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 4, ...route }));
};
return {
refreshCurrentTagsView,
@ -140,7 +75,6 @@ export default {
closeOtherTagsView,
closeAllTagsView,
openCurrenFullscreen,
onImplementClick,
...toRefs(state),
};
},

View File

@ -96,7 +96,7 @@
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance } from 'vue';
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance, watch } from 'vue';
import * as echarts from 'echarts';
import { CountUp } from 'countup.js';
import { formatAxis } from '/@/utils/formatTime';
@ -130,6 +130,7 @@ export default {
},
],
},
myCharts: [],
});
// vuex
const getUserInfos = computed(() => {
@ -234,9 +235,7 @@ export default {
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initHomeOvertime = () => {
@ -288,8 +287,14 @@ export default {
],
};
myChart.setOption(option);
state.myCharts.push(myChart);
};
// echarts resize
const initEchartsResize = () => {
window.addEventListener('resize', () => {
myChart.resize();
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
});
};
//
@ -297,7 +302,19 @@ export default {
initNumCountUp();
initHomeLaboratory();
initHomeOvertime();
initEchartsResize();
});
// vuex tagsview resize /
watch(
() => store.state.tagsViewRoutes.isTagsViewCurrenFull,
() => {
nextTick(() => {
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
});
}
);
return {
getUserInfos,
currentTime,

View File

@ -120,7 +120,7 @@ export default {
position: absolute;
top: 0;
right: 0;
width: 51px;
width: 50px;
height: 50px;
overflow: hidden;
cursor: pointer;
@ -134,19 +134,22 @@ export default {
border-bottom: 50px solid #ffffff;
border-right: 50px solid transparent;
z-index: 2;
top: 0;
right: 0;
}
&:hover {
opacity: 1;
transition: all ease 0.3s;
color: var(--color-primary);
}
i {
content: '';
width: 50px;
width: 48px;
height: 50px;
position: absolute;
top: -2px;
top: 0px;
right: 0px;
font-size: 50px;
font-size: 47px;
z-index: 1;
}
}

View File

@ -1,9 +1,10 @@
<template>
<div class="layout-view-bg-white flex" :style="{ height: `calc(100vh - ${setViewHeight}` }">
<div class="flex-margin">
<el-result icon="success" title="普通路由" subTitle="请根据提示进行操作">
<el-result icon="success" title="普通路由" subTitle="可 `开启 TagsView 共用` 进行单标签测试">
<template #extra>
<el-button type="primary" size="small" icon="iconfont icon-putong" @click="onGoDetailsClick">点击测试普通路由传参</el-button>
<el-input v-model="value" placeholder="请输入路由参数id值" clearable></el-input>
<el-button type="primary" size="small" icon="iconfont icon-putong" class="mt15" @click="onGoDetailsClick">普通路由传参</el-button>
</template>
</el-result>
</div>
@ -18,7 +19,9 @@ export default defineComponent({
name: 'paramsCommon',
setup() {
const store = useStore();
const state = reactive({});
const state = reactive({
value: '',
});
const router = useRouter();
// view
const setViewHeight = computed(() => {
@ -30,11 +33,9 @@ export default defineComponent({
const onGoDetailsClick = () => {
router.push({
path: '/params/common/details',
query: {
t: new Date().getTime(),
id: Math.random(),
},
query: { id: state.value, name: 'vue-next-admin' },
});
state.value = '';
};
return {
setViewHeight,

View File

@ -1,9 +1,10 @@
<template>
<div class="layout-view-bg-white flex" :style="{ height: `calc(100vh - ${setViewHeight}` }">
<div class="flex-margin">
<el-result icon="warning" title="动态路由" subTitle="请根据提示进行操作">
<el-result icon="warning" title="动态路由" subTitle="可 `开启 TagsView 共用` 进行单标签测试">
<template #extra>
<el-button type="primary" size="small" icon="iconfont icon-dongtai" @click="onGoDetailsClick">点击测试动态路由传参</el-button>
<el-input v-model="value" placeholder="请输入路由参数id值" clearable></el-input>
<el-button type="primary" size="small" icon="iconfont icon-dongtai" class="mt15" @click="onGoDetailsClick">动态路由传参</el-button>
</template>
</el-result>
</div>
@ -18,7 +19,9 @@ export default defineComponent({
name: 'paramsDynamic',
setup() {
const store = useStore();
const state = reactive({});
const state = reactive({
value: '',
});
const router = useRouter();
// view
const setViewHeight = computed(() => {
@ -29,15 +32,14 @@ export default defineComponent({
//
const onGoDetailsClick = () => {
// name name
const t = new Date().getTime();
const id = Math.random();
router.push({
name: 'paramsDynamicDetails',
params: {
t,
id,
t: 'vue-next-admin',
id: state.value,
},
});
state.value = '';
};
return {
setViewHeight,

View File

@ -106,6 +106,7 @@ export default defineComponent({
txt: '',
fun: 0,
},
myCharts: [],
});
//
const initTime = () => {
@ -233,9 +234,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
//
const map = myChart.getModel().getComponent('bmap').getBMap();
@ -355,9 +354,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// A
const initVisualizingContentLeftBottom = () => {
@ -473,9 +470,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initVisualizingContentCenterTop = () => {
@ -603,9 +598,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initVisualizingContentCenterBottom = () => {
@ -702,9 +695,7 @@ export default defineComponent({
},
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initVisualizingContentRightTop = () => {
@ -839,9 +830,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initVisualizingContentRightBottom = () => {
@ -923,20 +912,27 @@ export default defineComponent({
],
};
myChart.setOption(option);
state.myCharts.push(myChart);
};
// echarts resize
const initEchartsResize = () => {
window.addEventListener('resize', () => {
myChart.resize();
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
});
};
//
onMounted(() => {
onMounted(async () => {
initTime();
initEchartsMap();
initVisualizingContentLeftTop();
initVisualizingContentLeftBottom();
initVisualizingContentCenterTop();
initVisualizingContentCenterBottom();
initVisualizingContentRightTop();
initVisualizingContentRightBottom();
await initEchartsMap();
await initVisualizingContentLeftTop();
await initVisualizingContentLeftBottom();
await initVisualizingContentCenterTop();
await initVisualizingContentCenterBottom();
await initVisualizingContentRightTop();
await initVisualizingContentRightBottom();
await initEchartsResize();
});
//
onUnmounted(() => {

View File

@ -253,6 +253,7 @@ export default defineComponent({
dBtnActive: 0,
earth3DBtnList,
chartData4List,
myCharts: [],
});
//
const initTime = () => {
@ -291,9 +292,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initRightChartData4 = () => {
@ -381,9 +380,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 7
const initRightChartData3 = () => {
@ -462,9 +459,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
//
const initRightChartData6 = () => {
@ -478,7 +473,7 @@ export default defineComponent({
},
grid: {
top: 20,
right: 42,
right: 50,
bottom: 0,
left: 80,
},
@ -508,7 +503,7 @@ export default defineComponent({
data: ['施肥任务完成率', '施药任务完成率', '农事任务完成率'],
axisLabel: {
color: '#A7D6F4',
fontSize: 10,
fontSize: 12,
},
},
],
@ -516,12 +511,12 @@ export default defineComponent({
{
name: '标准化',
type: 'bar',
barWidth: 12, //
barWidth: 10, //
label: {
show: true,
position: 'right', //
color: '#A7D6F4',
fontSize: 10,
fontSize: 12,
distance: 15, //
formatter: '{c}%', //
}, //
@ -551,9 +546,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 7
const initRightChartData2 = () => {
@ -686,9 +679,7 @@ export default defineComponent({
],
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
state.myCharts.push(myChart);
};
// 3DEarth
const init3DEarth = (globeRadius) => {
@ -751,7 +742,7 @@ export default defineComponent({
myChart.setOption(option);
};
//
const initAddEventListener3DEarthFun = () => {
const initAddEventListener3DEarth = () => {
let w = document.body.clientWidth;
let globeRadius = 0;
if (w >= 1920) globeRadius = 100;
@ -761,22 +752,25 @@ export default defineComponent({
else if (w < 768) globeRadius = 20;
init3DEarth(globeRadius);
};
//
const initAddEventListener3DEarth = () => {
initAddEventListener3DEarthFun();
// echarts resize
const initEchartsResize = () => {
initAddEventListener3DEarth();
window.addEventListener('resize', () => {
initAddEventListener3DEarthFun();
for (let i = 0; i < state.myCharts.length; i++) {
state.myCharts[i].resize();
}
initAddEventListener3DEarth();
});
};
//
onMounted(() => {
initAddEventListener3DEarth();
onMounted(async () => {
initTime();
initRightChartData1();
initRightChartData4();
initRightChartData3();
initRightChartData2();
initRightChartData6();
await initRightChartData1();
await initRightChartData4();
await initRightChartData3();
await initRightChartData2();
await initRightChartData6();
await initEchartsResize();
});
//
onUnmounted(() => {
@ -841,7 +835,7 @@ export default defineComponent({
left: 50%;
transform: translateX(-50%);
border: 1px transparent solid;
border-image: linear-gradient(to right, #000718, #43bdf0) 1 10;
border-image: linear-gradient(to right, rgba(0, 0, 0, 0.1), #43bdf0) 1 10;
}
span {
cursor: pointer;