feat(Component): Setting component add copy button
This commit is contained in:
parent
ff4dd3afbf
commit
e496096539
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ElDrawer, ElDivider } from 'element-plus'
|
import { ElDrawer, ElDivider, ElButton, ElMessage } from 'element-plus'
|
||||||
import { ref, unref, computed, watch } from 'vue'
|
import { ref, unref, computed, watch } from 'vue'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { ThemeSwitch } from '@/components/ThemeSwitch'
|
import { ThemeSwitch } from '@/components/ThemeSwitch'
|
||||||
|
@ -10,6 +10,8 @@ import { trim, setCssVar } from '@/utils'
|
||||||
import ColorRadioPicker from './components/ColorRadioPicker.vue'
|
import ColorRadioPicker from './components/ColorRadioPicker.vue'
|
||||||
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
||||||
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
|
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
|
||||||
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
@ -100,6 +102,84 @@ watch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 拷贝
|
||||||
|
const copyConfig = async () => {
|
||||||
|
const { copy, copied } = useClipboard({
|
||||||
|
source: `
|
||||||
|
// 面包屑
|
||||||
|
breadcrumb: ${appStore.getBreadcrumb},
|
||||||
|
// 面包屑图标
|
||||||
|
breadcrumbIcon: ${appStore.getBreadcrumbIcon},
|
||||||
|
// 折叠图标
|
||||||
|
hamburger: ${appStore.getHamburger},
|
||||||
|
// 全屏图标
|
||||||
|
screenfull: ${appStore.getScreenfull},
|
||||||
|
// 尺寸图标
|
||||||
|
size: ${appStore.getSize},
|
||||||
|
// 多语言图标
|
||||||
|
locale: ${appStore.getLocale},
|
||||||
|
// 标签页
|
||||||
|
tagsView: ${appStore.getTagsView},
|
||||||
|
// logo
|
||||||
|
logo: ${appStore.getLogo},
|
||||||
|
// 固定header
|
||||||
|
fixedHeader: ${appStore.getFixedHeader},
|
||||||
|
// 灰色模式
|
||||||
|
greyMode: ${appStore.getGreyMode},
|
||||||
|
// layout布局
|
||||||
|
layout: '${appStore.getLayout}',
|
||||||
|
// 暗黑模式
|
||||||
|
isDark: ${appStore.getIsDark},
|
||||||
|
// 组件尺寸
|
||||||
|
currentSize: '${appStore.getCurrentSize}',
|
||||||
|
// 主题相关
|
||||||
|
theme: {
|
||||||
|
// 主题色
|
||||||
|
elColorPrimary: '${appStore.getTheme.elColorPrimary}',
|
||||||
|
// 左侧菜单边框颜色
|
||||||
|
leftMenuBorderColor: '${appStore.getTheme.leftMenuBorderColor}',
|
||||||
|
// 左侧菜单背景颜色
|
||||||
|
leftMenuBgColor: '${appStore.getTheme.leftMenuBgColor}',
|
||||||
|
// 左侧菜单浅色背景颜色
|
||||||
|
leftMenuBgLightColor: '${appStore.getTheme.leftMenuBgLightColor}',
|
||||||
|
// 左侧菜单选中背景颜色
|
||||||
|
leftMenuBgActiveColor: '${appStore.getTheme.leftMenuBgActiveColor}',
|
||||||
|
// 左侧菜单收起选中背景颜色
|
||||||
|
leftMenuCollapseBgActiveColor: '${appStore.getTheme.leftMenuCollapseBgActiveColor}',
|
||||||
|
// 左侧菜单字体颜色
|
||||||
|
leftMenuTextColor: '${appStore.getTheme.leftMenuTextColor}',
|
||||||
|
// 左侧菜单选中字体颜色
|
||||||
|
leftMenuTextActiveColor: '${appStore.getTheme.leftMenuTextActiveColor}',
|
||||||
|
// logo字体颜色
|
||||||
|
logoTitleTextColor: '${appStore.getTheme.logoTitleTextColor}',
|
||||||
|
// logo边框颜色
|
||||||
|
logoBorderColor: '${appStore.getTheme.logoBorderColor}',
|
||||||
|
// 头部背景颜色
|
||||||
|
topHeaderBgColor: '${appStore.getTheme.topHeaderBgColor}',
|
||||||
|
// 头部字体颜色
|
||||||
|
topHeaderTextColor: '${appStore.getTheme.topHeaderTextColor}',
|
||||||
|
// 头部悬停颜色
|
||||||
|
topHeaderHoverColor: '${appStore.getTheme.topHeaderHoverColor}',
|
||||||
|
// 头部边框颜色
|
||||||
|
topToolBorderColor: '${appStore.getTheme.topToolBorderColor}'
|
||||||
|
}
|
||||||
|
`
|
||||||
|
})
|
||||||
|
await copy()
|
||||||
|
if (unref(copied)) {
|
||||||
|
ElMessage.success(t('setting.copySuccess'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空缓存
|
||||||
|
const clear = () => {
|
||||||
|
const { wsCache } = useCache()
|
||||||
|
wsCache.delete('layout')
|
||||||
|
wsCache.delete('theme')
|
||||||
|
wsCache.delete('isDark')
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -181,6 +261,16 @@ watch(
|
||||||
<!-- 界面显示 -->
|
<!-- 界面显示 -->
|
||||||
<ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
|
<ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
|
||||||
<InterfaceDisplay />
|
<InterfaceDisplay />
|
||||||
|
|
||||||
|
<ElDivider />
|
||||||
|
<div>
|
||||||
|
<ElButton type="primary" class="w-full" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5px">
|
||||||
|
<ElButton type="danger" class="w-full" @click="clear">
|
||||||
|
{{ t('setting.clearAndReset') }}
|
||||||
|
</ElButton>
|
||||||
|
</div>
|
||||||
</ElDrawer>
|
</ElDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ export default defineComponent({
|
||||||
(routers: AppRouteRecordRaw[]) => {
|
(routers: AppRouteRecordRaw[]) => {
|
||||||
initTabMap(routers)
|
initTabMap(routers)
|
||||||
filterMenusPath(routers, routers)
|
filterMenusPath(routers, routers)
|
||||||
console.log(tabPathMap)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
|
|
@ -15,9 +15,8 @@ export interface AppState {
|
||||||
tagsView: boolean
|
tagsView: boolean
|
||||||
logo: boolean
|
logo: boolean
|
||||||
fixedHeader: boolean
|
fixedHeader: boolean
|
||||||
fixedMenu: boolean
|
|
||||||
greyMode: boolean
|
greyMode: boolean
|
||||||
|
pageLoading: boolean
|
||||||
layout: LayoutType
|
layout: LayoutType
|
||||||
title: string
|
title: string
|
||||||
userInfo: string
|
userInfo: string
|
||||||
|
@ -29,6 +28,12 @@ export interface AppState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appModules: AppState = {
|
export const appModules: AppState = {
|
||||||
|
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
||||||
|
sizeMap: ['default', 'large', 'small'],
|
||||||
|
mobile: false, // 是否是移动端
|
||||||
|
title: 'ButterflyAdmin', // 标题
|
||||||
|
pageLoading: false, // 路由跳转loading
|
||||||
|
|
||||||
breadcrumb: true, // 面包屑
|
breadcrumb: true, // 面包屑
|
||||||
breadcrumbIcon: true, // 面包屑图标
|
breadcrumbIcon: true, // 面包屑图标
|
||||||
collapse: false, // 折叠菜单
|
collapse: false, // 折叠菜单
|
||||||
|
@ -39,16 +44,11 @@ export const appModules: AppState = {
|
||||||
tagsView: true, // 标签页
|
tagsView: true, // 标签页
|
||||||
logo: true, // logo
|
logo: true, // logo
|
||||||
fixedHeader: true, // 固定toolheader
|
fixedHeader: true, // 固定toolheader
|
||||||
fixedMenu: false, // 固定切割菜单
|
|
||||||
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
||||||
|
|
||||||
layout: wsCache.get('layout') || 'classic', // layout布局
|
layout: wsCache.get('layout') || 'classic', // layout布局
|
||||||
title: 'ButterflyAdmin', // 标题
|
|
||||||
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
|
||||||
isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
|
isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
|
||||||
currentSize: wsCache.get('default') || 'default', // 组件尺寸
|
currentSize: wsCache.get('default') || 'default', // 组件尺寸
|
||||||
sizeMap: ['default', 'large', 'small'],
|
|
||||||
mobile: false, // 是否是移动端
|
|
||||||
theme: wsCache.get('theme') || {
|
theme: wsCache.get('theme') || {
|
||||||
// 主题色
|
// 主题色
|
||||||
elColorPrimary: '#409eff',
|
elColorPrimary: '#409eff',
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStoreWithOut()
|
||||||
|
|
||||||
|
export const usePageLoading = () => {
|
||||||
|
const loadStart = () => {
|
||||||
|
appStore.setPageLoading(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadDone = () => {
|
||||||
|
appStore.setPageLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
loadStart,
|
||||||
|
loadDone
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import { ElScrollbar } from 'element-plus'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const pageLoading = computed(() => appStore.getPageLoading)
|
||||||
|
|
||||||
// 标签页
|
// 标签页
|
||||||
const tagsView = computed(() => appStore.getTagsView)
|
const tagsView = computed(() => appStore.getTagsView)
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ export const useRenderLayout = () => {
|
||||||
style="transition: all var(--transition-time-02);"
|
style="transition: all var(--transition-time-02);"
|
||||||
>
|
>
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
|
v-loading={pageLoading.value}
|
||||||
class={[
|
class={[
|
||||||
'v-content',
|
'v-content',
|
||||||
{
|
{
|
||||||
|
@ -119,6 +122,7 @@ export const useRenderLayout = () => {
|
||||||
style="transition: all var(--transition-time-02);"
|
style="transition: all var(--transition-time-02);"
|
||||||
>
|
>
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
|
v-loading={pageLoading.value}
|
||||||
class={[
|
class={[
|
||||||
'v-content',
|
'v-content',
|
||||||
{
|
{
|
||||||
|
@ -161,6 +165,7 @@ export const useRenderLayout = () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="v-app-right h-full w-full">
|
<div class="v-app-right h-full w-full">
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
|
v-loading={pageLoading.value}
|
||||||
class={[
|
class={[
|
||||||
'v-content',
|
'v-content',
|
||||||
{
|
{
|
||||||
|
@ -212,6 +217,7 @@ export const useRenderLayout = () => {
|
||||||
style="transition: all var(--transition-time-02);"
|
style="transition: all var(--transition-time-02);"
|
||||||
>
|
>
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
|
v-loading={pageLoading.value}
|
||||||
class={[
|
class={[
|
||||||
'v-content',
|
'v-content',
|
||||||
{
|
{
|
||||||
|
@ -232,7 +238,7 @@ export const useRenderLayout = () => {
|
||||||
!collapse.value && fixedHeader.value
|
!collapse.value && fixedHeader.value
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
style="transition: all var(--transition-time-02);"
|
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
|
||||||
></TagsView>
|
></TagsView>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,10 @@ export default {
|
||||||
greyMode: 'Grey mode',
|
greyMode: 'Grey mode',
|
||||||
fixedHeader: 'Fixed header',
|
fixedHeader: 'Fixed header',
|
||||||
headerTheme: 'Header theme',
|
headerTheme: 'Header theme',
|
||||||
cutMenu: 'Cut Menu'
|
cutMenu: 'Cut Menu',
|
||||||
|
copy: 'Copy',
|
||||||
|
clearAndReset: 'Clear cache and reset',
|
||||||
|
copySuccess: 'Copy success'
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'Default',
|
default: 'Default',
|
||||||
|
|
|
@ -38,7 +38,10 @@ export default {
|
||||||
greyMode: '灰色模式',
|
greyMode: '灰色模式',
|
||||||
fixedHeader: '固定头部',
|
fixedHeader: '固定头部',
|
||||||
headerTheme: '头部主题',
|
headerTheme: '头部主题',
|
||||||
cutMenu: '切割菜单'
|
cutMenu: '切割菜单',
|
||||||
|
copy: '拷贝',
|
||||||
|
clearAndReset: '清除缓存并且重置',
|
||||||
|
copySuccess: '拷贝成功'
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: '默认',
|
default: '默认',
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type { RouteRecordRaw } from 'vue-router'
|
||||||
import { useTitle } from '@/hooks/web/useTitle'
|
import { useTitle } from '@/hooks/web/useTitle'
|
||||||
import { useNProgress } from '@/hooks/web/useNProgress'
|
import { useNProgress } from '@/hooks/web/useNProgress'
|
||||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
||||||
|
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
||||||
|
|
||||||
const permissionStore = usePermissionStoreWithOut()
|
const permissionStore = usePermissionStoreWithOut()
|
||||||
|
|
||||||
|
@ -14,10 +15,13 @@ const { wsCache } = useCache()
|
||||||
|
|
||||||
const { start, done } = useNProgress()
|
const { start, done } = useNProgress()
|
||||||
|
|
||||||
|
const { loadStart, loadDone } = usePageLoading()
|
||||||
|
|
||||||
const whiteList = ['/login'] // 不重定向白名单
|
const whiteList = ['/login'] // 不重定向白名单
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
start()
|
start()
|
||||||
|
loadStart()
|
||||||
if (wsCache.get(appStore.getUserInfo)) {
|
if (wsCache.get(appStore.getUserInfo)) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
next({ path: '/' })
|
next({ path: '/' })
|
||||||
|
@ -48,4 +52,5 @@ router.beforeEach(async (to, from, next) => {
|
||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
useTitle(to?.meta?.title as string)
|
useTitle(to?.meta?.title as string)
|
||||||
done() // 结束Progress
|
done() // 结束Progress
|
||||||
|
loadDone()
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,13 +42,12 @@ export const useAppStore = defineStore({
|
||||||
getFixedHeader(): boolean {
|
getFixedHeader(): boolean {
|
||||||
return this.fixedHeader
|
return this.fixedHeader
|
||||||
},
|
},
|
||||||
getFixedMenu(): boolean {
|
|
||||||
return this.fixedMenu
|
|
||||||
},
|
|
||||||
getGreyMode(): boolean {
|
getGreyMode(): boolean {
|
||||||
return this.greyMode
|
return this.greyMode
|
||||||
},
|
},
|
||||||
|
getPageLoading(): boolean {
|
||||||
|
return this.pageLoading
|
||||||
|
},
|
||||||
getLayout(): LayoutType {
|
getLayout(): LayoutType {
|
||||||
return this.layout
|
return this.layout
|
||||||
},
|
},
|
||||||
|
@ -105,13 +104,12 @@ export const useAppStore = defineStore({
|
||||||
setFixedHeader(fixedHeader: boolean) {
|
setFixedHeader(fixedHeader: boolean) {
|
||||||
this.fixedHeader = fixedHeader
|
this.fixedHeader = fixedHeader
|
||||||
},
|
},
|
||||||
setFixedMenu(fixedMenu: boolean) {
|
|
||||||
this.fixedMenu = fixedMenu
|
|
||||||
},
|
|
||||||
setGreyMode(greyMode: boolean) {
|
setGreyMode(greyMode: boolean) {
|
||||||
this.greyMode = greyMode
|
this.greyMode = greyMode
|
||||||
},
|
},
|
||||||
|
setPageLoading(pageLoading: boolean) {
|
||||||
|
this.pageLoading = pageLoading
|
||||||
|
},
|
||||||
setLayout(layout: LayoutType) {
|
setLayout(layout: LayoutType) {
|
||||||
if (this.mobile && layout !== 'classic') {
|
if (this.mobile && layout !== 'classic') {
|
||||||
ElMessage.warning('移动端模式下不支持切换其他布局')
|
ElMessage.warning('移动端模式下不支持切换其他布局')
|
||||||
|
|
Loading…
Reference in New Issue