diff --git a/src/App.vue b/src/App.vue index 295489b..fc116ea 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,20 @@ + + diff --git a/src/layout/Header/components/expand.vue b/src/layout/Header/components/expand.vue deleted file mode 100644 index e69de29..0000000 diff --git a/src/layout/Header/components/globalComSize.vue b/src/layout/Header/components/globalComSize.vue new file mode 100644 index 0000000..65a1ac0 --- /dev/null +++ b/src/layout/Header/components/globalComSize.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/src/layout/Header/index.vue b/src/layout/Header/index.vue index d4bd324..c453481 100644 --- a/src/layout/Header/index.vue +++ b/src/layout/Header/index.vue @@ -18,12 +18,16 @@
+ + + + {{ @@ -51,7 +55,9 @@ import { UserFilled } from '@element-plus/icons-vue' import Personal from './components/Personal.vue' import TagViews from '../TagsView/index.vue' + import GlobalComSize from './components/globalComSize.vue' import UHamburger from '@/components/u-Hamburger/index.vue' + import USetting from './components/Setting.vue' import UScreenFull from '@/components/u-screenfull/index.vue' import UInfo from '@/components/u-info/index.vue' import UHeaderSearch from '@/components/u-headerSearch/index.vue' diff --git a/src/layout/TagsView/index.vue b/src/layout/TagsView/index.vue index 10df6f0..5f466e9 100644 --- a/src/layout/TagsView/index.vue +++ b/src/layout/TagsView/index.vue @@ -23,12 +23,19 @@
- -
-
-
-
+ + + 更多 + + + @@ -135,15 +142,35 @@ } } - const closeSelectedTag = (event, view) => { + const closeSelectedTag = async (event, view) => { if (tags.value.get(view.path)) { tags.value.delete(view.path) } - store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { - if (isActive(view)) { - toLastView(visitedViews, view) + let { visitedViews } = await store.dispatch('tagsView/delView', view) + if (isActive(view)) { + toLastView(visitedViews, view) + } + } + + // 关闭当前 + const closeCurrentTab = (event)=>{ + closeSelectedTag(event,route) + } + + // 关闭其他 + const closeOtherTab= async ()=>{ + const { name } = route + for(let item of visitedViews.value){ + if(item.name!==name){ + await closeSelectedTag(null,item) } - }) + } + } + + // 关闭所有 去首页 + const closeAllTab = ()=>{ + store.dispatch('tagsView/delAllViews') + router.push('/') } const routerGo = (tag) => { @@ -259,14 +286,13 @@ display: block; } &.active { - background-color: #42b983; + background-color: $primaryColor; color: #fff; - border-color: #42b983; + border-color: $primaryColor; } } .item-tag-wrap:hover { - border-color: #42b983; - //color: #42b983; + border-color: $primaryColor; } .tags-scroll-inner { display: flex; diff --git a/src/main.ts b/src/main.ts index 4a74e80..28bfd86 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,12 +13,13 @@ import SvgIcon from '@/components/SvgIcon/index.vue'// svg component import ElementPlus from 'element-plus' import UContainerLayout from '@/components/u-container-layout/index.vue' import 'element-plus/dist/index.css' -import zhCn from 'element-plus/es/locale/lang/zh-cn' + // 引入暗黑模式 element-plus 2.2 内置暗黑模式 import 'element-plus/theme-chalk/dark/css-vars.css' // 自定义暗黑模式 import "@/styles/element-dark.scss"; + const app = createApp(App) app.component('svg-icon',SvgIcon) app.component('u-container-layout',UContainerLayout) @@ -36,7 +37,4 @@ Object.keys(ElIconsModules).forEach((key) => {//循环遍历组件名称 app.use(store) app.use(router) - -app.use(ElementPlus,{ - locale: zhCn, -}).mount('#app') +app.use(ElementPlus).mount('#app') diff --git a/src/router/index.ts b/src/router/index.ts index 2f51511..ca76621 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -103,10 +103,11 @@ const zipRoutes = { // // 异步组件 export const asyncRoutes = [ - tableRouter, chartsRouter, + tableRouter, + chatRouter, - componentsRouter, + // componentsRouter, othersRouter, nestedRouter, excelRouter, diff --git a/src/store/modules/setting.ts b/src/store/modules/setting.ts index a99e9d9..ad7027b 100644 --- a/src/store/modules/setting.ts +++ b/src/store/modules/setting.ts @@ -1,7 +1,8 @@ import {Module} from "vuex"; - +import {PRIMARY_COLOR} from "../../config"; const state = { themeConfig:{ + showSetting:false, // 菜单展示模式 默认 vertical horizontal / vertical mode: 'vertical', // tagsView 是否展示 默认展示 @@ -11,7 +12,11 @@ const state = { // 深色模式 切换暗黑模式 isDark: false, // 显示侧边栏Logo - showLogo:true + showLogo:true, + // 主题颜色 + primary:PRIMARY_COLOR, + // element组件大小 + globalComSize:'default' }, } diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts index 6ad4802..fb91192 100644 --- a/src/store/modules/tagsView.ts +++ b/src/store/modules/tagsView.ts @@ -33,19 +33,25 @@ const mutations = { } }, DEL_VISITED_VIEW: (state, view) => { - for (const [i, v] of state.visitedViews.entries()) { - if (v.path === view.path) { - state.visitedViews.splice(i, 1) - break - } - } - for (const i of state.cachedViews) { - if (i === view.name) { - const index = state.cachedViews.indexOf(i) - state.cachedViews.splice(index, 1) - break - } - } + state.visitedViews = state.visitedViews.filter(v=>{ + return v.path !== view.path + }) + state.cachedViews = state.cachedViews.filter(v=>{ + return v.path !== view.path + }) + // for (const [i, v] of state.visitedViews.entries()) { + // if (v.path === view.path) { + // state.visitedViews.splice(i, 1) + // break + // } + // } + // for (const i of state.cachedViews) { + // if (i === view.name) { + // const index = state.cachedViews.indexOf(i) + // state.cachedViews.splice(index, 1) + // break + // } + // } }, DEL_CACHED_VIEW: (state, view) => { diff --git a/src/styles/element-dark.scss b/src/styles/element-dark.scss index e0b702b..7ea19cc 100644 --- a/src/styles/element-dark.scss +++ b/src/styles/element-dark.scss @@ -136,5 +136,12 @@ html.dark { color: var(--el-text-color-primary) !important; } + // icon + .m-info .bell, + .m-setting .bell, + .m-headerSearch .bell{ + color: white!important; + } + } diff --git a/src/styles/variables.scss b/src/styles/variables.scss index 555f030..92abe7b 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -8,10 +8,13 @@ $tiffany: #4ab7bd; $yellow: #fec171; $panGreen: #30b08f; +/* 全局 css 变量 */ +$primaryColor: var(--el-color-primary); + // sidebar $menuText: #bfcbd9; $menuActiveText: #409eff; -$subMenuActiveText: #f4f4f5; // https://github.com/ElemeFE/element/issues/12951 +$subMenuActiveText: #f4f4f5; $menuBg: #304156; $menuHover: #263445; @@ -21,8 +24,6 @@ $subMenuHover: #001528; $sideBarWidth: 210px; -// the :export directive is the magic sauce for webpack -// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass :export { menuText: $menuText; menuActiveText: $menuActiveText; @@ -32,4 +33,5 @@ $sideBarWidth: 210px; subMenuBg: $subMenuBg; subMenuHover: $subMenuHover; sideBarWidth: $sideBarWidth; + primaryColor: $primaryColor; } diff --git a/src/utils/index.js b/src/utils/index.ts similarity index 84% rename from src/utils/index.js rename to src/utils/index.ts index ce6e739..2f5f33b 100644 --- a/src/utils/index.js +++ b/src/utils/index.ts @@ -423,3 +423,62 @@ export const deepObjClone = function (obj) { } return clone(obj) } +import { ElMessage } from "element-plus"; + +/** + * hex颜色转rgb颜色 + * @param str 颜色值字符串 + * @returns 返回处理后的颜色值 + */ +export function hexToRgb(str: any) { + let hexs: any = ""; + let reg = /^\#?[0-9A-Fa-f]{6}$/; + if (!reg.test(str)) return ElMessage.warning("输入错误的hex"); + str = str.replace("#", ""); + hexs = str.match(/../g); + for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16); + return hexs; +} + +/** + * rgb颜色转Hex颜色 + * @param r 代表红色 + * @param g 代表绿色 + * @param b 代表蓝色 + * @returns 返回处理后的颜色值 + */ +export function rgbToHex(r: any, g: any, b: any) { + let reg = /^\d{1,3}$/; + if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ElMessage.warning("输入错误的rgb颜色值"); + let hexs = [r.toString(16), g.toString(16), b.toString(16)]; + for (let i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`; + return `#${hexs.join("")}`; +} + +/** + * 加深颜色值 + * @param color 颜色值字符串 + * @param level 加深的程度,限0-1之间 + * @returns 返回处理后的颜色值 + */ +export function getDarkColor(color: string, level: number) { + let reg = /^\#?[0-9A-Fa-f]{6}$/; + if (!reg.test(color)) return ElMessage.warning("输入错误的hex颜色值"); + let rgb = hexToRgb(color); + for (let i = 0; i < 3; i++) rgb[i] = Math.floor(rgb[i] * (1 - level)); + return rgbToHex(rgb[0], rgb[1], rgb[2]); +} + +/** + * 变浅颜色值 + * @param color 颜色值字符串 + * @param level 加深的程度,限0-1之间 + * @returns 返回处理后的颜色值 + */ +export function getLightColor(color: string, level: number) { + let reg = /^\#?[0-9A-Fa-f]{6}$/; + if (!reg.test(color)) return ElMessage.warning("输入错误的hex颜色值"); + let rgb = hexToRgb(color); + for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]); + return rgbToHex(rgb[0], rgb[1], rgb[2]); +} diff --git a/src/utils/validate.js b/src/utils/validate.ts similarity index 100% rename from src/utils/validate.js rename to src/utils/validate.ts diff --git a/vite.config.ts b/vite.config.ts index 45d6b28..cde1c81 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from 'vite' +import { defineConfig,ConfigEnv, UserConfig } from 'vite' import vue from '@vitejs/plugin-vue' // import AutoImport from 'unplugin-auto-import/vite' // import Components from 'unplugin-vue-components/vite' @@ -7,78 +7,85 @@ import path from 'path' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' // 增加 vue文件 script name值 import vueSetupExtend from 'vite-plugin-vue-setup-extend' -// import viteCompression from 'vite-plugin-compression' +import viteCompression from 'vite-plugin-compression' function resolve (dir) { return path.join(__dirname, '.', dir) } // https://vitejs.dev/config/ -export default defineConfig({ - plugins: [vue(), - vueSetupExtend(), - // AutoImport({ - // resolvers: [ElementPlusResolver()], - // }), - // Components({ - // resolvers: [ElementPlusResolver()], - // }), - // * 使用 svg 图标 - createSvgIconsPlugin({ - // 指定需要缓存的图标文件夹 - iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')], - // 指定symbolId格式 - symbolId: 'icon-[dir]-[name]', - }), - // gzip压缩 生产环境生成 .gz 文件 - // viteCompression({ - // verbose: true, - // disable: false, - // threshold: 10240, - // algorithm: 'gzip', - // ext: '.gz', - // }), - ], - css: { - preprocessorOptions: { - scss: { - additionalData: `@use "./src/styles/index.scss" as *;` +export default defineConfig(({ mode }: ConfigEnv): UserConfig => { + console.log('mode================',mode) + return { + plugins: [vue(), + vueSetupExtend(), + // AutoImport({ + // resolvers: [ElementPlusResolver()], + // }), + // Components({ + // resolvers: [ElementPlusResolver()], + // }), + // * 使用 svg 图标 + createSvgIconsPlugin({ + // 指定需要缓存的图标文件夹 + iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')], + // 指定symbolId格式 + symbolId: 'icon-[dir]-[name]', + }), + // gzip压缩 生产环境生成 .gz 文件 + mode==='production'&&viteCompression({ + verbose: true, + disable: false, + threshold: 10240, + algorithm: 'gzip', + ext: '.gz', + }), + ], + css: { + preprocessorOptions: { + scss: { + additionalData: `@use "./src/styles/index.scss" as *;` + } } - } - }, - // 配置别名 - resolve: { - alias: { - '@':resolve('src'), - 'static':resolve('public/static'), }, - // 忽略后缀名的配置选项, 添加 .vue 选项时要记得原本默认忽略的选项也要手动写入 - extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], - }, - //启动服务配置 - server: { - // 服务器主机名,如果允许外部访问,可设置为 "0.0.0.0" 也可设置成你的ip地址 - host: '0.0.0.0', - port: 8100, - open: true, - https: false, - cors: true, - // 代理跨域(模拟示例) - proxy: { - // "/api": { - // target: "", // easymock - // changeOrigin: true, - // rewrite: path => path.replace(/^\/api/, "") - // } - } - }, - // 生产环境打包配置 - //去除 console debugger - // build: { - // terserOptions: { - // compress: { - // drop_console: true, - // drop_debugger: true, - // }, - // }, - // }, + // 配置别名 + resolve: { + alias: { + '@':resolve('src'), + 'static':resolve('public/static'), + }, + // 忽略后缀名的配置选项, 添加 .vue 选项时要记得原本默认忽略的选项也要手动写入 + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], + }, + //启动服务配置 + server: { + // 服务器主机名,如果允许外部访问,可设置为 "0.0.0.0" 也可设置成你的ip地址 + host: '0.0.0.0', + port: 8100, + open: true, + https: false, + cors: true, + // 代理跨域(模拟示例) + proxy: { + // "/api": { + // target: "", // easymock + // changeOrigin: true, + // rewrite: path => path.replace(/^\/api/, "") + // } + } + }, + esbuild: { + pure:mode==='production' ? ["console.log", "debugger"] : [] + }, + // 生产环境打包配置 + //去除 console debugger + // build: { + // terserOptions: { + // compress: { + // drop_console: true, + // drop_debugger: true, + // }, + // }, + // }, + } + })