diff --git a/src/components/ThemePicker/index.vue b/src/components/ThemePicker/index.vue index 332b07e7..52419929 100644 --- a/src/components/ThemePicker/index.vue +++ b/src/components/ThemePicker/index.vue @@ -67,11 +67,18 @@ export default { methods: { updateStyle(style, oldCluster, newCluster) { - let newStyle = style + const colorOverrides = [] // only capture color overides oldCluster.forEach((color, index) => { - newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) + const value = newCluster[index] + const color_plain = color.replace(/([()])/g, '\\$1') + const repl = new RegExp(`(^|})([^{]+{[^{}]+)${color_plain}\\b([^}]*)(?=})`, 'gi') + const nestRepl = new RegExp(color_plain, 'ig') // for greed matching before the 'color' + let v + while ((v = repl.exec(style))) { + colorOverrides.push(v[2].replace(nestRepl, value) + value + v[3] + '}') // '}' not captured in the regexp repl to reserve it as locator-boundary + } }) - return newStyle + return colorOverrides.join('') }, getCSSString(url, callback, variable) { diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js index cbf9eeb7..378cbcd3 100644 --- a/src/store/modules/tagsView.js +++ b/src/store/modules/tagsView.js @@ -38,12 +38,9 @@ const tagsView = { }, DEL_OTHERS_VISITED_VIEWS: (state, view) => { - for (const [i, v] of state.visitedViews.entries()) { - if (v.path === view.path) { - state.visitedViews = state.visitedViews.slice(i, i + 1) - break - } - } + state.visitedViews = state.visitedViews.filter(v => { + return v.meta.affix || v.path === view.path + }) }, DEL_OTHERS_CACHED_VIEWS: (state, view) => { for (const i of state.cachedViews) { @@ -56,7 +53,9 @@ const tagsView = { }, DEL_ALL_VISITED_VIEWS: state => { - state.visitedViews = [] + // keep affix tags + const affixTags = state.visitedViews.filter(tag => tag.meta.affix) + state.visitedViews = affixTags }, DEL_ALL_CACHED_VIEWS: state => { state.cachedViews = [] diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index ce619fd3..96e89be7 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -170,8 +170,27 @@ .nest-menu .el-submenu>.el-submenu__title, .el-menu-item { &:hover { - // You can use $subMenuHover + // you can use $subMenuHover background-color: $menuHover !important; } } + + // the scroll bar appears when the subMenu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } } diff --git a/src/utils/createUniqueString.js b/src/utils/createUniqueString.js deleted file mode 100644 index 611725c4..00000000 --- a/src/utils/createUniqueString.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Created by jiachenpan on 17/3/8. - */ -export default function createUniqueString() { - const timestamp = +new Date() + '' - const randomNum = parseInt((1 + Math.random()) * 65536) + '' - return (+(randomNum + timestamp)).toString(32) -} diff --git a/src/utils/index.js b/src/utils/index.js index 821392e9..1370a423 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -239,7 +239,7 @@ export function debounce(func, wait, immediate) { // 据上一次触发时间间隔 const last = +new Date() - timestamp - // 上次被包装函数被调用时间间隔last小于设定时间间隔wait + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { @@ -291,6 +291,8 @@ export function uniqueArr(arr) { return Array.from(new Set(arr)) } -export function isExternal(path) { - return /^(https?:|mailto:|tel:)/.test(path) +export function createUniqueString() { + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) } diff --git a/src/utils/validate.js b/src/utils/validate.js index ada0e7e2..5e4056f5 100644 --- a/src/utils/validate.js +++ b/src/utils/validate.js @@ -2,31 +2,35 @@ * Created by jiachenpan on 16/11/18. */ -export function isvalidUsername(str) { +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +export function validUsername(str) { const valid_map = ['admin', 'editor'] return valid_map.indexOf(str.trim()) >= 0 } /* 合法uri*/ -export function validateURL(textval) { - const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ - return urlregex.test(textval) +export function validURL(url) { + const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return reg.test(url) } /* 小写字母*/ -export function validateLowerCase(str) { +export function validLowerCase(str) { const reg = /^[a-z]+$/ return reg.test(str) } /* 大写字母*/ -export function validateUpperCase(str) { +export function validUpperCase(str) { const reg = /^[A-Z]+$/ return reg.test(str) } /* 大小写字母*/ -export function validateAlphabets(str) { +export function validAlphabets(str) { const reg = /^[A-Za-z]+$/ return reg.test(str) } @@ -36,7 +40,7 @@ export function validateAlphabets(str) { * @param email * @returns {boolean} */ -export function validateEmail(email) { +export function validEmail(email) { const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ return re.test(email) } diff --git a/src/views/example/components/ArticleDetail.vue b/src/views/example/components/ArticleDetail.vue index 129016d7..1026559f 100644 --- a/src/views/example/components/ArticleDetail.vue +++ b/src/views/example/components/ArticleDetail.vue @@ -78,7 +78,7 @@ import Tinymce from '@/components/Tinymce' import Upload from '@/components/Upload/singleImage3' import MDinput from '@/components/MDinput' import Sticky from '@/components/Sticky' // 粘性header组件 -import { validateURL } from '@/utils/validate' +import { validURL } from '@/utils/validate' import { fetchArticle } from '@/api/article' import { userSearch } from '@/api/remoteSearch' import Warning from './Warning' @@ -121,7 +121,7 @@ export default { } const validateSourceUri = (rule, value, callback) => { if (value) { - if (validateURL(value)) { + if (validURL(value)) { callback() } else { this.$message({ diff --git a/src/views/layout/components/Sidebar/FixiOSBug.js b/src/views/layout/components/Sidebar/FixiOSBug.js index 5e0a9262..bc14856f 100644 --- a/src/views/layout/components/Sidebar/FixiOSBug.js +++ b/src/views/layout/components/Sidebar/FixiOSBug.js @@ -5,16 +5,16 @@ export default { } }, mounted() { - // In order to fix the click on menu on the ios device will trigger the mouseeleave bug + // In order to fix the click on menu on the ios device will trigger the mouseleave bug // https://github.com/PanJiaChen/vue-element-admin/issues/1135 this.fixBugIniOS() }, methods: { fixBugIniOS() { - const $submenu = this.$refs.submenu - if ($submenu) { - const handleMouseleave = $submenu.handleMouseleave - $submenu.handleMouseleave = (e) => { + const $subMenu = this.$refs.subMenu + if ($subMenu) { + const handleMouseleave = $subMenu.handleMouseleave + $subMenu.handleMouseleave = (e) => { if (this.device === 'mobile') { return } diff --git a/src/views/layout/components/Sidebar/Link.vue b/src/views/layout/components/Sidebar/Link.vue index cd2e0413..bff45cd8 100644 --- a/src/views/layout/components/Sidebar/Link.vue +++ b/src/views/layout/components/Sidebar/Link.vue @@ -7,7 +7,7 @@