diff --git a/.eslintrc.js b/.eslintrc.js index 6824bb0..7b28cb7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -44,6 +44,7 @@ module.exports = { 'vue/comment-directive': 'off', 'vue/no-parsing-error': 'off', 'vue/no-deprecated-v-on-native-modifier': 'off', + 'vue/multi-word-component-names': 'off', 'no-useless-escape': 'off', 'no-sparse-arrays': 'off', 'no-prototype-builtins': 'off', diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d4a70e..661b2b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ 🎉🎉🔥 `vue-next-admin-template` 基于 (vue-next-admin-v1.1.2 版本) vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支) +## 0.2.0 + +`2021.12.04` + +- 🎉 同步 master 分支 v1.2.0 版本内容,具体查看 master CHANGELOG.md + ## 0.1.0 `2021.10.17` diff --git a/README.md b/README.md index 5c6c96c..2490c31 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@

 

-#### 🌈 介绍(基础版 ts(不带国际化)) +#### 🌈 介绍 基础版 ts(不带国际化) 基于 vue3.x + CompositionAPI + typescript + vite + element plus + vue-router-next + next.vuex,适配手机、平板、pc 的后台开源免费模板,希望减少工作量,帮助大家实现快速开发。 diff --git a/package.json b/package.json index ab1a3a9..a054c0b 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,22 @@ { "name": "vue-next-admin-template", - "version": "0.1.0", + "version": "0.2.0", "description": "vue3 vite next admin template", "author": "lyt_20201208", "license": "MIT", "scripts": { - "dev": "vite", + "dev": "vite --force", "build": "vite build", "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/" }, "dependencies": { - "axios": "^0.23.0", - "echarts": "^5.2.1", - "element-plus": "^1.1.0-beta.20", + "axios": "^0.24.0", + "echarts": "^5.2.2", + "element-plus": "^1.2.0-beta.5", "qrcodejs2-fixes": "^0.0.2", "mitt": "^3.0.0", "nprogress": "^0.2.0", - "screenfull": "^5.1.0", + "screenfull": "^6.0.0", "sortablejs": "^1.14.0", "vue": "^3.2.20", "vue-clipboard3": "^1.0.1", @@ -26,21 +26,21 @@ "devDependencies": { "@types/axios": "^0.14.0", "@types/clipboard": "^2.0.1", - "@types/node": "^16.11.0", + "@types/node": "^16.11.11", "@types/nprogress": "^0.2.0", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", - "@vitejs/plugin-vue": "^1.9.3", - "@vue/compiler-sfc": "^3.2.20", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "@vitejs/plugin-vue": "^1.10.1", + "@vue/compiler-sfc": "^3.2.23", "dotenv": "^10.0.0", - "eslint": "^8.0.1", - "eslint-plugin-vue": "^7.19.1", - "prettier": "^2.4.1", - "sass": "^1.43.2", - "sass-loader": "^12.2.0", - "typescript": "^4.4.4", - "vite": "^2.6.7", - "vue-eslint-parser": "^7.11.0" + "eslint": "^8.4.0", + "eslint-plugin-vue": "^8.1.1", + "prettier": "^2.5.0", + "sass": "^1.44.0", + "sass-loader": "^12.3.0", + "typescript": "^4.5.2", + "vite": "^2.6.14", + "vue-eslint-parser": "^8.0.1" }, "browserslist": [ "> 1%", diff --git a/src/App.vue b/src/App.vue index 11202ad..f840c80 100644 --- a/src/App.vue +++ b/src/App.vue @@ -9,7 +9,7 @@ import { computed, ref, getCurrentInstance, onBeforeMount, onMounted, nextTick, defineComponent, watch } from 'vue'; import { useRoute } from 'vue-router'; import { useStore } from '/@/store/index'; -import { useTitle } from '/@/utils/setWebTitle'; +import other from '/@/utils/other'; import { Local, Session } from '/@/utils/storage'; import setIntroduction from '/@/utils/setIconfont'; import LockScreen from '/@/layout/lockScreen/index.vue'; @@ -23,7 +23,6 @@ export default defineComponent({ const setingsRef = ref(); const route = useRoute(); const store = useStore(); - const title = useTitle(); // 获取布局配置信息 const getThemeConfig = computed(() => { return store.state.themeConfig.themeConfig; @@ -61,7 +60,7 @@ export default defineComponent({ watch( () => route.path, () => { - title(); + other.useTitle(); } ); return { diff --git a/src/components/iconSelector/index.vue b/src/components/iconSelector/index.vue index 68feae0..90fab43 100644 --- a/src/components/iconSelector/index.vue +++ b/src/components/iconSelector/index.vue @@ -14,29 +14,33 @@ @blur="onIconBlur" >
-
{{ title }}
+
+
{{ title }}
+
+ ali + ele + awe +
+
- +
- +
@@ -61,7 +65,7 @@ export default { // 输入框前置内容 prepend: { type: String, - default: () => 'el-icon-thumb', + default: () => 'elementPointer', }, // 输入框占位文本 placeholder: { @@ -104,6 +108,7 @@ export default { }, setup(props, { emit }) { const inputWidthRef = ref(); + const selectorScrollbarRef = ref(); const state: any = reactive({ fontIconPrefix: '', fontIconVisible: false, @@ -112,6 +117,8 @@ export default { fontIconTabsIndex: 0, fontIconSheetsList: [], fontIconPlaceholder: '', + fontIconType: 'ali', + fontIconShow: true, }); // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值 const onIconFocus = () => { @@ -153,21 +160,19 @@ export default { }); }; // 初始化数据 - const initFontIconData = async () => { - if (props.type === 'ali') { + const initFontIconData = async (type: string) => { + state.fontIconSheetsList = []; + if (type === 'ali') { await initIconfont.ali().then((res: any) => { - state.fontIconTabsIndex = 0; // 阿里字体图标使用 `iconfont xxx` state.fontIconSheetsList = res.map((i) => `iconfont ${i}`); }); - } else if (props.type === 'ele') { + } else if (type === 'ele') { await initIconfont.ele().then((res: any) => { - state.fontIconTabsIndex = 1; state.fontIconSheetsList = res; }); - } else if (props.type === 'awe') { + } else if (type === 'awe') { await initIconfont.awe().then((res: any) => { - state.fontIconTabsIndex = 2; // fontawesome字体图标使用 `fa xxx` state.fontIconSheetsList = res.map((i) => `fa ${i}`); }); @@ -177,14 +182,19 @@ export default { state.fontIconPlaceholder = props.placeholder; // 初始化双向绑定回显 initModeValueEcho(); + // 切换时,滚动条置顶。感兴趣可以使用 keep-alive 进行缓存 + selectorScrollbarRef.value.wrap$.scrollTop = 0; + }; + // 图标点击切换 + const onIconChange = (type: string) => { + state.fontIconType = type; + initFontIconData(type); }; // 获取当前点击的 icon 图标 const onColClick = (v: any) => { state.fontIconPlaceholder = v; state.fontIconVisible = false; - if (state.fontIconTabsIndex === 0) state.fontIconPrefix = `${v}`; - else if (state.fontIconTabsIndex === 1) state.fontIconPrefix = `${v}`; - else if (state.fontIconTabsIndex === 2) state.fontIconPrefix = `${v}`; + state.fontIconPrefix = v; emit('get', state.fontIconPrefix); emit('update:modelValue', state.fontIconPrefix); }; @@ -196,7 +206,15 @@ export default { }; // 页面加载时 onMounted(() => { - initFontIconData(); + // 判断默认进来是什么类型图标,进行 tab 回显 + if (props.type === 'all') { + if (props.modelValue?.indexOf('iconfont') > -1) onIconChange('ali'); + else if (props.modelValue?.indexOf('element') > -1) onIconChange('ele'); + else if (props.modelValue?.indexOf('fa') > -1) onIconChange('awe'); + else onIconChange('ali'); + } else { + onIconChange(props.type); + } initResize(); getInputWidth(); }); @@ -209,8 +227,10 @@ export default { ); return { inputWidthRef, + selectorScrollbarRef, fontIconSheetsFilterList, onColClick, + onIconChange, onClearFontIcon, onIconFocus, onIconBlur, diff --git a/src/components/svgIcon/index.vue b/src/components/svgIcon/index.vue new file mode 100644 index 0000000..b3b6304 --- /dev/null +++ b/src/components/svgIcon/index.vue @@ -0,0 +1,28 @@ + diff --git a/src/layout/component/columnsAside.vue b/src/layout/component/columnsAside.vue index 3542646..bdd02d0 100644 --- a/src/layout/component/columnsAside.vue +++ b/src/layout/component/columnsAside.vue @@ -16,7 +16,7 @@ :title="v.meta.title" >
diff --git a/src/layout/main/defaults.vue b/src/layout/main/defaults.vue index f609ccc..3dade0a 100644 --- a/src/layout/main/defaults.vue +++ b/src/layout/main/defaults.vue @@ -33,7 +33,7 @@ export default { watch( () => route.path, () => { - proxy.$refs.layoutDefaultsScrollbarRef.wrap.scrollTop = 0; + proxy.$refs.layoutDefaultsScrollbarRef.wrap$.scrollTop = 0; } ); return { diff --git a/src/layout/navBars/breadcrumb/breadcrumb.vue b/src/layout/navBars/breadcrumb/breadcrumb.vue index 7ab7aee..016e8e3 100644 --- a/src/layout/navBars/breadcrumb/breadcrumb.vue +++ b/src/layout/navBars/breadcrumb/breadcrumb.vue @@ -9,10 +9,10 @@ - {{ v.meta.title }} + {{ v.meta.title }} - {{ v.meta.title }} + {{ v.meta.title }} diff --git a/src/layout/navBars/breadcrumb/closeFull.vue b/src/layout/navBars/breadcrumb/closeFull.vue index 8970dd6..6599e4f 100644 --- a/src/layout/navBars/breadcrumb/closeFull.vue +++ b/src/layout/navBars/breadcrumb/closeFull.vue @@ -1,7 +1,7 @@ diff --git a/src/layout/navBars/breadcrumb/search.vue b/src/layout/navBars/breadcrumb/search.vue index 879126f..bfd92b4 100644 --- a/src/layout/navBars/breadcrumb/search.vue +++ b/src/layout/navBars/breadcrumb/search.vue @@ -5,11 +5,15 @@ v-model="menuQuery" :fetch-suggestions="menuSearch" placeholder="菜单搜索:支持中文、路由路径" - prefix-icon="el-icon-search" ref="layoutMenuAutocompleteRef" @select="onHandleSelect" @blur="onSearchBlur" > + diff --git a/src/layout/navBars/breadcrumb/setings.vue b/src/layout/navBars/breadcrumb/setings.vue index 301c38e..c35557c 100644 --- a/src/layout/navBars/breadcrumb/setings.vue +++ b/src/layout/navBars/breadcrumb/setings.vue @@ -38,7 +38,7 @@ 菜单 / 顶栏
-
{{ 顶栏背景 }}
+
顶栏背景
@@ -355,17 +355,16 @@
- + + + + 一键复制配置 - + + + + 一键恢复默认
diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue index f4a53d9..4c0d4b0 100644 --- a/src/layout/navBars/breadcrumb/user.vue +++ b/src/layout/navBars/breadcrumb/user.vue @@ -14,7 +14,9 @@
- + + +
@@ -23,7 +25,9 @@ @@ -38,7 +42,9 @@ {{ getUserInfos.userName === '' ? 'test' : getUserInfos.userName }} - + + + @@ -42,10 +42,10 @@ export default defineComponent({ const state = reactive({ isShow: false, dropdownList: [ - { contextMenuClickId: 0, txt: '刷新', affix: false, icon: 'el-icon-refresh-right' }, - { contextMenuClickId: 1, txt: '关闭', affix: false, icon: 'el-icon-close' }, - { contextMenuClickId: 2, txt: '关闭其它', affix: false, icon: 'el-icon-circle-close' }, - { contextMenuClickId: 3, txt: '全部关闭', affix: false, icon: 'el-icon-folder-delete' }, + { contextMenuClickId: 0, txt: '刷新', affix: false, icon: 'elementRefreshRight' }, + { contextMenuClickId: 1, txt: '关闭', affix: false, icon: 'elementClose' }, + { contextMenuClickId: 2, txt: '关闭其它', affix: false, icon: 'elementCircleClose' }, + { contextMenuClickId: 3, txt: '全部关闭', affix: false, icon: 'elementFolderDelete' }, { contextMenuClickId: 4, txt: '当前页全屏', affix: false, icon: 'iconfont icon-fullscreen' }, ], item: {}, diff --git a/src/layout/navBars/tagsView/tagsView.vue b/src/layout/navBars/tagsView/tagsView.vue index 61e8e36..e6c9a6b 100644 --- a/src/layout/navBars/tagsView/tagsView.vue +++ b/src/layout/navBars/tagsView/tagsView.vue @@ -6,7 +6,7 @@ v-for="(v, k) in tagsViewList" :key="k" class="layout-navbars-tagsview-ul-li" - :data-name="v.name" + :data-name="v.url" :class="{ 'is-active': isActive(v) }" @contextmenu.prevent="onContextmenu(v, $event)" @click="onTagsClick(v, k)" @@ -20,18 +20,20 @@ {{ v.meta.title }} - + /> @@ -324,7 +326,7 @@ export default { }; // 鼠标滚轮滚动 const onHandleScroll = (e: any) => { - proxy.$refs.scrollbarRef.$refs.wrap.scrollLeft += e.wheelDelta / 4; + proxy.$refs.scrollbarRef.$refs.wrap$.scrollLeft += e.wheelDelta / 4; }; // tagsView 横向滚动 const tagsViewmoveToCurrentTag = () => { @@ -341,7 +343,7 @@ export default { // 最后 li let liLast: any = tagsRefs.value[tagsRefs.value.length - 1]; // 当前滚动条的值 - let scrollRefs = proxy.$refs.scrollbarRef.$refs.wrap; + let scrollRefs = proxy.$refs.scrollbarRef.$refs.wrap$; // 当前滚动条滚动宽度 let scrollS = scrollRefs.scrollWidth; // 当前滚动条偏移宽度 @@ -401,7 +403,7 @@ export default { state.sortable && state.sortable.destroy(); state.sortable = Sortable.create(el, { animation: 300, - dataIdAttr: 'data-name', + dataIdAttr: 'data-url', disabled: getThemeConfig.value.isSortableTagsView ? false : true, onEnd: () => { const sortEndList: any = []; diff --git a/src/layout/navMenu/horizontal.vue b/src/layout/navMenu/horizontal.vue index 9d17c1a..e323df1 100644 --- a/src/layout/navMenu/horizontal.vue +++ b/src/layout/navMenu/horizontal.vue @@ -5,19 +5,19 @@