'admin-21.08.01:更新修复请查看CHANGELOG.md文件或查看标签'
This commit is contained in:
parent
1dd6b653e7
commit
28edd79b1c
2
.env
2
.env
@ -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/
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -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`
|
||||
|
34
package.json
34
package.json
@ -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%",
|
||||
|
@ -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();
|
||||
|
@ -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',
|
||||
|
@ -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: '色弱模式',
|
||||
|
@ -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: '色弱模式',
|
||||
|
@ -1,14 +1,13 @@
|
||||
<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-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">
|
||||
@ -17,7 +16,6 @@
|
||||
</el-aside>
|
||||
</el-drawer>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, watch, getCurrentInstance, onBeforeMount } from 'vue';
|
||||
@ -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),
|
||||
};
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
65
src/layout/navBars/breadcrumb/closeFull.vue
Normal file
65
src/layout/navBars/breadcrumb/closeFull.vue
Normal 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>
|
@ -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,
|
||||
};
|
||||
},
|
||||
|
@ -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,
|
||||
|
@ -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(() => {
|
||||
|
@ -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、添加 tagsView:未设置隐藏(isHide)也添加到在 tagsView 中
|
||||
// 处理可开启多标签详情,单标签详情(动态路由(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);
|
||||
}
|
||||
};
|
||||
// 处理单标签时,第二次的值未覆盖第一次的 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、添加 tagsView:未设置隐藏(isHide)也添加到在 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;
|
||||
state.tagsViewList.push({ ...item });
|
||||
addBrowserSetSession(state.tagsViewList);
|
||||
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、关闭当前 tagsView:如果是设置了固定的(isAffix),不可以关闭
|
||||
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、关闭全部 tagsView:如果是设置了固定的(isAffix),不进行关闭
|
||||
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) => {
|
||||
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(() => {
|
||||
const { meta, name, params, query } = currentRouteInfo;
|
||||
if (meta.isDynamic) router.push({ name, params });
|
||||
else router.push({ path, query });
|
||||
store.dispatch('tagsViewRoutes/setCurrenFullscreen', 500);
|
||||
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,
|
||||
|
@ -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;
|
||||
nextTick(() => {
|
||||
state.refreshRouterViewKey = null;
|
||||
nextTick(() => {
|
||||
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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// 用户信息
|
||||
|
@ -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);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -91,6 +91,8 @@ const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
|
||||
isCacheTagsView: false,
|
||||
// 是否开启 TagsView 拖拽
|
||||
isSortableTagsView: true,
|
||||
// 是否开启 TagsView 共用
|
||||
isShareTagsView: false,
|
||||
// 是否开启 Footer 底部版权信息
|
||||
isFooter: false,
|
||||
// 是否开启灰色模式
|
||||
|
@ -54,7 +54,7 @@ body,
|
||||
.el-scrollbar {
|
||||
width: 100%;
|
||||
}
|
||||
// 此字段多次用到,不可删除,如需修改,请重写覆盖样式
|
||||
// 此字段多次用到,建议不删除,如需修改,请重写覆盖样式
|
||||
.layout-view-bg-white {
|
||||
background: white;
|
||||
width: 100%;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
};
|
||||
},
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(() => {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user