layout/ 目录下文件用 script setup 语法糖重写

This commit is contained in:
hooray 2021-09-07 14:29:48 +08:00
parent 94d4a23fd2
commit 5d06055af8
11 changed files with 510 additions and 669 deletions

View File

@ -44,25 +44,3 @@ $g-sub-sidebar-menu-hover-bg: darken(#fafafa, 10);
$g-sub-sidebar-menu-active-color: #e7f4ff;
// 菜单选中背景色
$g-sub-sidebar-menu-active-bg: #5482ee;
// 导航标记
// 背景色
$g-badge-bg: #f56c6c;
// 文字颜色
$g-badge-color: #fff;
// 边框颜色
$g-badge-border-color:#fff;
// 标签栏
// 背景色
$g-tabbar-bg: #f0f2f5;
// 分割线颜色
$g-tabbar-dividers-bg: #a9adb0;
// 标签文字颜色
$g-tabbar-tab-color: #999;
// 标签鼠标悬浮文字颜色
$g-tabbar-tab-hover-color: #999;
// 标签鼠标悬浮背景色
$g-tabbar-tab-hover-bg: #dee1e6;
// 标签选中文字颜色
$g-tabbar-tab-active-color: #97a8be;
// 标签选中背景色
$g-tabbar-tab-active-bg: #fff;

View File

@ -23,29 +23,29 @@
</div>
</template>
<script>
export default {
computed: {
locationOrigin: () => location.origin
},
mounted() {
this.$notify({
type: 'success',
title: '温馨提示',
dangerouslyUseHTMLString: true,
message: `
<script setup>
import { getCurrentInstance, onMounted, ref } from 'vue'
const { proxy } = getCurrentInstance()
const locationOrigin = ref(location.href)
onMounted(() => {
proxy.$notify({
type: 'success',
title: '温馨提示',
dangerouslyUseHTMLString: true,
message: `
<p>当前访问的是<b>基础版</b> (Vue3)</p>
<p>你可以点<a href="https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/vue3/pro/" target="_blank"><b>这里</b></a>访问专业版 (Vue3)</p>
`,
position: 'bottom-right',
duration: 5000
})
},
methods: {
open(url) {
window.open(url, 'top')
}
}
position: 'bottom-right',
duration: 5000
})
})
function open(url) {
window.open(url, 'top')
}
</script>

View File

@ -20,18 +20,12 @@
</transition>
</template>
<script>
<script setup>
import Logo from '../Logo/index.vue'
import UserMenu from '../UserMenu/index.vue'
import { inject } from 'vue'
export default {
name: 'Header',
components: {
Logo,
UserMenu
},
inject: ['switchMenu']
}
const switchMenu = inject('switchMenu')
</script>
<style lang="scss" scoped>

View File

@ -1,45 +1,38 @@
<template>
<router-link :to="to" :class="{
'title': true,
'is-link': $store.state.settings.enableDashboard
}" :title="title"
>
<router-link :to="to" class="title" :class="{'is-link': $store.state.settings.enableDashboard}" :title="title">
<img v-if="showLogo" :src="logo" class="logo">
<span v-if="showTitle">{{ title }}</span>
</router-link>
</template>
<script>
<script setup>
import imgLogo from '@/assets/images/logo.png'
import { defineProps, ref, computed } from 'vue'
import { useStore } from 'vuex'
export default {
name: 'Logo',
props: {
showLogo: {
type: Boolean,
default: true
},
showTitle: {
type: Boolean,
default: true
}
const store = useStore()
defineProps({
showLogo: {
type: Boolean,
default: true
},
data() {
return {
title: import.meta.env.VITE_APP_TITLE,
logo: imgLogo
}
},
computed: {
to() {
let rtn = {}
if (this.$store.state.settings.enableDashboard) {
rtn.name = 'dashboard'
}
return rtn
}
showTitle: {
type: Boolean,
default: true
}
}
})
const title = ref(import.meta.env.VITE_APP_TITLE)
const logo = ref(imgLogo)
const to = computed(() => {
let rtn = {}
if (store.state.settings.enableDashboard) {
rtn.name = 'dashboard'
}
return rtn
})
</script>
<style lang="scss" scoped>

View File

@ -19,16 +19,11 @@
</transition>
</template>
<script>
<script setup>
import Logo from '../Logo/index.vue'
import { inject } from 'vue'
export default {
name: 'MainSidebar',
components: {
Logo
},
inject: ['switchMenu']
}
const switchMenu = inject('switchMenu')
</script>
<style lang="scss" scoped>

View File

@ -2,7 +2,7 @@
<div id="search" :class="{'searching': isShow}" @click="isShow && $eventBus.emit('global-search-toggle')">
<div class="container">
<div class="search-box" @click.stop>
<el-input ref="input" v-model="search" prefix-icon="el-icon-search" placeholder="搜索页面支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
<el-input ref="input" v-model="searchInput" prefix-icon="el-icon-search" placeholder="搜索页面支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
<div class="tips">
<div class="tip">
<span>Alt</span>+<span>S</span>
@ -35,7 +35,7 @@
<svg-icon v-if="item.isExternal" name="external-link" />
</div>
<div class="breadcrumb">
<span v-for="(bc, index) in item.breadcrumb" :key="index">
<span v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex">
{{ bc }}
<i class="el-icon-arrow-right" />
</span>
@ -49,169 +49,163 @@
</div>
</template>
<script>
<script setup>
import { deepClone } from '@/util'
import { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'
import { useStore } from 'vuex'
export default {
name: 'Search',
props: {},
data() {
return {
isShow: false,
search: '',
sourceList: [],
actived: -1
const { proxy } = getCurrentInstance()
const store = useStore()
const isShow = ref(false)
const searchInput = ref('')
const sourceList = ref([])
const actived = ref(-1)
const resultList = computed(() => {
let result = []
result = sourceList.value.filter(item => {
let flag = false
if (item.title.indexOf(searchInput.value) >= 0) {
flag = true
}
},
computed: {
resultList() {
let result = []
result = this.sourceList.filter(item => {
let flag = false
if (item.title.indexOf(this.search) >= 0) {
flag = true
}
if (item.path.indexOf(this.search) >= 0) {
flag = true
}
if (item.breadcrumb.some(b => b.indexOf(this.search) >= 0)) {
flag = true
}
return flag
})
return result
if (item.path.indexOf(searchInput.value) >= 0) {
flag = true
}
},
watch: {
isShow(val) {
if (val) {
document.querySelector('body').classList.add('hidden')
this.$refs.search.scrollTop = 0
// input focus vue
this.$hotkeys('up', this.keyUp)
this.$hotkeys('down', this.keyDown)
this.$hotkeys('enter', this.keyEnter)
setTimeout(() => {
this.$refs.input.$el.children[0].focus()
}, 100)
if (item.breadcrumb.some(b => b.indexOf(searchInput.value) >= 0)) {
flag = true
}
return flag
})
return result
})
watch(() => isShow.value, val => {
if (val) {
document.querySelector('body').classList.add('hidden')
proxy.$refs.search.scrollTop = 0
// input focus vue
proxy.$hotkeys('up', keyUp)
proxy.$hotkeys('down', keyDown)
proxy.$hotkeys('enter', keyEnter)
setTimeout(() => {
proxy.$refs.input.$el.children[0].focus()
}, 100)
} else {
document.querySelector('body').classList.remove('hidden')
proxy.$hotkeys.unbind('up', keyUp)
proxy.$hotkeys.unbind('down', keyDown)
proxy.$hotkeys.unbind('enter', keyEnter)
setTimeout(() => {
searchInput.value = ''
actived.value = -1
}, 500)
}
})
watch(() => resultList.value, () => {
actived.value = -1
scrollTo(0)
})
onMounted(() => {
proxy.$eventBus.on('global-search-toggle', () => {
isShow.value = !isShow.value
})
proxy.$hotkeys('alt+s', e => {
if (store.state.settings.enableNavSearch) {
e.preventDefault()
isShow.value = true
}
})
store.state.menu.routes.map(item => {
getSourceList(item.children)
})
})
function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
function hasChildren(item) {
let flag = true
if (item.children) {
if (item.children.every(i => i.meta.sidebar === false)) {
flag = false
}
} else {
flag = false
}
return flag
}
function getSourceList(arr) {
arr.map(item => {
if (item.meta.sidebar !== false) {
if (hasChildren(item)) {
let baseBreadcrumb = item.meta.baseBreadcrumb ? deepClone(item.meta.baseBreadcrumb) : []
baseBreadcrumb.push(item.meta.title)
let child = deepClone(item.children)
child.map(c => {
c.meta.baseIcon = item.meta.icon || item.meta.baseIcon
c.meta.baseBreadcrumb = baseBreadcrumb
c.meta.basePath = item.meta.basePath ? [item.meta.basePath, item.path].join('/') : item.path
})
getSourceList(child)
} else {
document.querySelector('body').classList.remove('hidden')
this.$hotkeys.unbind('up', this.keyUp)
this.$hotkeys.unbind('down', this.keyDown)
this.$hotkeys.unbind('enter', this.keyEnter)
setTimeout(() => {
this.search = ''
this.actived = -1
}, 500)
let breadcrumb = []
if (item.meta.baseBreadcrumb) {
breadcrumb = deepClone(item.meta.baseBreadcrumb)
}
breadcrumb.push(item.meta.title)
let path = ''
if (isExternal(item.path)) {
path = item.path
} else {
path = item.meta.basePath ? [item.meta.basePath, item.path].join('/') : item.path
}
sourceList.value.push({
icon: item.meta.icon || item.meta.baseIcon,
title: item.meta.title,
i18n: item.meta.i18n,
breadcrumb: breadcrumb,
path: path,
isExternal: isExternal(item.path)
})
}
},
resultList() {
this.actived = -1
this.scrollTo(0)
}
},
created() {},
mounted() {
this.$eventBus.on('global-search-toggle', () => {
this.isShow = !this.isShow
})
this.$hotkeys('alt+s', e => {
if (this.$store.state.settings.enableNavSearch) {
e.preventDefault()
this.isShow = true
}
})
this.$store.state.menu.routes.map(item => {
this.getSourceList(item.children)
})
},
methods: {
isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
},
hasChildren(item) {
let flag = true
if (item.children) {
if (item.children.every(i => i.meta.sidebar === false)) {
flag = false
}
} else {
flag = false
}
return flag
},
getSourceList(arr) {
arr.map(item => {
if (item.meta.sidebar !== false) {
if (this.hasChildren(item)) {
let baseBreadcrumb = item.meta.baseBreadcrumb ? deepClone(item.meta.baseBreadcrumb) : []
baseBreadcrumb.push(item.meta.title)
let child = deepClone(item.children)
child.map(c => {
c.meta.baseIcon = item.meta.icon || item.meta.baseIcon
c.meta.baseBreadcrumb = baseBreadcrumb
c.meta.basePath = item.meta.basePath ? [item.meta.basePath, item.path].join('/') : item.path
})
this.getSourceList(child)
} else {
let breadcrumb = []
if (item.meta.baseBreadcrumb) {
breadcrumb = deepClone(item.meta.baseBreadcrumb)
}
breadcrumb.push(item.meta.title)
let path = ''
if (this.isExternal(item.path)) {
path = item.path
} else {
path = item.meta.basePath ? [item.meta.basePath, item.path].join('/') : item.path
}
this.sourceList.push({
icon: item.meta.icon || item.meta.baseIcon,
title: item.meta.title,
i18n: item.meta.i18n,
breadcrumb: breadcrumb,
path: path,
isExternal: this.isExternal(item.path)
})
}
}
})
}
function keyUp() {
if (resultList.value.length) {
actived.value -= 1
if (actived.value < 0) {
actived.value = resultList.value.length - 1
}
scrollTo(proxy.$refs[`search-item-${actived.value}`].offsetTop)
}
}
function keyDown() {
if (resultList.value.length) {
actived.value += 1
if (actived.value > resultList.value.length - 1) {
actived.value = 0
}
scrollTo(proxy.$refs[`search-item-${actived.value}`].offsetTop)
}
}
function keyEnter() {
if (actived.value !== -1) {
proxy.$refs[`search-item-${actived.value}`].click()
}
}
function scrollTo(offsetTop) {
if (actived.value !== -1) {
if (
offsetTop + proxy.$refs[`search-item-${actived.value}`].clientHeight > proxy.$refs['search'].scrollTop + proxy.$refs['search'].clientHeight ||
offsetTop + proxy.$refs[`search-item-${actived.value}`].clientHeight <= proxy.$refs['search'].scrollTop
) {
proxy.$refs['search'].scrollTo({
top: offsetTop,
behavior: 'smooth'
})
},
keyUp() {
if (this.resultList.length) {
this.actived -= 1
if (this.actived < 0) {
this.actived = this.resultList.length - 1
}
this.scrollTo(this.$refs[`search-item-${this.actived}`].offsetTop)
}
},
keyDown() {
if (this.resultList.length) {
this.actived += 1
if (this.actived > this.resultList.length - 1) {
this.actived = 0
}
this.scrollTo(this.$refs[`search-item-${this.actived}`].offsetTop)
}
},
keyEnter() {
if (this.actived !== -1) {
this.$refs[`search-item-${this.actived}`].click()
}
},
scrollTo(offsetTop) {
if (this.actived !== -1) {
if (
offsetTop + this.$refs[`search-item-${this.actived}`].clientHeight > this.$refs['search'].scrollTop + this.$refs['search'].clientHeight ||
offsetTop + this.$refs[`search-item-${this.actived}`].clientHeight <= this.$refs['search'].scrollTop
) {
this.$refs['search'].scrollTo({
top: offsetTop,
behavior: 'smooth'
})
}
}
}
}
}

View File

@ -10,14 +10,8 @@
<router-link v-else-if="!hasChildren" v-slot="{ href, navigate, isActive, isExactActive }" custom :to="resolvePath(item.path)">
<a :href="isExternal(resolvePath(item.path)) ? resolvePath(item.path) : href" :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']" :target="isExternal(resolvePath(item.path)) ? '_blank' : '_self'" @click="navigate">
<el-menu-item :title="item.meta.title" :index="resolvePath(item.path)">
<svg-icon v-if="iconName(isActive || isExactActive, item.meta.icon, item.meta.activeIcon)" :name="iconName(isActive || isExactActive, item.meta.icon, item.meta.activeIcon)" class="icon" />
<svg-icon v-if="iconName(isActive || isExactActive, item.meta.icon)" :name="iconName(isActive || isExactActive, item.meta.icon)" class="icon" />
<span class="title">{{ item.meta.title }}</span>
<span v-if="badge(item.meta.badge).visible" :class="{
'badge': true,
'badge-dot': badge(item.meta.badge).type === 'dot',
'badge-text': badge(item.meta.badge).type === 'text'
}"
>{{ badge(item.meta.badge).type === 'text' ? badge(item.meta.badge).value : '' }}</span>
</el-menu-item>
</a>
</router-link>
@ -26,102 +20,58 @@
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" class="icon unactive" />
<svg-icon v-if="item.meta.activeIcon || item.meta.icon" :name="item.meta.activeIcon || item.meta.icon" class="icon active" />
<span class="title">{{ item.meta.title }}</span>
<span v-if="badge(item.meta.badge).visible" :class="{
'badge': true,
'badge-dot': badge(item.meta.badge).type === 'dot',
'badge-text': badge(item.meta.badge).type === 'text'
}"
>{{ badge(item.meta.badge).type === 'text' ? badge(item.meta.badge).value : '' }}</span>
</template>
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" :base-path="resolvePath(item.path)" />
</el-sub-menu>
</div>
</template>
<script>
<script setup>
import SidebarItem from './index.vue'
import path from 'path-browserify'
import { computed, defineProps } from 'vue'
export default {
name: 'SidebarItem',
props: {
item: {
type: Object,
required: true
},
basePath: {
type: String,
default: ''
}
const props = defineProps({
item: {
type: Object,
required: true
},
data() {
return {}
},
computed: {
hasChildren() {
let flag = true
if (this.item.children) {
if (this.item.children.every(item => item.meta.sidebar === false)) {
flag = false
}
} else {
flag = false
}
return flag
}
},
created() {},
mounted() {},
methods: {
isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
},
resolvePath(routePath) {
if (this.isExternal(routePath)) {
return routePath
}
if (this.isExternal(this.basePath)) {
return this.basePath
}
return this.basePath ? path.resolve(this.basePath, routePath) : routePath
},
iconName(isActive, icon, activeIcon) {
let name = ''
if ((!isActive && icon) || (isActive && !activeIcon)) {
name = icon
} else if (isActive && activeIcon) {
name = activeIcon
}
return name
},
badge(badge) {
let res = {
type: '', // text or dot
value: '',
visible: false
}
if (badge) {
res.visible = true
res.value = typeof badge == 'function' ? badge() : badge
if (typeof res.value == 'boolean') {
res.type = 'dot'
if (!res.value) {
res.visible = false
}
} else if (typeof res.value == 'number') {
res.type = 'text'
if (res.value <= 0) {
res.visible = false
}
} else {
res.type = 'text'
if (!res.value) {
res.visible = false
}
}
}
return res
}
basePath: {
type: String,
default: ''
}
})
const hasChildren = computed(() => {
let flag = true
if (props.item.children) {
if (props.item.children.every(item => item.meta.sidebar === false)) {
flag = false
}
} else {
flag = false
}
return flag
})
function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
function resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(props.basePath)) {
return props.basePath
}
return props.basePath ? path.resolve(props.basePath, routePath) : routePath
}
function iconName(isActive, icon) {
let name = ''
if (!isActive && icon) {
name = icon
}
return name
}
</script>
@ -176,52 +126,6 @@ a {
color: inherit;
text-decoration: none;
}
.badge {
position: absolute;
z-index: 1;
background-color: $g-badge-bg;
box-shadow: 0 0 0 1px $g-badge-border-color;
@include position-center(y);
&-dot {
right: 15px;
border-radius: 50%;
width: 6px;
height: 6px;
&::after {
content: '';
pointer-events: none;
position: absolute;
top: 0;
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
animation: dot-twinkling 1s infinite ease-in-out;
background-color: $g-badge-bg;
}
}
@keyframes dot-twinkling {
0% {
opacity: 0.6;
transform: scale(0.8);
}
100% {
opacity: 0;
transform: scale(2.4);
}
}
&-text {
right: 15px;
border-radius: 10px;
font-size: 12px;
height: 18px;
line-height: 18px;
padding: 0 6px;
text-align: center;
white-space: nowrap;
color: $g-badge-color;
}
}
.el-sub-menu__title {
> .badge {
&-dot {

View File

@ -20,26 +20,15 @@
</div>
</template>
<script>
<script setup>
import Logo from '../Logo/index.vue'
import SidebarItem from '../SidebarItem/index.vue'
import { ref } from 'vue'
export default {
name: 'SubSidebar',
components: {
Logo,
SidebarItem
},
data() {
return {
sidebarScrollTop: 0
}
},
methods: {
onSidebarScroll(e) {
this.sidebarScrollTop = e.target.scrollTop
}
}
const sidebarScrollTop = ref(0)
function onSidebarScroll(e) {
sidebarScrollTop.value = e.target.scrollTop
}
</script>

View File

@ -139,178 +139,179 @@
</div>
</template>
<script>
export default {
name: 'ThemeSetting',
inject: ['reload'],
props: {},
data() {
return {
isShow: false
}
<script setup>
import { computed, getCurrentInstance, inject, onMounted, ref } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
const { proxy } = getCurrentInstance()
const store = useStore()
const route = useRoute()
const reload = inject('reload')
const isShow = ref(false)
const menuMode = computed({
get: function() {
return store.state.settings.menuMode
},
computed: {
menuMode: {
get: function() {
return this.$store.state.settings.menuMode
},
set: function(newValue) {
this.$store.commit('menu/switchHeaderActived', 0)
this.$store.commit('settings/updateThemeSetting', {
'menuMode': newValue
})
this.$store.state.settings.menuMode !== 'single' && this.$store.commit('menu/setHeaderActived', this.$route.fullPath)
}
},
elementSize: {
get: function() {
return this.$store.state.settings.elementSize
},
set: function(newValue) {
this.$ELEMENT.size = newValue
this.$store.commit('settings/updateThemeSetting', {
'elementSize': newValue
})
this.reload()
}
},
enableSidebarCollapse: {
get: function() {
return this.$store.state.settings.enableSidebarCollapse
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableSidebarCollapse': newValue
})
}
},
sidebarCollapse: {
get: function() {
return this.$store.state.settings.sidebarCollapse
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'sidebarCollapse': newValue
})
}
},
switchSidebarAndPageJump: {
get: function() {
return this.$store.state.settings.switchSidebarAndPageJump
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'switchSidebarAndPageJump': newValue
})
}
},
sidebarUniqueOpened: {
get: function() {
return this.$store.state.settings.sidebarUniqueOpened
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'sidebarUniqueOpened': newValue
})
}
},
topbarFixed: {
get: function() {
return this.$store.state.settings.topbarFixed
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'topbarFixed': newValue
})
}
},
enableBreadcrumb: {
get: function() {
return this.$store.state.settings.enableBreadcrumb
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableBreadcrumb': newValue
})
}
},
showCopyright: {
get: function() {
return this.$store.state.settings.showCopyright
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'showCopyright': newValue
})
}
},
enableNavSearch: {
get: function() {
return this.$store.state.settings.enableNavSearch
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableNavSearch': newValue
})
}
},
enableFullscreen: {
get: function() {
return this.$store.state.settings.enableFullscreen
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableFullscreen': newValue
})
}
},
enablePageReload: {
get: function() {
return this.$store.state.settings.enablePageReload
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enablePageReload': newValue
})
}
},
enableProgress: {
get: function() {
return this.$store.state.settings.enableProgress
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableProgress': newValue
})
}
},
enableDynamicTitle: {
get: function() {
return this.$store.state.settings.enableDynamicTitle
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableDynamicTitle': newValue
})
}
},
enableDashboard: {
get: function() {
return this.$store.state.settings.enableDashboard
},
set: function(newValue) {
this.$store.commit('settings/updateThemeSetting', {
'enableDashboard': newValue
})
}
}
set: function(newValue) {
store.commit('menu/switchHeaderActived', 0)
store.commit('settings/updateThemeSetting', {
'menuMode': newValue
})
store.state.settings.menuMode !== 'single' && store.commit('menu/setHeaderActived', route.fullPath)
}
})
const elementSize = computed({
get: function() {
return store.state.settings.elementSize
},
mounted() {
this.$eventBus.on('global-theme-toggle', () => {
this.isShow = !this.isShow
set: function(newValue) {
proxy.$ELEMENT.size = newValue
store.commit('settings/updateThemeSetting', {
'elementSize': newValue
})
reload()
}
})
const enableSidebarCollapse = computed({
get: function() {
return store.state.settings.enableSidebarCollapse
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableSidebarCollapse': newValue
})
}
}
})
const sidebarCollapse = computed({
get: function() {
return store.state.settings.sidebarCollapse
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'sidebarCollapse': newValue
})
}
})
const switchSidebarAndPageJump = computed({
get: function() {
return store.state.settings.switchSidebarAndPageJump
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'switchSidebarAndPageJump': newValue
})
}
})
const sidebarUniqueOpened = computed({
get: function() {
return store.state.settings.sidebarUniqueOpened
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'sidebarUniqueOpened': newValue
})
}
})
const topbarFixed = computed({
get: function() {
return store.state.settings.topbarFixed
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'topbarFixed': newValue
})
}
})
const enableBreadcrumb = computed({
get: function() {
return store.state.settings.enableBreadcrumb
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableBreadcrumb': newValue
})
}
})
const showCopyright = computed({
get: function() {
return store.state.settings.showCopyright
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'showCopyright': newValue
})
}
})
const enableNavSearch = computed({
get: function() {
return store.state.settings.enableNavSearch
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableNavSearch': newValue
})
}
})
const enableFullscreen = computed({
get: function() {
return store.state.settings.enableFullscreen
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableFullscreen': newValue
})
}
})
const enablePageReload = computed({
get: function() {
return store.state.settings.enablePageReload
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enablePageReload': newValue
})
}
})
const enableProgress = computed({
get: function() {
return store.state.settings.enableProgress
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableProgress': newValue
})
}
})
const enableDynamicTitle = computed({
get: function() {
return store.state.settings.enableDynamicTitle
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableDynamicTitle': newValue
})
}
})
const enableDashboard = computed({
get: function() {
return store.state.settings.enableDashboard
},
set: function(newValue) {
store.commit('settings/updateThemeSetting', {
'enableDashboard': newValue
})
}
})
onMounted(() => {
proxy.$eventBus.on('global-theme-toggle', () => {
isShow.value = !isShow.value
})
})
</script>
<style lang="scss" scoped>

View File

@ -25,57 +25,51 @@
</div>
</template>
<script>
<script setup>
import { compile } from 'path-to-regexp'
import { deepClone } from '@/util'
import UserMenu from '../UserMenu/index.vue'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
export default {
name: 'Topbar',
components: {
UserMenu
},
data() {
return {
scrollTop: 0
}
},
computed: {
breadcrumbList() {
let breadcrumbList = []
if (this.$store.state.settings.enableDashboard) {
breadcrumbList.push({
path: '/dashboard',
title: this.$store.state.settings.dashboardTitle
})
}
if (this.$route.meta.breadcrumbNeste) {
this.$route.meta.breadcrumbNeste.map((item, index) => {
let tmpItem = deepClone(item)
if (index != 0) {
tmpItem.path = `${this.$route.meta.breadcrumbNeste[0].path}/${item.path}`
}
breadcrumbList.push(tmpItem)
})
}
return breadcrumbList
}
},
mounted() {
window.addEventListener('scroll', this.onScroll)
},
unmounted() {
window.removeEventListener('scroll', this.onScroll)
},
methods: {
pathCompile(path) {
let toPath = compile(path)
return toPath(this.$route.params)
},
onScroll() {
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
}
const store = useStore()
const route = useRoute()
const breadcrumbList = computed(() => {
let breadcrumbList = []
if (store.state.settings.enableDashboard) {
breadcrumbList.push({
path: '/dashboard',
title: store.state.settings.dashboardTitle
})
}
if (route.meta.breadcrumbNeste) {
route.meta.breadcrumbNeste.map((item, index) => {
let tmpItem = deepClone(item)
if (index != 0) {
tmpItem.path = `${route.meta.breadcrumbNeste[0].path}/${item.path}`
}
breadcrumbList.push(tmpItem)
})
}
return breadcrumbList
})
const scrollTop = ref(0)
onMounted(() => {
window.addEventListener('scroll', onScroll)
})
onUnmounted(() => {
window.removeEventListener('scroll', onScroll)
})
function onScroll() {
scrollTop.value = document.documentElement.scrollTop || document.body.scrollTop
}
function pathCompile(path) {
let toPath = compile(path)
return toPath(route.params)
}
</script>

View File

@ -37,60 +37,59 @@
</div>
</template>
<script>
<script setup>
import screenfull from 'screenfull'
import { computed, inject, onBeforeUnmount, onMounted, ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
export default {
name: 'UserMenu',
inject: ['reload'],
data() {
return {
isFullscreenEnable: screenfull.isEnabled,
isFullscreen: false
}
},
mounted() {
if (screenfull.isEnabled) {
screenfull.on('change', this.fullscreenChange)
}
},
beforeUnmount() {
if (screenfull.isEnabled) {
screenfull.off('change', this.fullscreenChange)
}
},
methods: {
fullscreen() {
screenfull.toggle()
},
fullscreenChange() {
this.isFullscreen = screenfull.isFullscreen
},
userCommand(command) {
switch (command) {
case 'dashboard':
this.$router.push({
name: 'dashboard'
})
break
case 'setting':
this.$router.push({
name: 'personalSetting'
})
break
case 'logout':
this.$store.dispatch('user/logout').then(() => {
this.$router.push({
name: 'login'
})
})
break
}
},
pro() {
window.open(`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/vue3/pro`, 'top')
}
const reload = inject('reload')
const store = useStore()
const router = useRouter()
const isFullscreenEnable = computed(() => screenfull.isEnabled)
const isFullscreen = ref(false)
onMounted(() => {
if (isFullscreenEnable.value) {
screenfull.on('change', fullscreenChange)
}
})
onBeforeUnmount(() => {
if (isFullscreenEnable.value) {
screenfull.off('change', fullscreenChange)
}
})
function fullscreen() {
screenfull.toggle()
}
function fullscreenChange() {
isFullscreen.value = screenfull.isFullscreen
}
function userCommand(command) {
switch (command) {
case 'dashboard':
router.push({
name: 'dashboard'
})
break
case 'setting':
router.push({
name: 'personalSetting'
})
break
case 'logout':
store.dispatch('user/logout').then(() => {
router.push({
name: 'login'
})
})
break
}
}
function pro() {
window.open(`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/vue3/pro`, 'top')
}
</script>