mirror of
https://gitee.com/lyt-top/vue-next-admin
synced 2026-06-18 22:35:59 +08:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e57dde4bab | |||
| fdf9cd4abe | |||
| 664e70de6c | |||
| 4259e9931f | |||
| 3a57a7f4ff | |||
| fab396b503 | |||
| 41f6992630 | |||
| a402bd3c3a | |||
| 7d004ee948 | |||
| 5a75f2626e | |||
| 21248a361e | |||
| 6441700ae1 | |||
| f716918ef2 | |||
| abf9f1ae08 |
25
CHANGELOG.md
25
CHANGELOG.md
@ -2,6 +2,31 @@
|
||||
|
||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
|
||||
## 2.2.0
|
||||
|
||||
`2022.07.10`
|
||||
|
||||
⚡⚡⚡ [/sec/stores/userInfo.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/stores/userInfo.ts) 下添加了 `getApiUserInfo` 接口模拟数据 `setTimeout` 为 3 秒
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🐞 修复 [主界面重新授权按钮点击卡死不跳转登录界面#I5C3JS](https://gitee.com/lyt-top/vue-next-admin/issues/I5C3JS),感谢[@Hero-Typ](https://gitee.com/tian_yu_peng)
|
||||
- 🐞 修复 编译警告[#I5CVSB](https://gitee.com/lyt-top/vue-next-admin/issues/I5CVSB),全局替换成 `:deep(attr)`,感谢[@Linvas](https://gitee.com/linvas)。参考文档:[vue3 sfc-style](https://v3.cn.vuejs.org/api/sfc-style.html#style-scoped)。`node_modules\print-js\dist\print.js` 需 `print-js` 作者适配或去除 `package.json` 中的 `"print-js": "^1.6.0"`
|
||||
- 🐞 修复 [vue-next-admin-template-js 版本前端控制路由:userInfo.js 请求用户信息接口报错,加载不到路由 可以写个定时器模拟一下接口 一样的报错#I5F1HP](https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP),感谢[@白开水](https://gitee.com/libin951223)
|
||||
|
||||
## 2.1.1
|
||||
|
||||
`2022.05.27`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎯 优化 深色模式下,`<el-button text></el-button>` 时,`:active` 样式
|
||||
- 🎯 优化 [页面缓存在刷新之后失效 #I58U75](https://gitee.com/lyt-top/vue-next-admin/issues/I58U75)),感谢[@ls0428](https://gitee.com/ls0428)
|
||||
- 🎯 优化 [SvgIcon 对下载的 Svg 图像设置颜色无效 #I59ND0](https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0)),感谢[@elus_z](https://gitee.com/elus_z)
|
||||
- 🎯 优化 `/src/utils/toolsValidate.ts` 工具类
|
||||
- 🐞 修复 [布局切换,TagsView 显示的 tab 会多一个出来 #I58WGM](https://gitee.com/lyt-top/vue-next-admin/issues/I58WGM),感谢[@lg_boy](https://gitee.com/lg_boy)
|
||||
- 🐞 修复 [如果设置顶部面包屑导航开启图标 isBreadcrumbIcon=true 后,样式有点问题 如果不开启就是正常的 #I58VB8](https://gitee.com/lyt-top/vue-next-admin/issues/I58VB8)
|
||||
- 🐞 修复 地址栏路由地址输入错误时,返回首页后,再次输入路由地址错误时,不跳转 404 问题
|
||||
- 🐞 修复 [2.1.0 版本的图标选择组件多次点击后功能失效 #I590TH](https://gitee.com/lyt-top/vue-next-admin/issues/I590TH),感谢[@quber](https://gitee.com/quber)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
`2022.04.18`
|
||||
|
||||
20
README.md
20
README.md
@ -41,9 +41,9 @@
|
||||
|
||||
#### 🏭 环境支持
|
||||
|
||||
| Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
|
||||
|  |  |  |  |
|
||||
| Edge | Firefox | Chrome | Safari |
|
||||
| --------- | ------------ | ----------- | ----------- |
|
||||
| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 64 | Safari ≥ 12 |
|
||||
|
||||
> 由于 Vue3 不再支持 IE11,故而 ElementPlus 也不支持 IE11 及之前版本。
|
||||
|
||||
@ -76,15 +76,19 @@ cnpm run build
|
||||
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>
|
||||
3 群:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=02EWb5P2JkP-8iwzaDadgFdxA0HSHPpn&jump_from=webapi">795345435</a>
|
||||
4 群:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=0gTFO04WwkeZZ6R4lju6gucbeXHK-wNd&jump_from=webapi">736626228</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 讨论群1" title="vue-next-admin 讨论群1"/>
|
||||
<img src="https://img-blog.csdnimg.cn/35e00f12a3fe4820892ec630ca72f15f.png" width="220" height="220" alt="vue-next-admin 讨论群1" 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 讨论群2" title="vue-next-admin 讨论群2"/>
|
||||
<img src="https://img-blog.csdnimg.cn/5f1b548abd9f434eb41edde31d1c1fa9.png" width="220" height="220" alt="vue-next-admin 讨论群2" title="vue-next-admin 讨论群2"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=02EWb5P2JkP-8iwzaDadgFdxA0HSHPpn&jump_from=webapi">
|
||||
<img src="https://gitee.com/lyt-top/vue-next-admin-images/raw/master/user/qq3.png" width="220" height="220" alt="vue-next-admin 讨论群3" title="vue-next-admin 讨论群3"/>
|
||||
<img src="https://img-blog.csdnimg.cn/70c8a012dd304246bddeac2184c4ab3a.png" width="220" height="220" alt="vue-next-admin 讨论群3" title="vue-next-admin 讨论群3"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=0gTFO04WwkeZZ6R4lju6gucbeXHK-wNd&jump_from=webapi">
|
||||
<img src="https://img-blog.csdnimg.cn/e5c9704eed1342bc9d9e74b37203402d.png" width="220" height="220" alt="vue-next-admin 讨论群4" title="vue-next-admin 讨论群4"/>
|
||||
</a>
|
||||
|
||||
#### 💒 集成后端
|
||||
@ -96,6 +100,8 @@ cnpm run build
|
||||
- <a target="_blank" href="https://gitee.com/diygw/diygw-ui-php/">@diygw.com gw-ui-php</a>
|
||||
- <a target="_blank" href="https://gitee.com/zsvg/vboot-net">@zsvg vboot-net</a>
|
||||
- <a target="_blank" href="https://gitee.com/zsvg/vboot-java">@zsvg vboot-java</a>
|
||||
- <a target="_blank" href="https://gitee.com/wonderful-code/buildadmin">@青红造了个白 buildadmin</a>
|
||||
- <a target="_blank" href="https://github.com/xiaodingding/iotfast">@Goodwell iotfast(一个开源的物联网平台)</a>
|
||||
|
||||
#### ❤️ 鸣谢列表
|
||||
|
||||
@ -129,7 +135,7 @@ cnpm run build
|
||||
特别感谢老哥们的建议、指导与帮忙。谢谢!
|
||||
|
||||
- <a href="https://gitee.com/click33/sa-plus" target="_blank">@省长</a>
|
||||
- <a href="https://gitee.com/jskz/Jskz-SpringCloud" target="_blank">@唐参
|
||||
- <a href="https://gitee.com/jskz/Jskz-SpringCloud" target="_blank">@唐参</a>
|
||||
- <a href="https://gitee.com/chuange" target="_blank">@川歌</a>
|
||||
- @华仔
|
||||
|
||||
|
||||
879
package-lock.json
generated
879
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-next-admin",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "vue3 vite next admin template",
|
||||
"author": "lyt_20201208",
|
||||
"license": "MIT",
|
||||
@ -10,15 +10,15 @@
|
||||
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^1.1.4",
|
||||
"@wangeditor/editor": "^5.0.1",
|
||||
"@element-plus/icons-vue": "^2.0.6",
|
||||
"@wangeditor/editor": "^5.1.1",
|
||||
"axios": "^0.27.2",
|
||||
"countup.js": "^2.2.0",
|
||||
"countup.js": "^2.3.2",
|
||||
"cropperjs": "^1.5.12",
|
||||
"echarts": "^5.3.2",
|
||||
"echarts": "^5.3.3",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"echarts-wordcloud": "^2.0.0",
|
||||
"element-plus": "^2.2.1",
|
||||
"element-plus": "^2.2.9",
|
||||
"js-cookie": "^3.0.1",
|
||||
"jsplumb": "^2.15.6",
|
||||
"mitt": "^3.0.0",
|
||||
@ -26,32 +26,32 @@
|
||||
"pinia": "^2.0.14",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcodejs2-fixes": "^0.0.2",
|
||||
"screenfull": "^6.0.1",
|
||||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"splitpanes": "^3.1.1",
|
||||
"vue": "^3.2.35",
|
||||
"vue": "^3.2.37",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-grid-layout": "^3.0.0-beta1",
|
||||
"vue-i18n": "^9.1.10",
|
||||
"vue-router": "^4.0.15"
|
||||
"vue-router": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.35",
|
||||
"@types/node": "^18.0.3",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/sortablejs": "^1.13.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.25.0",
|
||||
"@typescript-eslint/parser": "^5.25.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"@vitejs/plugin-vue": "^2.3.3",
|
||||
"@vue/compiler-sfc": "^3.2.35",
|
||||
"@vue/compiler-sfc": "^3.2.37",
|
||||
"dotenv": "^16.0.1",
|
||||
"eslint": "^8.16.0",
|
||||
"eslint-plugin-vue": "^9.0.1",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "^1.52.1",
|
||||
"sass-loader": "^13.0.0",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^2.9.9",
|
||||
"vue-eslint-parser": "^9.0.2"
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-plugin-vue": "^9.2.0",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.53.0",
|
||||
"sass-loader": "^13.0.2",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^2.9.14",
|
||||
"vue-eslint-parser": "^9.0.3"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="editor-container">
|
||||
<div id="editor-toolbar"></div>
|
||||
<div :id="id" :style="{ height }"></div>
|
||||
<div ref="editorToolbar"></div>
|
||||
<div ref="editorContent" :style="{ height }"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -13,6 +13,8 @@ import { toolbarKeys } from './toolbar';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface WangeditorState {
|
||||
editorToolbar: HTMLDivElement | null;
|
||||
editorContent: HTMLDivElement | null;
|
||||
editor: any;
|
||||
}
|
||||
|
||||
@ -51,7 +53,9 @@ export default defineComponent({
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const state = reactive<WangeditorState>({
|
||||
editorToolbar: null,
|
||||
editor: null,
|
||||
editorContent: null,
|
||||
});
|
||||
// 富文本配置
|
||||
const wangeditorConfig = () => {
|
||||
@ -79,13 +83,13 @@ export default defineComponent({
|
||||
const initWangeditor = () => {
|
||||
state.editor = createEditor({
|
||||
html: props.modelValue,
|
||||
selector: `#${props.id}`,
|
||||
selector: state.editorContent!,
|
||||
config: wangeditorConfig(),
|
||||
mode: props.mode,
|
||||
});
|
||||
createToolbar({
|
||||
editor: state.editor,
|
||||
selector: '#editor-toolbar',
|
||||
selector: state.editorToolbar!,
|
||||
mode: props.mode,
|
||||
config: toolbarConfig(),
|
||||
});
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
<template>
|
||||
<div class="icon-selector w100 h100">
|
||||
<el-popover placement="bottom" :width="fontIconWidth" trigger="click" transition="el-zoom-in-top" popper-class="icon-selector-popper">
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
:width="fontIconWidth"
|
||||
trigger="click"
|
||||
transition="el-zoom-in-top"
|
||||
popper-class="icon-selector-popper"
|
||||
@show="onPopoverShow"
|
||||
>
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="fontIconSearch"
|
||||
@ -126,7 +133,6 @@ export default defineComponent({
|
||||
if (!props.modelValue) return false;
|
||||
state.fontIconSearch = '';
|
||||
state.fontIconPlaceholder = props.modelValue;
|
||||
initFontIconTypeEcho();
|
||||
};
|
||||
// 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
|
||||
const onIconBlur = () => {
|
||||
@ -137,7 +143,7 @@ export default defineComponent({
|
||||
};
|
||||
// 处理 icon 双向绑定数值回显
|
||||
const initModeValueEcho = () => {
|
||||
if (props.modelValue === '') return false;
|
||||
if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
|
||||
(<string | undefined>state.fontIconPlaceholder) = props.modelValue;
|
||||
(<string | undefined>state.fontIconPrefix) = props.modelValue;
|
||||
};
|
||||
@ -191,8 +197,6 @@ export default defineComponent({
|
||||
state.fontIconPlaceholder = props.placeholder;
|
||||
// 初始化双向绑定回显
|
||||
initModeValueEcho();
|
||||
// 切换时,滚动条置顶。感兴趣可以使用 keep-alive <component :is="xxx"/> 进行缓存
|
||||
selectorScrollbarRef.value.wrap$.scrollTop = 0;
|
||||
};
|
||||
// 图标点击切换
|
||||
const onIconChange = (type: string) => {
|
||||
@ -212,14 +216,18 @@ export default defineComponent({
|
||||
emit('clear', state.fontIconPrefix);
|
||||
emit('update:modelValue', state.fontIconPrefix);
|
||||
};
|
||||
// 监听 Popover 打开,用于双向绑定值回显
|
||||
const onPopoverShow = () => {
|
||||
initModeValueEcho();
|
||||
initFontIconTypeEcho();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
// 判断默认进来是什么类型图标,进行 tab 回显
|
||||
if (props.type === 'all') initFontIconTypeEcho();
|
||||
else onIconChange(props.type);
|
||||
initModeValueEcho();
|
||||
initResize();
|
||||
getInputWidth();
|
||||
});
|
||||
|
||||
// 监听双向绑定 modelValue 的变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
@ -236,6 +244,7 @@ export default defineComponent({
|
||||
onClearFontIcon,
|
||||
onIconFocus,
|
||||
onIconBlur,
|
||||
onPopoverShow,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
|
||||
@ -172,7 +172,7 @@ export default defineComponent({
|
||||
.notice-bar-warp-slot {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
::v-deep(.el-carousel__item) {
|
||||
:deep(.el-carousel__item) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@ -2,7 +2,9 @@
|
||||
<i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle">
|
||||
<component :is="getIconName" />
|
||||
</i>
|
||||
<img v-else-if="isShowIconImg" :src="getIconName" :style="setIconImgStyle" />
|
||||
<div v-else-if="isShowIconImg" :style="setIconImgOutStyle">
|
||||
<img :src="getIconName" :style="setIconSvgInsStyle" />
|
||||
</div>
|
||||
<i v-else :class="getIconName" :style="setIconSvgStyle" />
|
||||
</template>
|
||||
|
||||
@ -47,15 +49,24 @@ export default defineComponent({
|
||||
return `font-size: ${props.size}px;color: ${props.color};`;
|
||||
});
|
||||
// 设置图片样式
|
||||
const setIconImgStyle = computed(() => {
|
||||
return `width: ${props.size}px;height: ${props.size}px`;
|
||||
const setIconImgOutStyle = computed(() => {
|
||||
return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;`;
|
||||
});
|
||||
// 设置图片样式
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0
|
||||
const setIconSvgInsStyle = computed(() => {
|
||||
const filterStyle: string[] = [];
|
||||
const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];
|
||||
compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} 30px 0);`));
|
||||
return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;
|
||||
});
|
||||
return {
|
||||
getIconName,
|
||||
isShowIconSvg,
|
||||
isShowIconImg,
|
||||
setIconSvgStyle,
|
||||
setIconImgStyle,
|
||||
setIconImgOutStyle,
|
||||
setIconSvgInsStyle,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
<div v-show="isShowLoockLogin" class="layout-lock-screen-login">
|
||||
<div class="layout-lock-screen-login-box">
|
||||
<div class="layout-lock-screen-login-box-img">
|
||||
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg" />
|
||||
<img src="https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500" />
|
||||
</div>
|
||||
<div class="layout-lock-screen-login-box-name">Administrator</div>
|
||||
<div class="layout-lock-screen-login-box-value">
|
||||
@ -359,11 +359,11 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep(.el-input-group__append) {
|
||||
:deep(.el-input-group__append) {
|
||||
background: var(--el-color-white);
|
||||
padding: 0px 15px;
|
||||
}
|
||||
::v-deep(.el-input__inner) {
|
||||
:deep(.el-input__inner) {
|
||||
border-right-color: var(--el-border-color-extra-light);
|
||||
&:hover {
|
||||
border-color: var(--el-border-color-extra-light);
|
||||
|
||||
@ -100,8 +100,8 @@ export default defineComponent({
|
||||
state.routeSplitFirst = `/${state.routeSplit[0]}`;
|
||||
state.routeSplitIndex = 1;
|
||||
getBreadcrumbList(routesList.value);
|
||||
if (route.name === 'home') state.breadcrumbList.shift();
|
||||
state.breadcrumbList[state.breadcrumbList.length - 1].meta.tagsViewName = other.setTagsViewNameI18n(route);
|
||||
if (route.name === 'home' || (route.name === 'notFound' && state.breadcrumbList.length > 1)) state.breadcrumbList.shift();
|
||||
if (state.breadcrumbList.length > 0) state.breadcrumbList[state.breadcrumbList.length - 1].meta.tagsViewName = other.setTagsViewNameI18n(route);
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
@ -140,6 +140,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
.layout-navbars-breadcrumb-span {
|
||||
display: flex;
|
||||
opacity: 0.7;
|
||||
color: var(--next-bg-topBarColor);
|
||||
}
|
||||
@ -147,11 +148,11 @@ export default defineComponent({
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
::v-deep(.el-breadcrumb__separator) {
|
||||
:deep(.el-breadcrumb__separator) {
|
||||
opacity: 0.7;
|
||||
color: var(--next-bg-topBarColor);
|
||||
}
|
||||
::v-deep(.el-breadcrumb__inner a, .el-breadcrumb__inner.is-link) {
|
||||
:deep(.el-breadcrumb__inner a, .el-breadcrumb__inner.is-link) {
|
||||
font-weight: unset !important;
|
||||
color: var(--next-bg-topBarColor);
|
||||
&:hover {
|
||||
|
||||
@ -42,7 +42,7 @@ export default defineComponent({
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
::v-deep(i) {
|
||||
:deep(i) {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 35px;
|
||||
@ -52,7 +52,7 @@ export default defineComponent({
|
||||
}
|
||||
&:hover {
|
||||
transition: all 0.3s ease;
|
||||
::v-deep(i) {
|
||||
:deep(i) {
|
||||
color: var(--el-color-primary);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
@ -122,12 +122,12 @@ export default defineComponent({
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout-search-dialog {
|
||||
::v-deep(.el-dialog) {
|
||||
:deep(.el-dialog) {
|
||||
box-shadow: unset !important;
|
||||
border-radius: 0 !important;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
::v-deep(.el-autocomplete) {
|
||||
:deep(.el-autocomplete) {
|
||||
width: 560px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
|
||||
@ -679,7 +679,7 @@ export default defineComponent({
|
||||
.layout-breadcrumb-seting-bar {
|
||||
height: calc(100vh - 50px);
|
||||
padding: 0 15px;
|
||||
::v-deep(.el-scrollbar__view) {
|
||||
:deep(.el-scrollbar__view) {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
.layout-breadcrumb-seting-bar-flex {
|
||||
|
||||
@ -160,7 +160,8 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
.then(async () => {
|
||||
Session.clear(); // 清除缓存/token等
|
||||
// 清除缓存/token等
|
||||
Session.clear();
|
||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||
window.location.reload();
|
||||
})
|
||||
@ -282,16 +283,16 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep(.el-dropdown) {
|
||||
:deep(.el-dropdown) {
|
||||
color: var(--next-bg-topBarColor);
|
||||
}
|
||||
::v-deep(.el-badge) {
|
||||
:deep(.el-badge) {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep(.el-badge__content.is-fixed) {
|
||||
:deep(.el-badge__content.is-fixed) {
|
||||
top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ export default defineComponent({
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
::v-deep(.el-empty__description p) {
|
||||
:deep(.el-empty__description p) {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,8 +205,8 @@ export default defineComponent({
|
||||
if (findItem.meta.isLink && !findItem.meta.isIframe) return false;
|
||||
to.meta.isDynamic ? (findItem.params = to.params) : (findItem.query = to.query);
|
||||
findItem.url = setTagsViewHighlight(findItem);
|
||||
await storesKeepALiveNames.addCachedView(findItem);
|
||||
state.tagsViewList.push({ ...findItem });
|
||||
await storesKeepALiveNames.addCachedView(findItem);
|
||||
addBrowserSetSession(state.tagsViewList);
|
||||
}
|
||||
};
|
||||
@ -607,7 +607,7 @@ export default defineComponent({
|
||||
border-bottom: 1px solid var(--next-border-color-light);
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
::v-deep(.el-scrollbar__wrap) {
|
||||
:deep(.el-scrollbar__wrap) {
|
||||
overflow-x: auto !important;
|
||||
}
|
||||
&-ul {
|
||||
|
||||
@ -141,10 +141,10 @@ export default defineComponent({
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
margin-right: 30px;
|
||||
::v-deep(.el-scrollbar__bar.is-vertical) {
|
||||
:deep(.el-scrollbar__bar.is-vertical) {
|
||||
display: none;
|
||||
}
|
||||
::v-deep(a) {
|
||||
:deep(a) {
|
||||
width: 100%;
|
||||
}
|
||||
.el-menu.el-menu--horizontal {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="layout-view-bg-white flex mt1" :style="{ height: `calc(100vh - ${setIframeHeight}`, border: 'none' }" v-loading="iframeLoading">
|
||||
<iframe :src="iframeUrl" frameborder="0" height="100%" width="100%" id="iframe" v-show="!iframeLoading"></iframe>
|
||||
<iframe :src="iframeUrl" frameborder="0" height="100%" width="100%" ref="iframeDom" v-show="!iframeLoading"></iframe>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -20,6 +20,7 @@ export default defineComponent({
|
||||
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
|
||||
const route = useRoute();
|
||||
const state = reactive({
|
||||
iframeDom: null as HTMLIFrameElement | null,
|
||||
iframeLoading: true,
|
||||
iframeUrl: '',
|
||||
});
|
||||
@ -28,7 +29,7 @@ export default defineComponent({
|
||||
state.iframeUrl = <any>route.meta.isLink;
|
||||
nextTick(() => {
|
||||
state.iframeLoading = true;
|
||||
const iframe = document.getElementById('iframe');
|
||||
const iframe = state.iframeDom;
|
||||
if (!iframe) return false;
|
||||
iframe.onload = () => {
|
||||
state.iframeLoading = false;
|
||||
|
||||
@ -11,11 +11,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick, watch } from 'vue';
|
||||
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick, watch, onMounted } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
|
||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||
import { Session } from '/@/utils/storage';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface ParentViewState {
|
||||
@ -56,6 +57,16 @@ export default defineComponent({
|
||||
});
|
||||
});
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I58U75
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I59RXK
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (themeConfig.value.isCacheTagsView) cachedViews.value = Session.get('tagsViewList')?.map((item: any) => item.name);
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
// 页面卸载时
|
||||
onUnmounted(() => {
|
||||
proxy.mittBus.off('onTagsViewRefreshRouterView', () => {});
|
||||
|
||||
@ -33,14 +33,14 @@ const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...lay
|
||||
* @method setAddRoute 添加动态路由
|
||||
* @method setFilterMenuAndCacheTagsViewRoutes 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
*/
|
||||
|
||||
export async function initBackEndControlRoutes() {
|
||||
// 界面 loading 动画开始执行
|
||||
if (window.nextLoading === undefined) NextLoading.start();
|
||||
// 无 token 停止执行下一步
|
||||
if (!Session.get('token')) return false;
|
||||
// 触发初始化用户信息 pinia
|
||||
useUserInfo().setUserInfos();
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||
await useUserInfo().setUserInfos();
|
||||
// 获取路由菜单数据
|
||||
const res = await getBackEndControlRoutes();
|
||||
// 存储接口原始路由(未处理component),根据需求选择使用
|
||||
|
||||
@ -24,7 +24,8 @@ export async function initFrontEndControlRoutes() {
|
||||
// 无 token 停止执行下一步
|
||||
if (!Session.get('token')) return false;
|
||||
// 触发初始化用户信息 pinia
|
||||
useUserInfo(pinia).setUserInfos();
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||
await useUserInfo(pinia).setUserInfos();
|
||||
// 添加动态路由
|
||||
await setAddRoute();
|
||||
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
|
||||
@ -85,9 +85,6 @@ export function formatTwoStageRoutes(arr: any) {
|
||||
return newArr;
|
||||
}
|
||||
|
||||
// isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
|
||||
if (!isRequestRoutes) initFrontEndControlRoutes();
|
||||
|
||||
// 路由加载前
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.configure({ showSpinner: false });
|
||||
@ -114,6 +111,10 @@ router.beforeEach(async (to, from, next) => {
|
||||
// 动态添加路由:防止非首页刷新时跳转回首页的问题
|
||||
// 确保 addRoute() 时动态添加的路由已经被完全加载上去
|
||||
next({ ...to, replace: true });
|
||||
} else {
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||
await initFrontEndControlRoutes();
|
||||
next({ ...to, replace: true });
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
|
||||
@ -1164,18 +1164,6 @@ export const notFoundAndNoPower = [
|
||||
* @returns 返回路由菜单数据
|
||||
*/
|
||||
export const staticRoutes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/',
|
||||
name: '/',
|
||||
component: () => import('/@/layout/index.vue'),
|
||||
meta: {
|
||||
title: '布局界面',
|
||||
},
|
||||
children: [
|
||||
// 请不要往这里 `children` 中添加内容,此内容为了防止 No match found for location with path "xxx" 问题
|
||||
...notFoundAndNoPower,
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
|
||||
@ -19,46 +19,54 @@ export const useUserInfo = defineStore('userInfo', {
|
||||
}),
|
||||
actions: {
|
||||
async setUserInfos() {
|
||||
// 模拟数据,请求接口时,记得删除多余代码及对应依赖的引入
|
||||
const userName = Cookies.get('userName');
|
||||
// 模拟数据
|
||||
let defaultRoles: Array<string> = [];
|
||||
let defaultAuthBtnList: Array<string> = [];
|
||||
// admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
||||
let adminRoles: Array<string> = ['admin'];
|
||||
// admin 按钮权限标识
|
||||
let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
|
||||
// test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
||||
let testRoles: Array<string> = ['common'];
|
||||
// test 按钮权限标识
|
||||
let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
|
||||
// 不同用户模拟不同的用户权限
|
||||
if (userName === 'admin') {
|
||||
defaultRoles = adminRoles;
|
||||
defaultAuthBtnList = adminAuthBtnList;
|
||||
} else {
|
||||
defaultRoles = testRoles;
|
||||
defaultAuthBtnList = testAuthBtnList;
|
||||
}
|
||||
// 用户信息模拟数据
|
||||
const userInfos = {
|
||||
userName: userName,
|
||||
photo:
|
||||
userName === 'admin'
|
||||
? 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg'
|
||||
: 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
|
||||
time: new Date().getTime(),
|
||||
roles: defaultRoles,
|
||||
authBtnList: defaultAuthBtnList,
|
||||
};
|
||||
// 存储用户信息到浏览器缓存
|
||||
Session.set('userInfo', userInfos);
|
||||
|
||||
if (Session.get('userInfo')) {
|
||||
this.userInfos = Session.get('userInfo');
|
||||
} else {
|
||||
const userInfos: any = await this.getApiUserInfo();
|
||||
this.userInfos = userInfos;
|
||||
}
|
||||
},
|
||||
// 模拟接口数据
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||
async getApiUserInfo() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
// 模拟数据,请求接口时,记得删除多余代码及对应依赖的引入
|
||||
const userName = Cookies.get('userName');
|
||||
// 模拟数据
|
||||
let defaultRoles: Array<string> = [];
|
||||
let defaultAuthBtnList: Array<string> = [];
|
||||
// admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
||||
let adminRoles: Array<string> = ['admin'];
|
||||
// admin 按钮权限标识
|
||||
let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
|
||||
// test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
|
||||
let testRoles: Array<string> = ['common'];
|
||||
// test 按钮权限标识
|
||||
let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
|
||||
// 不同用户模拟不同的用户权限
|
||||
if (userName === 'admin') {
|
||||
defaultRoles = adminRoles;
|
||||
defaultAuthBtnList = adminAuthBtnList;
|
||||
} else {
|
||||
defaultRoles = testRoles;
|
||||
defaultAuthBtnList = testAuthBtnList;
|
||||
}
|
||||
// 用户信息模拟数据
|
||||
const userInfos = {
|
||||
userName: userName,
|
||||
photo:
|
||||
userName === 'admin'
|
||||
? 'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500'
|
||||
: 'https://img2.baidu.com/it/u=2370931438,70387529&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
||||
time: new Date().getTime(),
|
||||
roles: defaultRoles,
|
||||
authBtnList: defaultAuthBtnList,
|
||||
};
|
||||
resolve(userInfos);
|
||||
}, 3000);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -52,9 +52,12 @@
|
||||
--el-text-color-placeholder: var(--next-text-color-placeholder) !important;
|
||||
--el-disabled-bg-color: var(--next-color-disabled) !important;
|
||||
--el-fill-base: var(--next-color-white) !important;
|
||||
--el-fill-colo: var(--next-color-hover-rgba) !important;
|
||||
--el-fill-color: var(--next-color-hover-rgba) !important;
|
||||
--el-fill-color-blank: var(--next-color-disabled) !important;
|
||||
--el-fill-color-light: var(--next-color-hover-rgba) !important;
|
||||
--el-bg-color-overlay: var(--el-color-primary-light-9) !important;
|
||||
--el-mask-color: rgb(42 42 42 / 80%);
|
||||
|
||||
// button
|
||||
.el-button {
|
||||
|
||||
@ -51,7 +51,7 @@ export function setTagsViewNameI18n(item: any) {
|
||||
let tagsViewName: any = '';
|
||||
const { query, params, meta } = item;
|
||||
if (query?.tagsViewName || params?.tagsViewName) {
|
||||
if (/zh-cn|en|zh-tw/.test(query?.tagsViewName) || /zh-cn|en|zh-tw/.test(params?.tagsViewName)) {
|
||||
if (/\/zh-cn|en|zh-tw\//.test(query?.tagsViewName) || /\/(zh-cn|en|zh-tw)\//.test(params?.tagsViewName)) {
|
||||
// 国际化
|
||||
const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName));
|
||||
tagsViewName = urlTagsParams[i18n.global.locale];
|
||||
@ -113,7 +113,7 @@ export function deepClone(obj: any) {
|
||||
newObj = {};
|
||||
}
|
||||
for (let attr in obj) {
|
||||
if (typeof obj[attr] === 'object') {
|
||||
if (obj[attr] && typeof obj[attr] === 'object') {
|
||||
newObj[attr] = deepClone(obj[attr]);
|
||||
} else {
|
||||
newObj[attr] = obj[attr];
|
||||
|
||||
@ -190,7 +190,7 @@ export function verifyNumberCnUppercase(val: any, unit = '仟佰拾亿仟佰拾
|
||||
*/
|
||||
export function verifyPhone(val: string) {
|
||||
// false: 手机号码不正确
|
||||
if (!/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/.test(val)) return false;
|
||||
if (!/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0|1,5-9]))\d{8}$/.test(val)) return false;
|
||||
// true: 手机号码正确
|
||||
else return true;
|
||||
}
|
||||
|
||||
@ -412,15 +412,15 @@
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
margin-left: 10px;
|
||||
::v-deep(.el-progress__text) {
|
||||
:deep(.el-progress__text) {
|
||||
color: var(--el-text-color-primary);
|
||||
font-size: 12px !important;
|
||||
text-align: right;
|
||||
}
|
||||
::v-deep(.el-progress-bar__outer) {
|
||||
:deep(.el-progress-bar__outer) {
|
||||
background-color: rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
::v-deep(.el-progress-bar) {
|
||||
:deep(.el-progress-bar) {
|
||||
margin-right: -22px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
||||
@ -35,10 +34,12 @@ export default defineComponent({
|
||||
const storesTagsViewRoutes = useTagsViewRoutes();
|
||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
|
||||
const router = useRouter();
|
||||
const onSetAuth = () => {
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5C3JS
|
||||
// 清除缓存/token等
|
||||
Session.clear();
|
||||
router.push('/login');
|
||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||
window.location.reload();
|
||||
};
|
||||
// 设置主内容的高度
|
||||
const initTagViewHeight = computed(() => {
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
<template>
|
||||
<div id="printRref">
|
||||
<el-card shadow="hover" header="复制剪切演示">
|
||||
<el-alert
|
||||
title="感谢优秀的 `vue-clipboard3`,项目地址:https://github.com/JamieCurnow/vue-clipboard3`"
|
||||
type="success"
|
||||
:closable="false"
|
||||
class="mb15"
|
||||
></el-alert>
|
||||
<el-input placeholder="请输入内容" v-model="copyVal">
|
||||
<template #append>
|
||||
<el-button @click="copyText(copyVal)">复制链接</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-input placeholder="先点击上方 `复制链接` 按钮,然后 `Ctrl + V` 进行粘贴! " v-model="shearVal" class="mt15"> </el-input>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-card shadow="hover" header="复制剪切演示">
|
||||
<el-alert
|
||||
title="感谢优秀的 `vue-clipboard3`,项目地址:https://github.com/JamieCurnow/vue-clipboard3`"
|
||||
type="success"
|
||||
:closable="false"
|
||||
class="mb15"
|
||||
></el-alert>
|
||||
<el-input placeholder="请输入内容" v-model="copyVal">
|
||||
<template #append>
|
||||
<el-button @click="copyText(copyVal)">复制链接</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-input placeholder="先点击上方 `复制链接` 按钮,然后 `Ctrl + V` 进行粘贴! " v-model="shearVal" class="mt15"> </el-input>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :sm="6" class="mb15" v-for="(v, k) in topCardItemList" :key="k">
|
||||
<div class="countup-card-item countup-card-item-box" :style="{ background: `var(${v.color})` }">
|
||||
<div class="countup-card-item-flex">
|
||||
<div class="countup-card-item-flex" ref="topCardItemRefs">
|
||||
<div class="countup-card-item-title pb3">{{ v.title }}</div>
|
||||
<div class="countup-card-item-title-num pb6" :id="`titleNum${k + 1}`"></div>
|
||||
<div class="countup-card-item-title-num pb6"></div>
|
||||
<div class="countup-card-item-tip pb3">{{ v.tip }}</div>
|
||||
<div class="countup-card-item-tip-num" :id="`tipNum${k + 1}`"></div>
|
||||
<div class="countup-card-item-tip-num"></div>
|
||||
</div>
|
||||
<i :class="v.icon" :style="{ color: v.iconColor }"></i>
|
||||
</div>
|
||||
@ -44,6 +44,7 @@ export default defineComponent({
|
||||
name: 'funCountup',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
topCardItemRefs: null as any,
|
||||
topCardItemList: [
|
||||
{
|
||||
title: '今日访问人数',
|
||||
@ -86,14 +87,10 @@ export default defineComponent({
|
||||
// 初始化数字滚动
|
||||
const initNumCountUp = () => {
|
||||
nextTick(() => {
|
||||
new CountUp('titleNum1', Math.random() * 10000).start();
|
||||
new CountUp('titleNum2', Math.random() * 10000).start();
|
||||
new CountUp('titleNum3', Math.random() * 10000).start();
|
||||
new CountUp('titleNum4', Math.random() * 10000).start();
|
||||
new CountUp('tipNum1', Math.random() * 1000).start();
|
||||
new CountUp('tipNum2', Math.random() * 1000).start();
|
||||
new CountUp('tipNum3', Math.random() * 1000).start();
|
||||
new CountUp('tipNum4', Math.random() * 1000).start();
|
||||
state.topCardItemRefs.forEach((v: HTMLDivElement) => {
|
||||
new CountUp(v.querySelector('.countup-card-item-title-num') as HTMLDivElement, Math.random() * 10000).start();
|
||||
new CountUp(v.querySelector('.countup-card-item-tip-num') as HTMLDivElement, Math.random() * 1000).start();
|
||||
});
|
||||
});
|
||||
};
|
||||
// 重置/刷新数值
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :style="{ height: `calc(100vh - ${initTagViewHeight}` }">
|
||||
<div class="layout-view-bg-white">
|
||||
<div id="echartsMap" style="height: 100%"></div>
|
||||
<div ref="echartsMap" style="height: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -23,6 +23,7 @@ export default defineComponent({
|
||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
|
||||
const state: any = reactive({
|
||||
echartsMap: null,
|
||||
echartsMapList,
|
||||
echartsMapData,
|
||||
});
|
||||
@ -52,7 +53,7 @@ export default defineComponent({
|
||||
};
|
||||
// 初始化 echartsMap
|
||||
const initEchartsMap = () => {
|
||||
const myChart = echarts.init(<HTMLElement>document.getElementById('echartsMap'));
|
||||
const myChart = echarts.init(<HTMLElement>state.echartsMap);
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="printRef">
|
||||
<div ref="printRef">
|
||||
<el-card shadow="hover" header="打印演示">
|
||||
<el-alert
|
||||
title="感谢优秀的 `print-js`,项目地址:https://github.com/crabbly/Print.js。请在打印弹窗 `更多设置` 中开启 `背景图形。`"
|
||||
@ -22,11 +22,13 @@ import printJs from 'print-js';
|
||||
export default defineComponent({
|
||||
name: 'funPrintJs',
|
||||
setup() {
|
||||
const state = reactive({});
|
||||
const state = reactive({
|
||||
printRef: null as null | HTMLDivElement,
|
||||
});
|
||||
// 打印点击
|
||||
const onPrintJs = () => {
|
||||
printJs({
|
||||
printable: 'printRef',
|
||||
printable: state.printRef,
|
||||
type: 'html',
|
||||
css: ['//at.alicdn.com/t/font_2298093_o73r8wjdhlg.css', '//unpkg.com/element-plus/dist/index.css'],
|
||||
scanStyles: false,
|
||||
|
||||
@ -110,7 +110,7 @@ export default defineComponent({
|
||||
<style scoped lang="scss">
|
||||
.fun-tagsview {
|
||||
.fun-tagsview-from-item {
|
||||
::v-deep(.el-form-item__content) {
|
||||
:deep(.el-form-item__content) {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ export default defineComponent({
|
||||
frontEndsResetRoute();
|
||||
Cookies.set('userName', state.userAuth);
|
||||
// 模拟切换不同权限用户
|
||||
storesUserInfo.setUserInfos();
|
||||
await storesUserInfo.setUserInfos();
|
||||
await setAddRoute();
|
||||
setFilterMenuAndCacheTagsViewRoutes();
|
||||
};
|
||||
|
||||
@ -47,7 +47,7 @@ export default defineComponent({
|
||||
text-align: center;
|
||||
@extend .login-scan-animation;
|
||||
animation-delay: 0.1s;
|
||||
::v-deep(img) {
|
||||
:deep(img) {
|
||||
margin: auto;
|
||||
}
|
||||
.login-msg {
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="dialogVisible" width="769px">
|
||||
<template #title>
|
||||
<template #header>
|
||||
<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']">拖动指令效果(v-drag)</div>
|
||||
</template>
|
||||
<p>鼠标放标题头进行 Dialog 对话框拖动</p>
|
||||
|
||||
@ -328,7 +328,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep(.el-card__body) {
|
||||
:deep(.el-card__body) {
|
||||
height: 100%;
|
||||
.filtering-no-data {
|
||||
display: flex;
|
||||
|
||||
@ -13,10 +13,10 @@ export default defineComponent({
|
||||
name: 'pagesPreview',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
url: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg',
|
||||
url: 'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500',
|
||||
srcList: [
|
||||
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg',
|
||||
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
|
||||
'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500',
|
||||
'https://img2.baidu.com/it/u=2370931438,70387529&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
||||
'https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg',
|
||||
],
|
||||
});
|
||||
|
||||
@ -236,7 +236,7 @@ export default defineComponent({
|
||||
padding-right: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
&::v-deep(.el-tree-node) {
|
||||
&:deep(.el-tree-node) {
|
||||
border: 1px solid var(--next-border-color-light);
|
||||
border-bottom: none;
|
||||
color: #606266;
|
||||
|
||||
@ -240,7 +240,7 @@ export default defineComponent({
|
||||
|
||||
<style scoped lang="scss">
|
||||
.workflow-drawer-node {
|
||||
::v-deep {
|
||||
:deep {
|
||||
.el-tabs {
|
||||
box-shadow: unset;
|
||||
border: unset;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="workflow-tool-help">
|
||||
<el-dialog v-model="isShow" width="769px">
|
||||
<template #title>
|
||||
<template #header>
|
||||
<div v-drag="['.workflow-tool-help .el-dialog', '.workflow-tool-help .el-dialog__header']">使用帮助</div>
|
||||
</template>
|
||||
<div>1、拖入:鼠标移入左侧导航中,鼠标形状改变时拖动到右侧网格状的视图中。</div>
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
|
||||
<!-- 左侧导航区 -->
|
||||
<div class="workflow-content">
|
||||
<div id="workflow-left">
|
||||
<div class="workflow-left">
|
||||
<el-scrollbar>
|
||||
<div
|
||||
:id="`left${key}`"
|
||||
ref="leftNavRefs"
|
||||
v-for="(val, key) in leftNavList"
|
||||
:key="val.id"
|
||||
:style="{ height: val.isOpen ? 'auto' : '50px', overflow: 'hidden' }"
|
||||
@ -32,11 +32,12 @@
|
||||
</div>
|
||||
|
||||
<!-- 右侧绘画区 -->
|
||||
<div id="workflow-right">
|
||||
<div class="workflow-right" ref="workflowRightRef">
|
||||
<div
|
||||
v-for="(v, k) in jsplumbData.nodeList"
|
||||
:key="v.nodeId"
|
||||
:id="v.nodeId"
|
||||
:data-node-id="v.nodeId"
|
||||
:class="v.class"
|
||||
:style="{ left: v.left, top: v.top }"
|
||||
@click="onItemCloneClick(k)"
|
||||
@ -102,6 +103,8 @@ interface XyState {
|
||||
y: string | number;
|
||||
}
|
||||
interface WorkflowState {
|
||||
workflowRightRef: HTMLDivElement | null;
|
||||
leftNavRefs: any[];
|
||||
leftNavList: any[];
|
||||
dropdownNode: XyState;
|
||||
dropdownLine: XyState;
|
||||
@ -132,6 +135,8 @@ export default defineComponent({
|
||||
const { isTagsViewCurrenFull } = storeToRefs(stores);
|
||||
const { copyText } = commonFunction();
|
||||
const state = reactive<WorkflowState>({
|
||||
workflowRightRef: null as HTMLDivElement | null,
|
||||
leftNavRefs: [],
|
||||
leftNavList: [],
|
||||
dropdownNode: { x: '', y: '' },
|
||||
dropdownLine: { x: '', y: '' },
|
||||
@ -195,8 +200,8 @@ export default defineComponent({
|
||||
};
|
||||
// 左侧导航-初始化拖动
|
||||
const initSortable = () => {
|
||||
state.leftNavList.forEach((v, k) => {
|
||||
Sortable.create(document.getElementById(`left${k}`) as HTMLElement, {
|
||||
state.leftNavRefs.forEach((v) => {
|
||||
Sortable.create(v as HTMLDivElement, {
|
||||
group: {
|
||||
name: 'vue-next-admin-1',
|
||||
pull: 'clone',
|
||||
@ -209,7 +214,7 @@ export default defineComponent({
|
||||
onEnd: function (evt: any) {
|
||||
const { name, icon, id } = evt.clone.dataset;
|
||||
const { layerX, layerY, clientX, clientY } = evt.originalEvent;
|
||||
const el = document.querySelector('#workflow-right') as HTMLElement;
|
||||
const el = state.workflowRightRef!;
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
if (clientX < x || clientX > width + x || clientY < y || y > y + height) {
|
||||
ElMessage.warning('请把节点拖入到画布中');
|
||||
@ -546,11 +551,11 @@ export default defineComponent({
|
||||
.workflow-content {
|
||||
display: flex;
|
||||
height: calc(100% - 35px);
|
||||
#workflow-left {
|
||||
.workflow-left {
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--el-border-color-light, #ebeef5);
|
||||
::v-deep(.el-collapse-item__content) {
|
||||
:deep(.el-collapse-item__content) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.workflow-left-title {
|
||||
@ -607,7 +612,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
#workflow-right {
|
||||
.workflow-right {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@ -649,7 +654,7 @@ export default defineComponent({
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
::v-deep(.jtk-overlay):not(.aLabel) {
|
||||
:deep(.jtk-overlay):not(.aLabel) {
|
||||
padding: 4px 10px;
|
||||
border: 1px solid var(--el-border-color-light, #ebeef5) !important;
|
||||
color: var(--el-text-color-secondary) !important;
|
||||
@ -657,7 +662,7 @@ export default defineComponent({
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
}
|
||||
::v-deep(.jtk-overlay.workflow-right-empty-label) {
|
||||
:deep(.jtk-overlay.workflow-right-empty-label) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="personal-user">
|
||||
<div class="personal-user-left">
|
||||
<el-upload class="h100 personal-user-left-upload" action="https://jsonplaceholder.typicode.com/posts/" multiple :limit="1">
|
||||
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg" />
|
||||
<img src="https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500" />
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="personal-user-right">
|
||||
@ -233,7 +233,7 @@ export default defineComponent({
|
||||
width: 100px;
|
||||
height: 130px;
|
||||
border-radius: 3px;
|
||||
::v-deep(.el-upload) {
|
||||
:deep(.el-upload) {
|
||||
height: 100%;
|
||||
}
|
||||
.personal-user-left-upload {
|
||||
|
||||
@ -481,7 +481,7 @@ export default defineComponent({
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tools-warp-form {
|
||||
::v-deep(.el-form-item--small.el-form-item) {
|
||||
:deep(.el-form-item--small.el-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.tools-warp-form-msg {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="visualizing-demo1">
|
||||
<!-- 地图 -->
|
||||
<div id="visualizingDemo1" style="height: 100%"></div>
|
||||
<div ref="visualizingDemo1" style="height: 100%"></div>
|
||||
<div class="visualizing-container">
|
||||
<!-- 头部 -->
|
||||
<div class="visualizing-container-head">
|
||||
@ -98,6 +98,7 @@ import { echartsMapList, echartsMapData, echartsMapImgs } from './mock/demo1';
|
||||
|
||||
// 定义接口来定义对象的类型
|
||||
interface Demo1State {
|
||||
visualizingDemo1: any;
|
||||
echartsMapList: any;
|
||||
echartsMapData: any;
|
||||
echartsMapImgs: any;
|
||||
@ -110,6 +111,7 @@ export default defineComponent({
|
||||
setup() {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const state = reactive<Demo1State>({
|
||||
visualizingDemo1: null,
|
||||
echartsMapList,
|
||||
echartsMapData,
|
||||
echartsMapImgs,
|
||||
@ -142,7 +144,7 @@ export default defineComponent({
|
||||
};
|
||||
// 初始化 echartsMap(地图上的点)
|
||||
const initEchartsMap = () => {
|
||||
const myChart = echarts.init(<HTMLElement>document.getElementById('visualizingDemo1'));
|
||||
const myChart = echarts.init(<HTMLElement>state.visualizingDemo1);
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
@ -968,10 +970,10 @@ $titleWidth: 240px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
::v-deep(.BMap_cpyCtrl) {
|
||||
:deep(.BMap_cpyCtrl) {
|
||||
display: none;
|
||||
}
|
||||
::v-deep(.anchorBL) {
|
||||
:deep(.anchorBL) {
|
||||
display: none;
|
||||
}
|
||||
.visualizing-container {
|
||||
|
||||
@ -127,7 +127,7 @@
|
||||
<div class="big-data-down-center">
|
||||
<div class="big-data-down-center-one">
|
||||
<div class="big-data-down-center-one-content" ref="rightChartData5">
|
||||
<div id="3DEarth"></div>
|
||||
<div ref="the3DEarth"></div>
|
||||
<div :class="v.topLevelClass" v-for="(v, k) in earth3DBtnList" :key="k">
|
||||
<div class="circle" v-for="i in 4" :key="i"></div>
|
||||
<div class="text-box">
|
||||
@ -256,6 +256,7 @@ export default defineComponent({
|
||||
earth3DBtnList,
|
||||
chartData4List,
|
||||
myCharts: [],
|
||||
the3DEarth: null as HTMLDivElement | null,
|
||||
});
|
||||
// 初始化时间
|
||||
const initTime = () => {
|
||||
@ -685,7 +686,7 @@ export default defineComponent({
|
||||
};
|
||||
// 3DEarth 地图
|
||||
const init3DEarth = (globeRadius) => {
|
||||
let el = document.getElementById('3DEarth');
|
||||
let el = state.the3DEarth!;
|
||||
el.style.height = `${proxy.$refs.rightChartData5.offsetHeight}px`;
|
||||
const myChart = echarts.init(el);
|
||||
const option = {
|
||||
@ -852,7 +853,7 @@ export default defineComponent({
|
||||
.ml15:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
::v-deep(.el-dropdown) {
|
||||
:deep(.el-dropdown) {
|
||||
font-size: 13px !important;
|
||||
color: #43bdf0;
|
||||
cursor: pointer;
|
||||
|
||||
@ -52,22 +52,7 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [
|
||||
{
|
||||
postcssPlugin: 'internal:charset-removal',
|
||||
AtRule: {
|
||||
charset: (atRule) => {
|
||||
if (atRule.name === 'charset') {
|
||||
atRule.remove();
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
css: { preprocessorOptions: { css: { charset: false } } },
|
||||
define: {
|
||||
__VUE_I18N_LEGACY_API__: JSON.stringify(false),
|
||||
__VUE_I18N_FULL_INSTALL__: JSON.stringify(false),
|
||||
|
||||
Reference in New Issue
Block a user