add layout setting ui

This commit is contained in:
huzhushan 2021-07-23 17:25:30 +08:00
parent 4ea866e38d
commit fc6d8f317d
13 changed files with 258 additions and 61 deletions

View File

@ -24,7 +24,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 12:48:43 * @LastEditTime: 2021-07-23 15:12:50
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -33,7 +33,20 @@
<template> <template>
<router-view /> <router-view />
<layout-settings />
</template> </template>
<script>
import { defineComponent } from 'vue'
import LayoutSettings from '@/components/LayoutSettings/index.vue'
export default defineComponent({
components: {
LayoutSettings,
},
setup() {},
})
</script>
<style lang="scss"> <style lang="scss">
html, html,
body, body,

View File

@ -60,15 +60,16 @@
type="primary" type="primary"
icon="el-icon-delete" icon="el-icon-delete"
@click="clearAll" @click="clearAll"
>Clear All</el-button
> >
Clear All
</el-button>
</template> </template>
<el-table :data="errorLogs" border> <el-table :data="errorLogs" border>
<el-table-column label="Message"> <el-table-column label="Message">
<template #default="{ row }"> <template #default="{ row }">
<div style="margin-bottom:10px"> <div style="margin-bottom:10px">
<span class="message-title" style="padding-right: 16px;" <span class="message-title" style="padding-right: 16px;">
>页面: 页面:
</span> </span>
<el-tag type="success"> <el-tag type="success">
{{ row.url }} {{ row.url }}
@ -90,8 +91,8 @@
</div> </div>
<div v-if="row.err && row.err.config"> <div v-if="row.err && row.err.config">
<span class="message-title" style="padding-right: 16px;" <span class="message-title" style="padding-right: 16px;">
>接口地址: 接口地址:
</span> </span>
<el-tag type="info"> <el-tag type="info">
{{ row.err && row.err.config && row.err.config.url }} {{ row.err && row.err.config && row.err.config.url }}

View File

@ -0,0 +1,112 @@
<!--
* 佛曰:
* 写字楼里写字间写字间里程序员
* 程序人员写程序又拿程序换酒钱
* 酒醒只在网上坐酒醉还来网下眠
* 酒醉酒醒日复日网上网下年复年
* 但愿老死电脑间不愿鞠躬老板前
* 奔驰宝马贵者趣公交自行程序员
* 别人笑我忒疯癫我笑自己命太贱
* 不见满街漂亮妹哪个归得程序员
*
* @Descripttion:
* @version:
* @Date: 2021-07-23 15:04:58
* @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 16:54:26
* @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin
* @Donate: https://huzhushan.gitee.io/vue3-element-admin/donate/
-->
<template>
<el-button
class="btn-switch"
type="primary"
icon="el-icon-setting"
@click="drawer = true"
></el-button>
<el-drawer title="布局设置" :size="320" v-model="drawer" destroy-on-close>
<div class="box">
<div class="list">
<div class="item">
<div>内容宽度</div>
<el-select class="select" size="mini" v-model="layout.isFluid">
<el-option :value="true" label="流式布局" />
<el-option :value="false" label="固定宽度" />
</el-select>
</div>
<div class="item">
<div>菜单栏排列方式</div>
<el-select class="select" size="mini" v-model="menus.mode">
<el-option value="horizontal" label="水平排列" />
<el-option value="vertical" label="垂直排列" />
</el-select>
</div>
<el-divider />
<div class="item">
<div>显示标签栏</div>
<el-switch v-model="tagsbar.isShow" />
</div>
<div class="item">
<div>显示面包屑导航</div>
<el-switch v-model="breadcrumbs.isShow" />
</div>
<el-divider />
<div class="item">
<div>固定头部</div>
<el-switch v-model="topbar.isFixed" />
</div>
</div>
</div>
</el-drawer>
</template>
<script>
import { defineComponent, reactive, ref, toRaw, toRefs, watch } from 'vue'
import { useStore } from 'vuex'
export default defineComponent({
setup() {
const store = useStore()
const drawer = ref(false)
const settings = reactive({
...store.state.layoutSettings,
})
watch(settings, value => {
store.commit('layoutSettings/SAVE_SETTINGS', toRaw(value))
})
return {
drawer,
...toRefs(settings),
}
},
})
</script>
<style lang="scss" scoped>
.btn-switch {
position: fixed;
top: 100px;
right: -6px;
font-size: 20px;
}
.box {
height: 100%;
overflow: auto;
display: flex;
flex-direction: column;
.list {
flex: 1;
padding: 0 16px;
.item {
padding: 8px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.select {
width: 100px;
}
}
}
</style>

View File

@ -73,8 +73,9 @@
v-for="option of item.options" v-for="option of item.options"
:key="option.value" :key="option.value"
:label="option.value" :label="option.value"
>{{ option.name }}</el-radio
> >
{{ option.name }}
</el-radio>
</el-radio-group> </el-radio-group>
<el-radio-group <el-radio-group
v-model="searchModel[item.name]" v-model="searchModel[item.name]"
@ -85,8 +86,9 @@
v-for="option of item.options" v-for="option of item.options"
:key="option.value" :key="option.value"
:label="option.value" :label="option.value"
>{{ option.name }}</el-radio-button
> >
{{ option.name }}
</el-radio-button>
</el-radio-group> </el-radio-group>
<el-checkbox-group <el-checkbox-group
v-model="searchModel[item.name]" v-model="searchModel[item.name]"
@ -97,8 +99,9 @@
v-for="option of item.options" v-for="option of item.options"
:key="option.value" :key="option.value"
:label="option.value" :label="option.value"
>{{ option.name }}</el-checkbox
> >
{{ option.name }}
</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
<el-checkbox-group <el-checkbox-group
v-model="searchModel[item.name]" v-model="searchModel[item.name]"
@ -109,8 +112,9 @@
v-for="option of item.options" v-for="option of item.options"
:key="option.value" :key="option.value"
:label="option.value" :label="option.value"
>{{ option.name }}</el-checkbox-button
> >
{{ option.name }}
</el-checkbox-button>
</el-checkbox-group> </el-checkbox-group>
<el-date-picker <el-date-picker
v-else-if="item.type === 'date'" v-else-if="item.type === 'date'"
@ -182,12 +186,12 @@
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item class="search-btn"> <el-form-item class="search-btn">
<el-button type="primary" icon="el-icon-search" @click="handleSearch" <el-button type="primary" icon="el-icon-search" @click="handleSearch">
>查询</el-button 查询
> </el-button>
<el-button @click="handleReset" icon="el-icon-refresh-right" <el-button @click="handleReset" icon="el-icon-refresh-right">
>重置</el-button 重置
> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -13,7 +13,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 14:39:22 * @LastEditTime: 2021-07-23 16:48:37
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -68,15 +68,17 @@
</template> </template>
<script> <script>
import { defineComponent, inject, computed } from 'vue' import { defineComponent, computed } from 'vue'
import { useTags } from './hooks/useTags' import { useTags } from './hooks/useTags'
import { useContextMenu } from './hooks/useContextMenu' import { useContextMenu } from './hooks/useContextMenu'
import { useStore } from 'vuex'
export default defineComponent({ export default defineComponent({
name: 'Tagsbar', name: 'Tagsbar',
setup() { setup() {
const defaultSettings = inject('defaultSettings') const store = useStore()
const isTagsbarShow = computed(() => defaultSettings.tagsbar.isShow) const defaultSettings = computed(() => store.state.layoutSettings)
const isTagsbarShow = computed(() => defaultSettings.value.tagsbar.isShow)
const tags = useTags() const tags = useTags()
const contextMenu = useContextMenu(tags.tagList) const contextMenu = useContextMenu(tags.tagList)

View File

@ -27,7 +27,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 14:13:23 * @LastEditTime: 2021-07-23 17:22:14
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -38,7 +38,11 @@
<el-breadcrumb <el-breadcrumb
separator-class="el-icon-arrow-right" separator-class="el-icon-arrow-right"
class="breadcrumb" class="breadcrumb"
:class="{ mobile: device === 'mobile', show: isHorizontalMenu }" :class="{
mobile: device === 'mobile',
show: isHorizontalMenu,
hide: breadcrumbs.length <= 1,
}"
> >
<el-breadcrumb-item <el-breadcrumb-item
v-for="(item, index) in breadcrumbs" v-for="(item, index) in breadcrumbs"
@ -51,28 +55,20 @@
</el-breadcrumb> </el-breadcrumb>
</template> </template>
<script> <script>
import { import { defineComponent, computed, ref, onBeforeMount, watch } from 'vue'
defineComponent,
computed,
ref,
onBeforeMount,
watch,
inject,
} from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useStore } from 'vuex' import { useStore } from 'vuex'
export default defineComponent({ export default defineComponent({
setup() { setup(props, { emit }) {
const store = useStore() const store = useStore()
const device = computed(() => store.state.app.device) const device = computed(() => store.state.app.device)
const router = useRouter() const router = useRouter()
const route = router.currentRoute // 使useRoutewatch const route = router.currentRoute // 使useRoutewatch
const breadcrumbs = ref([]) const breadcrumbs = ref([])
const defaultSettings = computed(() => store.state.layoutSettings)
const defaultSettings = inject('defaultSettings')
const isHorizontalMenu = computed( const isHorizontalMenu = computed(
() => defaultSettings.menus.mode === 'horizontal' () => defaultSettings.value.menus.mode === 'horizontal'
) )
const getBreadcrumbs = route => { const getBreadcrumbs = route => {
@ -92,9 +88,16 @@ export default defineComponent({
breadcrumbs.value = getBreadcrumbs(route.value) breadcrumbs.value = getBreadcrumbs(route.value)
}) })
watch(route, newRoute => { watch(
breadcrumbs.value = getBreadcrumbs(newRoute) route,
}) newRoute => {
breadcrumbs.value = getBreadcrumbs(newRoute)
emit('on-breadcrumbs-change', breadcrumbs.value.length > 1)
},
{
immediate: true,
}
)
return { return {
device, device,
@ -132,6 +135,9 @@ export default defineComponent({
padding: 16px; padding: 16px;
background: #f5f5f5; background: #f5f5f5;
} }
&.hide {
display: none;
}
} }
</style> </style>
<style lang="scss"> <style lang="scss">

View File

@ -37,7 +37,7 @@
* @version: * @version:
* @Date: 2021-04-21 09:18:32 * @Date: 2021-04-21 09:18:32
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 13:42:10 * @LastEditTime: 2021-07-23 16:49:39
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -62,7 +62,7 @@
</div> </div>
</template> </template>
<script> <script>
import { defineComponent, computed, inject } from 'vue' import { defineComponent, computed } from 'vue'
import Logo from '@/layout/components/Sidebar/Logo.vue' import Logo from '@/layout/components/Sidebar/Logo.vue'
import Hamburger from './Hamburger.vue' import Hamburger from './Hamburger.vue'
import Breadcrumbs from './Breadcrumbs.vue' import Breadcrumbs from './Breadcrumbs.vue'
@ -79,13 +79,13 @@ export default defineComponent({
ErrorLog, ErrorLog,
}, },
setup() { setup() {
const defaultSettings = inject('defaultSettings')
const store = useStore() const store = useStore()
const defaultSettings = computed(() => store.state.layoutSettings)
const device = computed(() => store.state.app.device) const device = computed(() => store.state.app.device)
const isHorizontalMenu = computed( const isHorizontalMenu = computed(
() => defaultSettings.menus.mode === 'horizontal' () => defaultSettings.value.menus.mode === 'horizontal'
) )
const isShowLogo = computed( const isShowLogo = computed(
@ -95,7 +95,7 @@ export default defineComponent({
const isShowHamburger = computed(() => !isHorizontalMenu.value) const isShowHamburger = computed(() => !isHorizontalMenu.value)
const isShowBreadcrumbs = computed( const isShowBreadcrumbs = computed(
() => defaultSettings.breadcrumbs.isShow && !isHorizontalMenu.value () => defaultSettings.value.breadcrumbs.isShow && !isHorizontalMenu.value
) )
return { return {

View File

@ -27,7 +27,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 14:39:15 * @LastEditTime: 2021-07-23 17:19:35
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -42,16 +42,19 @@
<topbar /> <topbar />
<menus mode="horizontal" v-if="isHorizontalMenu" /> <menus mode="horizontal" v-if="isHorizontalMenu" />
<tagsbar /> <tagsbar />
<breadcrumbs v-if="isBreadcrumbsShow" /> <breadcrumbs
v-if="isBreadcrumbsShow"
@on-breadcrumbs-change="handleBreadcrumbsChange"
/>
</div> </div>
<div class="main" :class="{ pt0: isBreadcrumbsShow }"> <div class="main" :class="{ pt0: isBreadcrumbsShow && paddingFlag }">
<Content /> <Content />
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { defineComponent, computed, inject } from 'vue' import { defineComponent, ref, computed } from 'vue'
import Sidebar from './components/Sidebar/index.vue' import Sidebar from './components/Sidebar/index.vue'
import Topbar from './components/Topbar/index.vue' import Topbar from './components/Topbar/index.vue'
import Menus from './components/Sidebar/Menus.vue' import Menus from './components/Sidebar/Menus.vue'
@ -59,6 +62,7 @@ import Tagsbar from './components/Tagsbar/index.vue'
import Breadcrumbs from './components/Topbar/Breadcrumbs.vue' import Breadcrumbs from './components/Topbar/Breadcrumbs.vue'
import Content from './components/Content/index.vue' import Content from './components/Content/index.vue'
import { useResizeHandler } from './hooks/useResizeHandler' import { useResizeHandler } from './hooks/useResizeHandler'
import { useStore } from 'vuex'
export default defineComponent({ export default defineComponent({
name: 'layout', name: 'layout',
@ -72,22 +76,28 @@ export default defineComponent({
}, },
setup() { setup() {
useResizeHandler() useResizeHandler()
const store = useStore()
const defaultSettings = inject('defaultSettings') const defaultSettings = computed(() => store.state.layoutSettings)
const isFluid = computed(() => defaultSettings.layout.isFluid) const isFluid = computed(() => defaultSettings.value.layout.isFluid)
const isTopbarFixed = computed(() => defaultSettings.topbar.isFixed) const isTopbarFixed = computed(() => defaultSettings.value.topbar.isFixed)
const isHorizontalMenu = computed( const isHorizontalMenu = computed(
() => defaultSettings.menus.mode === 'horizontal' () => defaultSettings.value.menus.mode === 'horizontal'
) )
const isBreadcrumbsShow = computed( const isBreadcrumbsShow = computed(
() => isHorizontalMenu.value && defaultSettings.breadcrumbs.isShow () => isHorizontalMenu.value && defaultSettings.value.breadcrumbs.isShow
) )
const paddingFlag = ref(true)
const handleBreadcrumbsChange = boo => {
paddingFlag.value = boo
}
return { return {
isFluid, isFluid,
isTopbarFixed, isTopbarFixed,
isHorizontalMenu, isHorizontalMenu,
isBreadcrumbsShow, isBreadcrumbsShow,
paddingFlag,
handleBreadcrumbsChange,
} }
}, },
}) })

View File

@ -27,7 +27,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-22 18:04:34 * @LastEditTime: 2021-07-23 16:50:08
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -58,10 +58,6 @@ import './permission'
// 引入svg图标注册脚本 // 引入svg图标注册脚本
import 'vite-plugin-svg-icons/register' import 'vite-plugin-svg-icons/register'
// 引入全局设置
import defaultSettings from './defaultSettings'
app.provide('defaultSettings', defaultSettings)
// 注册全局组件 // 注册全局组件
import * as Components from './global-components' import * as Components from './global-components'
Object.entries(Components).forEach(([key, component]) => { Object.entries(Components).forEach(([key, component]) => {

View File

@ -0,0 +1,50 @@
/*
* _______________#########_______________________
* ______________############_____________________
* ______________#############____________________
* _____________##__###########___________________
* ____________###__######_#####__________________
* ____________###_#######___####_________________
* ___________###__##########_####________________
* __________####__###########_####_______________
* ________#####___###########__#####_____________
* _______######___###_########___#####___________
* _______#####___###___########___######_________
* ______######___###__###########___######_______
* _____######___####_##############__######______
* ____#######__#####################_#######_____
* ____#######__##############################____
* ___#######__######_#################_#######___
* ___#######__######_######_#########___######___
* ___#######____##__######___######_____######___
* ___#######________######____#####_____#####____
* ____######________#####_____#####_____####_____
* _____#####________####______#####_____###______
* ______#####______;###________###______#________
* ________##_______####________####______________
*
* @Descripttion:
* @version:
* @Date: 2021-07-23 16:10:49
* @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 16:19:35
* @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin
* @Donate: https://huzhushan.gitee.io/vue3-element-admin/donate/
*/
import { getItem, setItem } from '@/utils/storage' //getItem和setItem是封装的操作localStorage的方法
import defaultSettings from '@/defaultSettings'
export default {
namespaced: true,
state: getItem('defaultSettings') || defaultSettings,
mutations: {
SAVE_SETTINGS(state, data) {
Object.entries(data).forEach(([key, value]) => {
state[key] = value
})
setItem('defaultSettings', data)
},
},
}

View File

@ -48,7 +48,8 @@
<h1 class="title"> <h1 class="title">
屏幕已锁定 屏幕已锁定
<div class="unlock-btn" @click="handleUnlock"> <div class="unlock-btn" @click="handleUnlock">
<i class="el-icon-unlock"></i>解锁 <i class="el-icon-unlock"></i>
解锁
</div> </div>
</h1> </h1>
<div class="unlock-modal" v-show="showModal"> <div class="unlock-modal" v-show="showModal">

View File

@ -38,8 +38,9 @@
type="primary" type="primary"
class="btn" class="btn"
@click="submit" @click="submit"
>{{ btnText }}</el-button
> >
{{ btnText }}
</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>

View File

@ -12,7 +12,8 @@
<template> <template>
<h2>该页面入口不在菜单中显示</h2> <h2>该页面入口不在菜单中显示</h2>
<div> <div>
如果不需要在菜单中显示<br /> 如果不需要在菜单中显示
<br />
需要配置路由增加属性hidden: true注意不是在meta中增加该属性而是跟meta同级 需要配置路由增加属性hidden: true注意不是在meta中增加该属性而是跟meta同级
</div> </div>
</template> </template>