mirror of
https://gitee.com/lyt-top/vue-next-admin
synced 2026-06-15 21:30:47 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b1c80a8d4 | |||
| a4da51c179 | |||
| 12e6b2b4bc | |||
| 25fa3536de | |||
| ea5dccebe6 | |||
| e0960f9009 | |||
| c49736ae7d | |||
| dfcf817d70 | |||
| 71eb623cef |
32
CHANGELOG.md
32
CHANGELOG.md
@ -2,6 +2,38 @@
|
||||
|
||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
|
||||
## 1.0.17
|
||||
|
||||
`2021.08.22`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 去除设置布局切换,重置主题样式(initSetLayoutChange),切换布局需手动设置样式,设置的样式自动同步各布局
|
||||
- 🎯 优化 Dropdown 下拉菜单用户账号靠边时换行问题
|
||||
- 🎯 优化 左侧导航菜单,共用菜单树,防止 `布局配置` 设置 `菜单 / 顶栏` 时,样式丢失等问题
|
||||
- 🐞 修复 固定 header 后没有回到顶部的 bug,拉取项目后运行不起来的 bug。<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/14" target="_blank">!14</a>,感谢<a href="https://gitee.com/wjs0509" target="_blank">@wjs0509</a>
|
||||
- 🐞 修复 tagView 右键全屏后,浏览器窗口大小发生任何变化都会导致左边菜单显示出来,并且可点击打开对应页面。<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I46E6T" target="_blank">I46E6T</a>
|
||||
- 🐞 修复 默认设置 `菜单 / 顶栏` 样式不生效问题(/@/src/store/modules/themeConfig.ts)
|
||||
|
||||
## 1.0.16
|
||||
|
||||
`2021.08.14`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 菜单高亮(详情且详情设置了 meta.isHide 时,顶级菜单高亮),感谢群友@YourObject
|
||||
- 🎯 优化 详情路径写法:如父级(/pages/filtering),那么详情为(/pages/filtering/details?id=1)。这样写可实现(详情时,父级菜单高亮),否则写成(/pages/filteringDetails?id=1)顶级菜单将不会高亮。可参考:`页面/过滤筛选组件`,点击当前图片进行测试
|
||||
- 🎯 优化 tagsView 右键菜单全屏时,打开的界面高度问题
|
||||
- 🎯 优化 图表批量 resize 问题
|
||||
- 🐞 修复 菜单收起时(设置全局主题:primary 且有二级菜单时),文字高亮颜色不对
|
||||
- 🐞 修复 国际化 <a href="https://gitee.com/lyt-top/vue-next-admin/issues/I43NPE" target="_blank">#I43NPE</a>。可参考:`页面/过滤筛选组件`,点击顶部语言切换,进行底部分页国际化查看
|
||||
|
||||
## 1.0.15
|
||||
|
||||
`2021.08.06`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 tagsView 右键菜单点击时的字段名(id 已修改成 contextMenuClickId)与路由中返回的 id 名冲突问题,感谢群友@伯牙已遇钟子期
|
||||
- 🎉 新增 多个 form 表单验证界面演示
|
||||
|
||||
## 1.0.14
|
||||
|
||||
`2021.07.29`
|
||||
|
||||
13
README.md
13
README.md
@ -71,11 +71,18 @@ cnpm run build
|
||||
|
||||
#### 💯 学习交流加 QQ 群
|
||||
|
||||
- 若加群了没同意(一般不会超过一天),那就是群满了,请换一个群试试
|
||||
- 查看开发文档、<a href="https://lyt-top.gitee.io/vue-next-admin-preview/#/login" target="_blank">vue-next-admin</a> 开发文档正在编写中...
|
||||
- 群号码:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=RdUY97Vx0T0vZ_1OOu-X1yFNkWgDwbjC&jump_from=webapi">665452019</a>
|
||||
- 群号码:
|
||||
1 群:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=RdUY97Vx0T0vZ_1OOu-X1yFNkWgDwbjC&jump_from=webapi">665452019</a>
|
||||
2 群:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=zVfy3gNy7pNWVK3kMduDzwU369PZg2fw&jump_from=webapi">766356862</a>
|
||||
|
||||
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=RdUY97Vx0T0vZ_1OOu-X1yFNkWgDwbjC&jump_from=webapi">
|
||||
<img src="https://gitee.com/lyt-top/vue-next-admin-images/raw/master/user/qqs.png" width="220" alt="vue-next-admin 讨论群" title="vue-next-admin 讨论群"/></a>
|
||||
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=RdUY97Vx0T0vZ_1OOu-X1yFNkWgDwbjC&jump_from=webapi">
|
||||
<img src="https://gitee.com/lyt-top/vue-next-admin-images/raw/master/user/qq1.png" width="220" height="220" alt="vue-next-admin 讨论群" title="vue-next-admin 讨论群1"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=zVfy3gNy7pNWVK3kMduDzwU369PZg2fw&jump_from=webapi">
|
||||
<img src="https://gitee.com/lyt-top/vue-next-admin-images/raw/master/user/qq2.png" width="220" height="220" alt="vue-next-admin 讨论群" title="vue-next-admin 讨论群2"/>
|
||||
</a>
|
||||
|
||||
#### ❤️ 鸣谢列表
|
||||
|
||||
|
||||
24
package.json
24
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-next-admin",
|
||||
"version": "1.0.14",
|
||||
"version": "1.0.16",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
@ -11,9 +11,9 @@
|
||||
"countup.js": "^2.0.8",
|
||||
"cropperjs": "^1.5.12",
|
||||
"echarts": "^5.1.2",
|
||||
"echarts-gl": "^2.0.7",
|
||||
"echarts-gl": "^2.0.8",
|
||||
"echarts-wordcloud": "^2.0.0",
|
||||
"element-plus": "^1.0.2-beta.65",
|
||||
"element-plus": "^1.0.2-beta.71",
|
||||
"mitt": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"print-js": "^1.6.0",
|
||||
@ -28,26 +28,26 @@
|
||||
"vue-router": "^4.0.10",
|
||||
"vue-web-screen-shot": "^1.2.0",
|
||||
"vuex": "^4.0.2",
|
||||
"wangeditor": "^4.7.6"
|
||||
"wangeditor": "^4.7.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/clipboard": "^2.0.1",
|
||||
"@types/node": "^16.4.9",
|
||||
"@types/node": "^16.7.1",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/sortablejs": "^1.10.7",
|
||||
"@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",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
||||
"@typescript-eslint/parser": "^4.29.2",
|
||||
"@vitejs/plugin-vue": "^1.4.0",
|
||||
"@vue/compiler-sfc": "^3.2.4",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^7.15.0",
|
||||
"eslint-plugin-vue": "^7.16.0",
|
||||
"prettier": "^2.3.2",
|
||||
"sass": "^1.37.0",
|
||||
"sass": "^1.38.0",
|
||||
"sass-loader": "^12.1.0",
|
||||
"typescript": "^4.3.5",
|
||||
"vite": "^2.4.4",
|
||||
"vite": "^2.5.0",
|
||||
"vue-eslint-parser": "^7.10.0"
|
||||
},
|
||||
"browserslist": [
|
||||
|
||||
23
src/App.vue
23
src/App.vue
@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<router-view v-show="getThemeConfig.lockScreenTime !== 0" />
|
||||
<LockScreen v-if="getThemeConfig.isLockScreen" />
|
||||
<Setings ref="setingsRef" v-show="getThemeConfig.lockScreenTime !== 0" />
|
||||
<CloseFull />
|
||||
<el-config-provider :locale="i18nLocale">
|
||||
<router-view v-show="getThemeConfig.lockScreenTime !== 0" />
|
||||
<LockScreen v-if="getThemeConfig.isLockScreen" />
|
||||
<Setings ref="setingsRef" v-show="getThemeConfig.lockScreenTime !== 0" />
|
||||
<CloseFull />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, ref, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, nextTick, defineComponent, watch } from 'vue';
|
||||
import { computed, ref, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, nextTick, defineComponent, watch, reactive, toRefs } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { useTitle } from '/@/utils/setWebTitle';
|
||||
@ -24,6 +26,9 @@ export default defineComponent({
|
||||
const route = useRoute();
|
||||
const store = useStore();
|
||||
const title = useTitle();
|
||||
const state = reactive({
|
||||
i18nLocale: null,
|
||||
});
|
||||
// 获取布局配置信息
|
||||
const getThemeConfig = computed(() => {
|
||||
return store.state.themeConfig.themeConfig;
|
||||
@ -46,6 +51,10 @@ export default defineComponent({
|
||||
proxy.mittBus.on('openSetingsDrawer', () => {
|
||||
openSetingsDrawer();
|
||||
});
|
||||
// 设置 i18n,App.vue 中的 el-config-provider
|
||||
proxy.mittBus.on('getI18nConfig', (locale: string) => {
|
||||
state.i18nLocale = locale;
|
||||
});
|
||||
// 获取缓存中的布局配置
|
||||
if (Local.get('themeConfig')) {
|
||||
store.dispatch('themeConfig/setThemeConfig', Local.get('themeConfig'));
|
||||
@ -53,9 +62,10 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
});
|
||||
// 页面销毁时,关闭监听布局配置
|
||||
// 页面销毁时,关闭监听布局配置/i18n监听
|
||||
onUnmounted(() => {
|
||||
proxy.mittBus.off('openSetingsDrawer', () => {});
|
||||
proxy.mittBus.off('getI18nConfig', () => {});
|
||||
});
|
||||
// 监听路由的变化,设置网站标题
|
||||
watch(
|
||||
@ -67,6 +77,7 @@ export default defineComponent({
|
||||
return {
|
||||
setingsRef,
|
||||
getThemeConfig,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@ -26,7 +26,7 @@ import pagesFormI18nZhtw from '/@/i18n/pages/formI18n/zh-tw';
|
||||
*/
|
||||
const messages = {
|
||||
[zhcnLocale.name]: {
|
||||
el: zhcnLocale.el,
|
||||
...zhcnLocale,
|
||||
message: {
|
||||
...nextZhcn,
|
||||
...pagesHomeZhcn,
|
||||
@ -35,7 +35,7 @@ const messages = {
|
||||
},
|
||||
},
|
||||
[enLocale.name]: {
|
||||
el: enLocale.el,
|
||||
...enLocale,
|
||||
message: {
|
||||
...nextEn,
|
||||
...pagesHomeEn,
|
||||
@ -44,7 +44,7 @@ const messages = {
|
||||
},
|
||||
},
|
||||
[zhtwLocale.name]: {
|
||||
el: zhtwLocale.el,
|
||||
...zhtwLocale,
|
||||
message: {
|
||||
...nextZhtw,
|
||||
...pagesHomeZhtw,
|
||||
|
||||
@ -44,6 +44,7 @@ export default {
|
||||
pagesCityLinkage: 'CityLinkage',
|
||||
pagesFormAdapt: 'FormAdapt',
|
||||
pagesFormI18n: 'FormI18n',
|
||||
pagesFormRules: 'Multi form validation',
|
||||
pagesListAdapt: 'ListAdapt',
|
||||
pagesWaterfall: 'Waterfall',
|
||||
pagesSteps: 'Steps',
|
||||
|
||||
@ -44,6 +44,7 @@ export default {
|
||||
pagesCityLinkage: '城市多级联动',
|
||||
pagesFormAdapt: '表单自适应',
|
||||
pagesFormI18n: '表单国际化',
|
||||
pagesFormRules: '多表单验证',
|
||||
pagesListAdapt: '列表自适应',
|
||||
pagesWaterfall: '瀑布屏',
|
||||
pagesSteps: '步骤条',
|
||||
|
||||
@ -44,6 +44,7 @@ export default {
|
||||
pagesCityLinkage: '都市多級聯動',
|
||||
pagesFormAdapt: '表單自我調整',
|
||||
pagesFormI18n: '表單國際化',
|
||||
pagesFormRules: '多表單驗證',
|
||||
pagesListAdapt: '清單自我調整',
|
||||
pagesWaterfall: '瀑布屏',
|
||||
pagesSteps: '步驟條',
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
<template>
|
||||
<template v-if="clientWidth > 1000">
|
||||
<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>
|
||||
<el-drawer v-model="getThemeConfig.isCollapse" :with-header="false" direction="ltr" size="220px" v-else>
|
||||
<el-aside class="layout-aside w100 h100">
|
||||
<div class="h100" v-show="!isTagsViewCurrenFull">
|
||||
<el-aside class="layout-aside" :class="setCollapseStyle">
|
||||
<Logo v-if="setShowLogo" />
|
||||
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
|
||||
<Vertical :menuList="menuList" />
|
||||
</el-scrollbar>
|
||||
</el-aside>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -41,25 +33,50 @@ export default {
|
||||
return store.state.tagsViewRoutes.isTagsViewCurrenFull;
|
||||
});
|
||||
// 设置菜单展开/收起时的宽度
|
||||
const setCollapseWidth = computed(() => {
|
||||
let { layout, isCollapse, menuBar } = store.state.themeConfig.themeConfig;
|
||||
let asideBrColor = menuBar === '#FFFFFF' || menuBar === '#FFF' || menuBar === '#fff' || menuBar === '#ffffff' ? 'layout-el-aside-br-color' : '';
|
||||
if (layout === 'columns') {
|
||||
// 分栏布局,菜单收起时宽度给 1px
|
||||
const setCollapseStyle = computed(() => {
|
||||
const { layout, isCollapse, menuBar } = store.state.themeConfig.themeConfig;
|
||||
const asideBrColor =
|
||||
menuBar === '#FFFFFF' || menuBar === '#FFF' || menuBar === '#fff' || menuBar === '#ffffff' ? 'layout-el-aside-br-color' : '';
|
||||
// 判断是否是手机端
|
||||
if (state.clientWidth <= 1000) {
|
||||
if (isCollapse) {
|
||||
return ['layout-aside-width1', asideBrColor];
|
||||
document.body.setAttribute('class', 'el-popup-parent--hidden');
|
||||
const asideEle = document.querySelector('.layout-container') as HTMLElement;
|
||||
const modeDivs = document.createElement('div');
|
||||
modeDivs.setAttribute('class', 'layout-aside-mobile-mode');
|
||||
asideEle.appendChild(modeDivs);
|
||||
modeDivs.addEventListener('click', closeLayoutAsideMobileMode);
|
||||
return [asideBrColor, 'layout-aside-mobile', 'layout-aside-mobile-open'];
|
||||
} else {
|
||||
return ['layout-aside-width-default', asideBrColor];
|
||||
// 关闭弹窗
|
||||
closeLayoutAsideMobileMode();
|
||||
return [asideBrColor, 'layout-aside-mobile', 'layout-aside-mobile-close'];
|
||||
}
|
||||
} else {
|
||||
// 其它布局给 64px
|
||||
if (isCollapse) {
|
||||
return ['layout-aside-width64', asideBrColor];
|
||||
if (layout === 'columns') {
|
||||
// 分栏布局,菜单收起时宽度给 1px
|
||||
if (isCollapse) {
|
||||
return [asideBrColor, 'layout-aside-pc-1'];
|
||||
} else {
|
||||
return [asideBrColor, 'layout-aside-pc-220'];
|
||||
}
|
||||
} else {
|
||||
return ['layout-aside-width-default', asideBrColor];
|
||||
// 其它布局给 64px
|
||||
if (isCollapse) {
|
||||
return [asideBrColor, 'layout-aside-pc-64'];
|
||||
} else {
|
||||
return [asideBrColor, 'layout-aside-pc-220'];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// 关闭移动端蒙版
|
||||
const closeLayoutAsideMobileMode = () => {
|
||||
const el = document.querySelector('.layout-aside-mobile-mode');
|
||||
el && el.parentNode?.removeChild(el);
|
||||
store.state.themeConfig.themeConfig.isCollapse = false;
|
||||
document.body.setAttribute('class', '');
|
||||
};
|
||||
// 设置显示/隐藏 logo
|
||||
const setShowLogo = computed(() => {
|
||||
let { layout, isShowLogo } = store.state.themeConfig.themeConfig;
|
||||
@ -118,10 +135,11 @@ export default {
|
||||
});
|
||||
proxy.mittBus.on('layoutMobileResize', (res: any) => {
|
||||
initMenuFixed(res.clientWidth);
|
||||
closeLayoutAsideMobileMode();
|
||||
});
|
||||
});
|
||||
return {
|
||||
setCollapseWidth,
|
||||
setCollapseStyle,
|
||||
setShowLogo,
|
||||
getThemeConfig,
|
||||
isTagsViewCurrenFull,
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
<ColumnsAside />
|
||||
<div class="layout-columns-warp">
|
||||
<Aside />
|
||||
<el-container class="flex-center layout-backtop">
|
||||
<el-container class="flex-center layout-backtop" :class="{ 'layout-backtop': !isFixedHeader }">
|
||||
<Header v-if="isFixedHeader" />
|
||||
<el-scrollbar>
|
||||
<el-scrollbar :class="{ 'layout-backtop': isFixedHeader }">
|
||||
<Header v-if="!isFixedHeader" />
|
||||
<Main />
|
||||
</el-scrollbar>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-container class="layout-container">
|
||||
<Aside />
|
||||
<el-container class="flex-center layout-backtop">
|
||||
<el-container class="flex-center" :class="{ 'layout-backtop': !isFixedHeader }">
|
||||
<Header v-if="isFixedHeader" />
|
||||
<el-scrollbar ref="layoutDefaultsScrollbarRef">
|
||||
<el-scrollbar ref="layoutDefaultsScrollbarRef" :class="{ 'layout-backtop': isFixedHeader }">
|
||||
<Header v-if="!isFixedHeader" />
|
||||
<Main />
|
||||
</el-scrollbar>
|
||||
@ -23,7 +23,7 @@ export default {
|
||||
name: 'layoutDefaults',
|
||||
components: { Aside, Header, Main },
|
||||
setup() {
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const store = useStore();
|
||||
const route = useRoute();
|
||||
const isFixedHeader = computed(() => {
|
||||
|
||||
@ -109,7 +109,6 @@ export default {
|
||||
align-items: center;
|
||||
padding-right: 15px;
|
||||
background: var(--bg-topBar);
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid #f1f2f3;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -518,38 +518,9 @@ export default defineComponent({
|
||||
if (getThemeConfig.value.layout === layout) return false;
|
||||
getThemeConfig.value.layout = layout;
|
||||
getThemeConfig.value.isDrawer = false;
|
||||
initSetLayoutChange();
|
||||
initLayoutChangeFun();
|
||||
onMenuBarHighlightChange();
|
||||
};
|
||||
// 设置布局切换,重置主题样式
|
||||
const initSetLayoutChange = () => {
|
||||
if (getThemeConfig.value.layout === 'classic') {
|
||||
getThemeConfig.value.menuBar = '#FFFFFF';
|
||||
getThemeConfig.value.menuBarColor = '#606266';
|
||||
getThemeConfig.value.topBar = '#ffffff';
|
||||
getThemeConfig.value.topBarColor = '#606266';
|
||||
initLayoutChangeFun();
|
||||
} else if (getThemeConfig.value.layout === 'transverse') {
|
||||
getThemeConfig.value.menuBarColor = '#FFFFFF';
|
||||
getThemeConfig.value.topBar = '#545c64';
|
||||
getThemeConfig.value.topBarColor = '#FFFFFF';
|
||||
initLayoutChangeFun();
|
||||
} else if (getThemeConfig.value.layout === 'columns') {
|
||||
// 1.0.11 更新日志
|
||||
getThemeConfig.value.isShowLogo = false;
|
||||
getThemeConfig.value.menuBar = '#FFFFFF';
|
||||
getThemeConfig.value.menuBarColor = '#606266';
|
||||
getThemeConfig.value.topBar = '#ffffff';
|
||||
getThemeConfig.value.topBarColor = '#606266';
|
||||
initLayoutChangeFun();
|
||||
} else {
|
||||
getThemeConfig.value.menuBar = '#545c64';
|
||||
getThemeConfig.value.menuBarColor = '#eaeaea';
|
||||
getThemeConfig.value.topBar = '#FFFFFF';
|
||||
getThemeConfig.value.topBarColor = '#606266';
|
||||
initLayoutChangeFun();
|
||||
}
|
||||
};
|
||||
// 设置布局切换函数
|
||||
const initLayoutChangeFun = () => {
|
||||
onBgColorPickerChange('menuBar');
|
||||
@ -606,7 +577,7 @@ export default defineComponent({
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
// 判断当前布局是否不相同,不相同则初始化当前布局的样式,防止监听窗口大小改变时,布局配置logo、菜单背景等部分布局失效问题
|
||||
if (!Local.get('frequency')) initSetLayoutChange();
|
||||
if (!Local.get('frequency')) initLayoutChangeFun();
|
||||
Local.set('frequency', 1);
|
||||
// 修复防止退出登录再进入界面时,需要刷新样式才生效的问题,初始化布局样式等(登录的时候触发,目前方案)
|
||||
proxy.mittBus.on('onSignInClick', () => {
|
||||
@ -618,10 +589,9 @@ export default defineComponent({
|
||||
});
|
||||
// 监听窗口大小改变,非默认布局,设置成默认布局(适配移动端)
|
||||
proxy.mittBus.on('layoutMobileResize', (res: any) => {
|
||||
if (getThemeConfig.value.layout === res.layout) return false;
|
||||
getThemeConfig.value.layout = res.layout;
|
||||
getThemeConfig.value.isDrawer = false;
|
||||
initSetLayoutChange();
|
||||
initLayoutChangeFun();
|
||||
onMenuBarHighlightChange();
|
||||
});
|
||||
setTimeout(() => {
|
||||
|
||||
@ -194,17 +194,24 @@ export default {
|
||||
initI18n();
|
||||
title();
|
||||
};
|
||||
// 设置 element plus 组件的国际化
|
||||
const setI18nConfig = (locale: string) => {
|
||||
proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]);
|
||||
};
|
||||
// 初始化言语国际化
|
||||
const initI18n = () => {
|
||||
switch (Local.get('themeConfig').globalI18n) {
|
||||
case 'zh-cn':
|
||||
state.disabledI18n = 'zh-cn';
|
||||
setI18nConfig('zh-cn');
|
||||
break;
|
||||
case 'en':
|
||||
state.disabledI18n = 'en';
|
||||
setI18nConfig('en');
|
||||
break;
|
||||
case 'zh-tw':
|
||||
state.disabledI18n = 'zh-tw';
|
||||
setI18nConfig('zh-tw');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@ -11,7 +11,14 @@
|
||||
>
|
||||
<ul class="el-dropdown-menu">
|
||||
<template v-for="(v, k) in dropdownList">
|
||||
<li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" :key="k" v-if="!v.affix" @click="onCurrentContextmenuClick(v.id)">
|
||||
<li
|
||||
class="el-dropdown-menu__item"
|
||||
aria-disabled="false"
|
||||
tabindex="-1"
|
||||
:key="k"
|
||||
v-if="!v.affix"
|
||||
@click="onCurrentContextmenuClick(v.contextMenuClickId)"
|
||||
>
|
||||
<i :class="v.icon"></i>
|
||||
<span>{{ $t(v.txt) }}</span>
|
||||
</li>
|
||||
@ -35,12 +42,12 @@ export default defineComponent({
|
||||
const state = reactive({
|
||||
isShow: false,
|
||||
dropdownList: [
|
||||
{ id: 0, txt: 'message.tagsView.refresh', affix: false, icon: 'el-icon-refresh-right' },
|
||||
{ id: 1, txt: 'message.tagsView.close', affix: false, icon: 'el-icon-close' },
|
||||
{ id: 2, txt: 'message.tagsView.closeOther', affix: false, icon: 'el-icon-circle-close' },
|
||||
{ id: 3, txt: 'message.tagsView.closeAll', affix: false, icon: 'el-icon-folder-delete' },
|
||||
{ contextMenuClickId: 0, txt: 'message.tagsView.refresh', affix: false, icon: 'el-icon-refresh-right' },
|
||||
{ contextMenuClickId: 1, txt: 'message.tagsView.close', affix: false, icon: 'el-icon-close' },
|
||||
{ contextMenuClickId: 2, txt: 'message.tagsView.closeOther', affix: false, icon: 'el-icon-circle-close' },
|
||||
{ contextMenuClickId: 3, txt: 'message.tagsView.closeAll', affix: false, icon: 'el-icon-folder-delete' },
|
||||
{
|
||||
id: 4,
|
||||
contextMenuClickId: 4,
|
||||
txt: 'message.tagsView.fullscreen',
|
||||
affix: false,
|
||||
icon: 'iconfont icon-fullscreen',
|
||||
@ -53,8 +60,8 @@ export default defineComponent({
|
||||
return props.dropdown;
|
||||
});
|
||||
// 当前项菜单点击
|
||||
const onCurrentContextmenuClick = (id: number) => {
|
||||
emit('currentContextmenuClick', Object.assign({}, { id }, state.item));
|
||||
const onCurrentContextmenuClick = (contextMenuClickId: number) => {
|
||||
emit('currentContextmenuClick', Object.assign({}, { contextMenuClickId }, state.item));
|
||||
};
|
||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
||||
const openContextmenu = (item: any) => {
|
||||
|
||||
@ -46,7 +46,6 @@ import Sortable from 'sortablejs';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { NextLoading } from '/@/utils/loading';
|
||||
import { isObjectValueEqual } from '/@/utils/arrayOperation';
|
||||
import Contextmenu from '/@/layout/navBars/tagsView/contextmenu.vue';
|
||||
export default {
|
||||
@ -242,19 +241,7 @@ export default {
|
||||
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);
|
||||
store.dispatch('tagsViewRoutes/setCurrenFullscreen', true);
|
||||
};
|
||||
// 当前项右键菜单点击,拿当前点击的路由路径对比 浏览器缓存中的 tagsView 路由数组,取当前点击项的详细路由信息
|
||||
// 防止 tagsView 非当前页演示时,操作异常
|
||||
@ -279,7 +266,7 @@ export default {
|
||||
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) {
|
||||
switch (item.contextMenuClickId) {
|
||||
case 0:
|
||||
// 刷新当前
|
||||
if (meta.isDynamic) await router.push({ name, params });
|
||||
|
||||
@ -66,15 +66,6 @@ export default defineComponent({
|
||||
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft = els.offsetLeft;
|
||||
});
|
||||
};
|
||||
// 设置页面当前路由高亮
|
||||
const setCurrentRouterHighlight = (path: string) => {
|
||||
const currentPathSplit = path.split('/');
|
||||
if (store.state.themeConfig.themeConfig.layout === 'classic') {
|
||||
state.defaultActive = `/${currentPathSplit[1]}`;
|
||||
} else {
|
||||
state.defaultActive = path;
|
||||
}
|
||||
};
|
||||
// 路由过滤递归函数
|
||||
const filterRoutesFun = (arr: Array<object>) => {
|
||||
return arr
|
||||
@ -99,15 +90,26 @@ export default defineComponent({
|
||||
});
|
||||
return currentData;
|
||||
};
|
||||
// 设置页面当前路由高亮
|
||||
const setCurrentRouterHighlight = (currentRoute) => {
|
||||
const { path, meta } = currentRoute;
|
||||
if (store.state.themeConfig.themeConfig.layout === 'classic') {
|
||||
state.defaultActive = `/${path.split('/')[1]}`;
|
||||
} else {
|
||||
const pathSplit = meta.isDynamic ? meta.isDynamicPath.split('/') : path.split('/');
|
||||
if (pathSplit.length >= 4 && meta.isHide) state.defaultActive = pathSplit.splice(0, 3).join('/');
|
||||
else state.defaultActive = path;
|
||||
}
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initElMenuOffsetLeft();
|
||||
setCurrentRouterHighlight(route.meta.isDynamic ? route.meta.isDynamicPath : route.path);
|
||||
setCurrentRouterHighlight(route);
|
||||
});
|
||||
// 路由更新时
|
||||
onBeforeRouteUpdate((to) => {
|
||||
// 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
|
||||
setCurrentRouterHighlight(to.meta.isDynamic ? to.meta.isDynamicPath : to.path);
|
||||
setCurrentRouterHighlight(to);
|
||||
proxy.mittBus.emit('onMenuClick');
|
||||
// 修复经典布局开启切割菜单时,点击tagsView后左侧导航菜单数据不变的问题
|
||||
let { layout, isClassicSplitMenu } = store.state.themeConfig.themeConfig;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
router
|
||||
:default-active="defaultActive"
|
||||
background-color="transparent"
|
||||
:collapse="setIsCollapse"
|
||||
:collapse="isCollapse"
|
||||
:unique-opened="getThemeConfig.isUniqueOpened"
|
||||
:collapse-transition="false"
|
||||
>
|
||||
@ -29,7 +29,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, defineComponent, getCurrentInstance } from 'vue';
|
||||
import { toRefs, reactive, computed, defineComponent, getCurrentInstance, onMounted, watch } from 'vue';
|
||||
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
||||
import { useStore } from '/@/store/index';
|
||||
import SubItem from '/@/layout/navMenu/subItem.vue';
|
||||
@ -49,6 +49,7 @@ export default defineComponent({
|
||||
const state = reactive({
|
||||
// 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
|
||||
defaultActive: route.meta.isDynamic ? route.meta.isDynamicPath : route.path,
|
||||
isCollapse: false,
|
||||
});
|
||||
// 获取父级菜单数据
|
||||
const menuLists = computed(() => {
|
||||
@ -58,14 +59,31 @@ export default defineComponent({
|
||||
const getThemeConfig = computed(() => {
|
||||
return store.state.themeConfig.themeConfig;
|
||||
});
|
||||
// 菜单高亮(详情时,父级高亮)
|
||||
const setParentHighlight = (currentRoute) => {
|
||||
const { path, meta } = currentRoute;
|
||||
const pathSplit = meta.isDynamic ? meta.isDynamicPath.split('/') : path.split('/');
|
||||
if (pathSplit.length >= 4 && meta.isHide) return pathSplit.splice(0, 3).join('/');
|
||||
else return path;
|
||||
};
|
||||
// 设置菜单的收起/展开
|
||||
const setIsCollapse = computed(() => {
|
||||
return document.body.clientWidth < 1000 ? false : getThemeConfig.value.isCollapse;
|
||||
watch(
|
||||
store.state.themeConfig.themeConfig,
|
||||
() => {
|
||||
document.body.clientWidth <= 1000 ? (state.isCollapse = false) : (state.isCollapse = getThemeConfig.value.isCollapse);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
state.defaultActive = setParentHighlight(route);
|
||||
});
|
||||
// 路由更新时
|
||||
onBeforeRouteUpdate((to) => {
|
||||
// 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
|
||||
state.defaultActive = to.meta.isDynamic ? to.meta.isDynamicPath : to.path;
|
||||
state.defaultActive = setParentHighlight(to);
|
||||
proxy.mittBus.emit('onMenuClick');
|
||||
const clientWidth = document.body.clientWidth;
|
||||
if (clientWidth < 1000) getThemeConfig.value.isCollapse = false;
|
||||
@ -73,7 +91,6 @@ export default defineComponent({
|
||||
return {
|
||||
menuLists,
|
||||
getThemeConfig,
|
||||
setIsCollapse,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
|
||||
@ -32,8 +32,13 @@ export default defineComponent({
|
||||
// 设置 iframe 的高度
|
||||
const setIframeHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `84px`;
|
||||
else return `50px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `0px`;
|
||||
} else {
|
||||
if (isTagsview) return `84px`;
|
||||
else return `50px`;
|
||||
}
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
||||
@ -574,24 +574,32 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-sell',
|
||||
},
|
||||
/**
|
||||
* 注意此处详情写法:
|
||||
* 1、嵌套进父级里时,面包屑显示为:首页/页面/过滤筛选组件/过滤筛选组件详情
|
||||
* 2、不嵌套进父级时,面包屑显示为:首页/页面/过滤筛选组件/过滤筛选组件详情
|
||||
* 3、想要父级不高亮,面包屑显示为:首页/页面/过滤筛选组件详情,设置路径为:/pages/filteringDetails
|
||||
*/
|
||||
children: [
|
||||
{
|
||||
path: '/pages/filtering/details',
|
||||
name: 'pagesFilteringDetails',
|
||||
component: () => import('/@/views/pages/filtering/details.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFilteringDetails',
|
||||
isLink: '',
|
||||
isHide: true,
|
||||
isKeepAlive: false,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-s-order',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/pages/filteringDetails',
|
||||
name: 'pagesFilteringDetails',
|
||||
component: () => import('/@/views/pages/filtering/details.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFilteringDetails',
|
||||
isLink: '',
|
||||
isHide: true,
|
||||
isKeepAlive: false,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-s-order',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/filteringDetails1',
|
||||
path: '/pages/filtering/details1',
|
||||
name: 'pagesFilteringDetails1',
|
||||
component: () => import('/@/views/pages/filtering/details1.vue'),
|
||||
meta: {
|
||||
@ -695,6 +703,21 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||
icon: 'iconfont icon-diqiu',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/formRules',
|
||||
name: 'pagesFormRules',
|
||||
component: () => import('/@/views/pages/formRules/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFormRules',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-shuxing',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/listAdapt',
|
||||
name: 'pagesListAdapt',
|
||||
|
||||
@ -5,6 +5,7 @@ import { ThemeConfigState, RootStateTypes } from '/@/store/interface/index';
|
||||
/**
|
||||
* 2020.05.28 by lyt 优化
|
||||
* 修改一下配置时,需要每次都清理 `window.localStorage` 浏览器永久缓存,配置才会生效
|
||||
* 哪个大佬有解决办法,欢迎pr,感谢💕!
|
||||
*/
|
||||
const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
|
||||
namespaced: true,
|
||||
@ -29,8 +30,9 @@ const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
|
||||
|
||||
/**
|
||||
* 菜单 / 顶栏
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
|
||||
* 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
|
||||
* 注意:v1.0.17 版本去除设置布局切换,重置主题样式(initSetLayoutChange),
|
||||
* 切换布局需手动设置样式,设置的样式自动同步各布局,
|
||||
* 代码位置:/@/layout/navBars/breadcrumb/setings.vue
|
||||
*/
|
||||
// 默认顶栏导航背景颜色,请注意:需要同时修改 `/@/theme/common/var.scss` 对应的值
|
||||
topBar: '#ffffff',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Module } from 'vuex';
|
||||
import { Session } from '/@/utils/storage.ts';
|
||||
import { Session } from '/@/utils/storage';
|
||||
// 此处加上 `.ts` 后缀报错,具体原因不详
|
||||
import { UserInfosState, RootStateTypes } from '/@/store/interface/index';
|
||||
|
||||
|
||||
@ -65,18 +65,44 @@ body,
|
||||
.layout-el-aside-br-color {
|
||||
border-right: 1px solid rgb(238, 238, 238);
|
||||
}
|
||||
.layout-aside-width-default {
|
||||
// pc端左侧导航样式
|
||||
.layout-aside-pc-220 {
|
||||
width: 220px !important;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
.layout-aside-width64 {
|
||||
.layout-aside-pc-64 {
|
||||
width: 64px !important;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
.layout-aside-width1 {
|
||||
.layout-aside-pc-1 {
|
||||
width: 1px !important;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
// 手机端左侧导航样式
|
||||
.layout-aside-mobile {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -220px;
|
||||
width: 220px;
|
||||
z-index: 1;
|
||||
}
|
||||
.layout-aside-mobile-close {
|
||||
left: -220px;
|
||||
transition: all 0.3s cubic-bezier(0.71, -0.01, 0.18, 0.95);
|
||||
}
|
||||
.layout-aside-mobile-open {
|
||||
left: 0;
|
||||
transition: all 0.3s cubic-bezier(0.53, -0.26, 0.42, 1.18);
|
||||
}
|
||||
.layout-aside-mobile-mode {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.layout-scrollbar {
|
||||
@extend .el-scrollbar;
|
||||
padding: 15px;
|
||||
|
||||
@ -747,6 +747,11 @@
|
||||
// 默认样式修改
|
||||
.el-menu {
|
||||
border-right: none !important;
|
||||
width: 220px;
|
||||
}
|
||||
// 修复点击左侧菜单折叠再展开时,宽度不跟随问题
|
||||
.el-menu--collapse {
|
||||
width: 64px !important;
|
||||
}
|
||||
.el-menu-item,
|
||||
.el-submenu__title {
|
||||
@ -798,8 +803,9 @@
|
||||
color: set-color(primary);
|
||||
}
|
||||
}
|
||||
// 高亮时
|
||||
.el-menu-item.is-active {
|
||||
// 高亮时/菜单收起时
|
||||
.el-menu-item.is-active,
|
||||
.el-menu--collapse .el-submenu.is-active i {
|
||||
color: set-color(primary);
|
||||
}
|
||||
.el-active-extend {
|
||||
@ -885,6 +891,9 @@
|
||||
color: set-color(primary);
|
||||
background-color: set-color(primary-light-9);
|
||||
}
|
||||
.el-dropdown-menu .el-dropdown-menu__item {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Steps 步骤条
|
||||
------------------------------- */
|
||||
|
||||
@ -202,7 +202,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, onMounted, getCurrentInstance, watch, nextTick } from 'vue';
|
||||
import { toRefs, reactive, computed, onMounted, getCurrentInstance, watch, nextTick, onActivated } from 'vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import ChartHead from '/@/views/chart/head.vue';
|
||||
import * as echarts from 'echarts';
|
||||
@ -225,8 +225,13 @@ export default {
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 初始化中间图表1
|
||||
const initChartsCenterOne = () => {
|
||||
@ -440,13 +445,17 @@ export default {
|
||||
state.myCharts.push(myChart);
|
||||
};
|
||||
// 批量设置 echarts resize
|
||||
const initEchartsResize = () => {
|
||||
window.addEventListener('resize', () => {
|
||||
const initEchartsResizeFun = () => {
|
||||
nextTick(() => {
|
||||
for (let i = 0; i < state.myCharts.length; i++) {
|
||||
state.myCharts[i].resize();
|
||||
}
|
||||
});
|
||||
};
|
||||
// 批量设置 echarts resize
|
||||
const initEchartsResize = () => {
|
||||
window.addEventListener('resize', initEchartsResizeFun);
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initChartsCenterOne();
|
||||
@ -456,15 +465,15 @@ export default {
|
||||
initChartsInvestment();
|
||||
initEchartsResize();
|
||||
});
|
||||
// 由于页面缓存原因,keep-alive
|
||||
onActivated(() => {
|
||||
initEchartsResizeFun();
|
||||
});
|
||||
// 监听 vuex 中的 tagsview 开启全屏变化,重新 resize 图表,防止不出现/大小不变等
|
||||
watch(
|
||||
() => store.state.tagsViewRoutes.isTagsViewCurrenFull,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
for (let i = 0; i < state.myCharts.length; i++) {
|
||||
state.myCharts[i].resize();
|
||||
}
|
||||
});
|
||||
initEchartsResizeFun();
|
||||
}
|
||||
);
|
||||
return {
|
||||
|
||||
@ -23,8 +23,13 @@ export default {
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// echartsMap 将坐标信息和对应物理量的值合在一起
|
||||
const convertData = (data) => {
|
||||
|
||||
@ -51,23 +51,23 @@ export default {
|
||||
// 0 刷新当前,1 关闭当前,2 关闭其它,3 关闭全部 4 当前页全屏
|
||||
// 1、刷新当前 tagsView
|
||||
const refreshCurrentTagsView = () => {
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 0, ...route }));
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 0, ...route }));
|
||||
};
|
||||
// 2、关闭当前 tagsView
|
||||
const closeCurrentTagsView = () => {
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 1, ...route }));
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
|
||||
};
|
||||
// 3、关闭其它 tagsView
|
||||
const closeOtherTagsView = () => {
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 2, ...route }));
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 2, ...route }));
|
||||
};
|
||||
// 4、关闭全部 tagsView
|
||||
const closeAllTagsView = () => {
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 3, ...route }));
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 3, ...route }));
|
||||
};
|
||||
// 5、开启当前页面全屏
|
||||
const openCurrenFullscreen = () => {
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { id: 4, ...route }));
|
||||
proxy.mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 4, ...route }));
|
||||
};
|
||||
return {
|
||||
refreshCurrentTagsView,
|
||||
|
||||
@ -23,8 +23,13 @@ export default {
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 初始化数据
|
||||
const initEchartsTree = () => {
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance, watch } from 'vue';
|
||||
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance, watch, onActivated } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { CountUp } from 'countup.js';
|
||||
import { formatAxis } from '/@/utils/formatTime';
|
||||
@ -290,13 +290,17 @@ export default {
|
||||
state.myCharts.push(myChart);
|
||||
};
|
||||
// 批量设置 echarts resize
|
||||
const initEchartsResize = () => {
|
||||
window.addEventListener('resize', () => {
|
||||
const initEchartsResizeFun = () => {
|
||||
nextTick(() => {
|
||||
for (let i = 0; i < state.myCharts.length; i++) {
|
||||
state.myCharts[i].resize();
|
||||
}
|
||||
});
|
||||
};
|
||||
// 批量设置 echarts resize
|
||||
const initEchartsResize = () => {
|
||||
window.addEventListener('resize', initEchartsResizeFun);
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initNumCountUp();
|
||||
@ -304,15 +308,15 @@ export default {
|
||||
initHomeOvertime();
|
||||
initEchartsResize();
|
||||
});
|
||||
// 由于页面缓存原因,keep-alive
|
||||
onActivated(() => {
|
||||
initEchartsResizeFun();
|
||||
});
|
||||
// 监听 vuex 中的 tagsview 开启全屏变化,重新 resize 图表,防止不出现/大小不变等
|
||||
watch(
|
||||
() => store.state.tagsViewRoutes.isTagsViewCurrenFull,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
for (let i = 0; i < state.myCharts.length; i++) {
|
||||
state.myCharts[i].resize();
|
||||
}
|
||||
});
|
||||
initEchartsResizeFun();
|
||||
}
|
||||
);
|
||||
return {
|
||||
|
||||
@ -21,8 +21,13 @@ export default {
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
return {
|
||||
initTagViewHeight,
|
||||
|
||||
@ -21,8 +21,13 @@ export default {
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
return {
|
||||
initTagViewHeight,
|
||||
|
||||
@ -145,12 +145,12 @@ export default {
|
||||
const onTableItemClick = (v: object) => {
|
||||
if (v.id === 1) {
|
||||
router.push({
|
||||
path: '/pages/filteringDetails',
|
||||
path: '/pages/filtering/details',
|
||||
query: { id: v.id },
|
||||
});
|
||||
} else {
|
||||
router.push({
|
||||
path: '/pages/filteringDetails1',
|
||||
path: '/pages/filtering/details1',
|
||||
query: { id: v.id },
|
||||
});
|
||||
}
|
||||
|
||||
67
src/views/pages/formRules/component/formRulesOne.vue
Normal file
67
src/views/pages/formRules/component/formRulesOne.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="form-rules-one-container">
|
||||
<el-form :model="form" :rules="rules" ref="formRulesOneRef" size="small" label-width="100px" class="mt35">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入用户邮箱" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="登陆账户名" prop="autograph">
|
||||
<el-input v-model="form.autograph" placeholder="请输入登陆账户名" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="职务" prop="occupation">
|
||||
<el-select v-model="form.occupation" placeholder="请选择职务" clearable class="w100">
|
||||
<el-option label="计算机 / 互联网 / 通信" value="1"></el-option>
|
||||
<el-option label="生产 / 工艺 / 制造" value="2"></el-option>
|
||||
<el-option label="医疗 / 护理 / 制药" value="3"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted } from 'vue';
|
||||
export default {
|
||||
name: 'pagesFormRulesOne',
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const state = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
name: { required: true, message: '请输入姓名', trigger: 'blur' },
|
||||
email: { required: true, message: '请输入用户邮箱', trigger: 'blur' },
|
||||
autograph: { required: true, message: '请输入登陆账户名', trigger: 'blur' },
|
||||
occupation: { required: true, message: '请选择职务', trigger: 'change' },
|
||||
},
|
||||
});
|
||||
// 赋值回显
|
||||
const initForm = () => {
|
||||
state.form = props.data;
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initForm();
|
||||
});
|
||||
return {
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
49
src/views/pages/formRules/component/formRulesThree.vue
Normal file
49
src/views/pages/formRules/component/formRulesThree.vue
Normal file
@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="form-rules-three-container">
|
||||
<el-form :model="form" :rules="rules" ref="formRulesThreeRef" size="small" label-width="100px" class="mt35">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="创建用户" prop="createUser">
|
||||
<el-input v-model="form.createUser" placeholder="请输入创建用户" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="修改用户" prop="editUser">
|
||||
<el-input v-model="form.editUser" placeholder="请输入修改用户" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="所属用户" prop="user">
|
||||
<el-input v-model="form.user" placeholder="请输入所属用户" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="所属部门" prop="department">
|
||||
<el-input v-model="form.department" placeholder="请输入所属部门" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive } from 'vue';
|
||||
export default {
|
||||
name: 'pagesFormRulesThree',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
createUser: { required: true, message: '请输入创建用户', trigger: 'blur' },
|
||||
editUser: { required: true, message: '请输入修改用户', trigger: 'blur' },
|
||||
user: { required: true, message: '请输入所属用户', trigger: 'blur' },
|
||||
department: { required: true, message: '请输入所属部门', trigger: 'blur' },
|
||||
},
|
||||
});
|
||||
return {
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
51
src/views/pages/formRules/component/formRulesTwo.vue
Normal file
51
src/views/pages/formRules/component/formRulesTwo.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="form-rules-two-container">
|
||||
<el-form :model="form" :rules="rules" ref="formRulesTwoRef" size="small" label-width="100px" class="mt35">
|
||||
<el-row :gutter="35">
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="手机" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="请输入手机" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="性别">
|
||||
<el-select v-model="form.sex" placeholder="请选择性别" clearable class="w100">
|
||||
<el-option label="男" value="1"></el-option>
|
||||
<el-option label="女" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="登录密码" prop="password">
|
||||
<el-input v-model="form.password" placeholder="请输入登录密码" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
||||
<el-form-item label="权限角色" prop="auth">
|
||||
<el-input v-model="form.auth" placeholder="请输入权限角色" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive } from 'vue';
|
||||
export default {
|
||||
name: 'pagesFormRulesTwo',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
phone: { required: true, message: '请输入手机', trigger: 'blur' },
|
||||
password: { required: true, message: '请输入登录密码', trigger: 'blur' },
|
||||
auth: { required: true, message: '请输入权限角色', trigger: 'blur' },
|
||||
},
|
||||
});
|
||||
return {
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
73
src/views/pages/formRules/index.vue
Normal file
73
src/views/pages/formRules/index.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="form-rules-container">
|
||||
<el-card shadow="hover" header="表单组件1"> <FormRulesOne :data="formRulesOneData" ref="pagesFormRulesOneRef" /></el-card>
|
||||
<el-card shadow="hover" header="表单组件2" class="mt15"><FormRulesTwo ref="pagesFormRulesTwoRef" /> </el-card>
|
||||
<el-card shadow="hover" header="表单组件3" class="mt15"> <FormRulesThree ref="pagesFormRulesThreeRef" /></el-card>
|
||||
<el-row class="flex mt15">
|
||||
<div class="flex-margin">
|
||||
<el-button size="small" icon="el-icon-refresh-right" @click="onResetForm">重置表单</el-button>
|
||||
<el-button size="small" type="primary" icon="iconfont icon-shuxing" @click="onSubmitForm">验证表单</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, defineComponent, getCurrentInstance } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import FormRulesOne from '/@/views/pages/formRules/component/formRulesOne.vue';
|
||||
import FormRulesTwo from '/@/views/pages/formRules/component/formRulesTwo.vue';
|
||||
import FormRulesThree from '/@/views/pages/formRules/component/formRulesThree.vue';
|
||||
export default defineComponent({
|
||||
name: 'pagesFormRules',
|
||||
components: {
|
||||
FormRulesOne,
|
||||
FormRulesTwo,
|
||||
FormRulesThree,
|
||||
},
|
||||
setup() {
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const state = reactive({
|
||||
formRulesOneData: {
|
||||
name: 'lyt',
|
||||
email: 'lyt123@.com',
|
||||
autograph: 'lyt123456',
|
||||
occupation: '1',
|
||||
},
|
||||
});
|
||||
// 表单组件验证
|
||||
const formRulesValidate = (pageRef, sonRef) => {
|
||||
return new Promise((resolve) => {
|
||||
proxy.$refs[pageRef].$refs[sonRef].validate((valid) => {
|
||||
if (valid) resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
// 表单组件重置
|
||||
const formRulesResetFields = () => {
|
||||
proxy.$refs.pagesFormRulesOneRef.$refs.formRulesOneRef.resetFields();
|
||||
proxy.$refs.pagesFormRulesTwoRef.$refs.formRulesTwoRef.resetFields();
|
||||
proxy.$refs.pagesFormRulesThreeRef.$refs.formRulesThreeRef.resetFields();
|
||||
};
|
||||
// 验证表单
|
||||
const onSubmitForm = () => {
|
||||
Promise.all([
|
||||
formRulesValidate('pagesFormRulesOneRef', 'formRulesOneRef'),
|
||||
formRulesValidate('pagesFormRulesTwoRef', 'formRulesTwoRef'),
|
||||
formRulesValidate('pagesFormRulesThreeRef', 'formRulesThreeRef'),
|
||||
]).then(() => {
|
||||
ElMessage.success('表单全部验证成功');
|
||||
});
|
||||
};
|
||||
// 重置表单
|
||||
const onResetForm = () => {
|
||||
formRulesResetFields();
|
||||
};
|
||||
return {
|
||||
onSubmitForm,
|
||||
onResetForm,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -23,8 +23,13 @@ export default defineComponent({
|
||||
// 设置 view 的高度
|
||||
const setViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
||||
@ -26,8 +26,13 @@ export default defineComponent({
|
||||
// 设置 view 的高度
|
||||
const setViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 跳转到详情
|
||||
const onGoDetailsClick = () => {
|
||||
|
||||
@ -23,8 +23,13 @@ export default defineComponent({
|
||||
// 设置 view 的高度
|
||||
const setViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
||||
@ -26,8 +26,13 @@ export default defineComponent({
|
||||
// 设置 view 的高度
|
||||
const setViewHeight = computed(() => {
|
||||
let { isTagsview } = store.state.themeConfig.themeConfig;
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
let { isTagsViewCurrenFull } = store.state.tagsViewRoutes;
|
||||
if (isTagsViewCurrenFull) {
|
||||
return `30px`;
|
||||
} else {
|
||||
if (isTagsview) return `114px`;
|
||||
else return `80px`;
|
||||
}
|
||||
});
|
||||
// 跳转到详情
|
||||
const onGoDetailsClick = () => {
|
||||
|
||||
@ -30,9 +30,9 @@
|
||||
class="mt15"
|
||||
:pager-count="5"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
:current-page="tableData.param.pageNum"
|
||||
v-model:current-page="tableData.param.pageNum"
|
||||
background
|
||||
:page-size="tableData.param.pageSize"
|
||||
v-model:page-size="tableData.param.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total"
|
||||
>
|
||||
@ -84,7 +84,7 @@ export default {
|
||||
};
|
||||
// 分页改变
|
||||
const onHandleCurrentChange = (val: number) => {
|
||||
state.tableData.param.pageSize = val;
|
||||
state.tableData.param.pageNum = val;
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
||||
@ -10,7 +10,7 @@ const pathResolve = (dir: string): any => {
|
||||
const { VITE_PORT, VITE_OPEN, VITE_PUBLIC_PATH } = loadEnv();
|
||||
|
||||
const alias: Record<string, string> = {
|
||||
'/@': pathResolve('/src/'),
|
||||
'/@': pathResolve('./src/'),
|
||||
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js',
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user