@@ -24,7 +24,8 @@ const tagsViewStore = useTagsViewStore(); | |||
/* 50= navbar 50 */ | |||
min-height: calc(100vh - 50px); | |||
overflow: hidden; | |||
background-color: var(--el-bg-color-page); | |||
// background-color: var(--el-bg-color-page); | |||
background-color: #000; | |||
} | |||
.fixed-header + .app-main { | |||
@@ -1,4 +1,5 @@ | |||
<script setup lang="ts"> | |||
import { watch, ref } from "vue"; | |||
import { storeToRefs } from "pinia"; | |||
import { RouteLocationRaw, useRoute, useRouter } from "vue-router"; | |||
import { useAppStore } from "@/store/modules/app"; | |||
@@ -49,41 +50,53 @@ function logout() { | |||
function routerTo() { | |||
router.push("/myAccount"); | |||
} | |||
// 当前路由的名字 | |||
const routeName = ref(route.meta.name); | |||
watch( | |||
() => route.meta.name, | |||
(newName) => { | |||
routeName.value = newName; | |||
} | |||
); | |||
</script> | |||
<template> | |||
<!-- 顶部导航栏 --> | |||
<div class="navbar"> | |||
<div class="myNavbar"> | |||
<!-- 左侧面包屑 --> | |||
<div class="flex"> | |||
<div class="flex" v-if="false"> | |||
<hamburger | |||
:is-active="appStore.sidebar.opened" | |||
@toggleClick="toggleSideBar" | |||
/> | |||
<breadcrumb /> | |||
</div> | |||
<!-- 右侧导航设置 --> | |||
<div class="flex"> | |||
<div class="flex" v-if="false"> | |||
<!-- 导航栏设置(窄屏隐藏)--> | |||
<div class="setting-container" v-if="device !== 'mobile'"> | |||
<!--全屏 --> | |||
<div class="setting-item" @click="toggle"> | |||
<div class="setting-item" @click="toggle" v-if="false"> | |||
<svg-icon | |||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" | |||
/> | |||
</div> | |||
<!-- 布局大小 --> | |||
<el-tooltip content="布局大小" effect="dark" placement="bottom"> | |||
<el-tooltip | |||
content="布局大小" | |||
effect="dark" | |||
placement="bottom" | |||
v-if="false" | |||
> | |||
<size-select class="setting-item" /> | |||
</el-tooltip> | |||
<!--语言选择--> | |||
<lang-select class="setting-item" /> | |||
<lang-select class="setting-item" v-if="false" /> | |||
</div> | |||
<!-- 用户头像 --> | |||
<span @click="routerTo">个人账户</span> | |||
<el-dropdown trigger="click"> | |||
<el-dropdown trigger="click" v-if="false"> | |||
<div class="avatar-container"> | |||
<img :src="userStore.avatar + '?imageView2/1/w/80/h/80'" /> | |||
<i-ep-caret-bottom class="w-3 h-3" /> | |||
@@ -109,6 +122,11 @@ function routerTo() { | |||
</template> | |||
</el-dropdown> | |||
</div> | |||
<!-- 显示的,以上代码作废 --> | |||
<div style="position: absolute; left: 30px">{{ routeName }}</div> | |||
<div class="avatar"></div> | |||
<div @click="routerTo">个人账户</div> | |||
<div @click="logout" style="margin-left: 10px">退出登录</div> | |||
</div> | |||
</template> | |||
@@ -154,4 +172,24 @@ function routerTo() { | |||
} | |||
} | |||
} | |||
// 代替原来的navbar | |||
.myNavbar { | |||
display: flex; | |||
align-items: center; | |||
justify-content: flex-end; | |||
height: 50px; | |||
padding: 0 20px; | |||
color: #fff; | |||
background-color: #fff; | |||
background-color: #000; | |||
box-shadow: 0 0 1px #0003; | |||
.avatar { | |||
width: 30px; | |||
height: 30px; | |||
margin-right: 5px; | |||
background-color: red; | |||
border-radius: 50%; | |||
} | |||
} | |||
</style> |
@@ -1,13 +1,13 @@ | |||
<script lang="ts" setup> | |||
import { useSettingsStore } from '@/store/modules/settings'; | |||
import { useSettingsStore } from "@/store/modules/settings"; | |||
const settingsStore = useSettingsStore(); | |||
defineProps({ | |||
collapse: { | |||
type: Boolean, | |||
required: true | |||
} | |||
required: true, | |||
}, | |||
}); | |||
const logo = ref(new URL(`../../../assets/logo.png`, import.meta.url).href); | |||
@@ -19,25 +19,33 @@ const logo = ref(new URL(`../../../assets/logo.png`, import.meta.url).href); | |||
<router-link | |||
v-if="collapse" | |||
key="collapse" | |||
class="h-full w-full flex items-center justify-center" | |||
class="h-full w-full flex items-center justify-center left-top-box" | |||
to="/" | |||
> | |||
<img v-if="settingsStore.sidebarLogo" :src="logo" class="w-5 h-5" /> | |||
<span v-else class="ml-3 text-white text-sm font-bold" | |||
>vue3-element-admin</span | |||
> | |||
<!-- <img | |||
v-if="settingsStore.sidebarLogo" | |||
src="../../../assets/img/left-top-logo.png" | |||
class="w-5 h-5" | |||
/> --> | |||
<img | |||
v-if="settingsStore.sidebarLogo" | |||
src="../../../assets/img/left-top-logo.png" | |||
/> | |||
<span v-else class="ml-3 text-white text-sm font-bold"></span> | |||
</router-link> | |||
<router-link | |||
v-else | |||
key="expand" | |||
class="h-full w-full flex items-center justify-center" | |||
class="h-full w-full flex items-center justify-center left-top-box" | |||
to="/" | |||
> | |||
<img v-if="settingsStore.sidebarLogo" :src="logo" class="w-5 h-5" /> | |||
<span class="ml-3 text-white text-sm font-bold" | |||
>vue3-element-admin</span | |||
> | |||
<img | |||
v-if="settingsStore.sidebarLogo" | |||
src="../../../assets/img/left-top-logo.png" | |||
class="left-top-logo" | |||
/> | |||
<span class="ml-3 text-white text-sm font-bold"></span> | |||
</router-link> | |||
</transition> | |||
</div> | |||
@@ -45,6 +53,17 @@ const logo = ref(new URL(`../../../assets/logo.png`, import.meta.url).href); | |||
<style lang="scss" scoped> | |||
// https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component | |||
.left-top-box { | |||
background-color: #000; | |||
} | |||
.left-top-logo { | |||
width: 180px; | |||
height: 40px; | |||
padding: 5px 0 0 10px; | |||
} | |||
.sidebarLogoFade-enter-active { | |||
transition: opacity 2s; | |||
} | |||
@@ -1,5 +1,5 @@ | |||
<script setup lang="ts"> | |||
import { useRoute } from "vue-router"; | |||
import { RouteLocationRaw, useRoute, useRouter } from "vue-router"; | |||
import SidebarItem from "./SidebarItem.vue"; | |||
import Logo from "./Logo.vue"; | |||
@@ -10,19 +10,48 @@ import { useAppStore } from "@/store/modules/app"; | |||
import { storeToRefs } from "pinia"; | |||
import variables from "@/styles/variables.module.scss"; | |||
// 静态路由 | |||
import { constantRoutes } from "@/router"; | |||
const settingsStore = useSettingsStore(); | |||
const permissionStore = usePermissionStore(); | |||
const appStore = useAppStore(); | |||
const { sidebarLogo } = storeToRefs(settingsStore); | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
function routerTo(url: RouteLocationRaw) { | |||
router.push(url); | |||
} | |||
</script> | |||
<template> | |||
<!-- 左侧菜单 --> | |||
<div :class="{ 'has-logo': sidebarLogo }"> | |||
<logo v-if="sidebarLogo" :collapse="!appStore.sidebar.opened" /> | |||
<el-scrollbar> | |||
<div class="myRouter"> | |||
<div class="myRouter-item" @click="routerTo('/createVideo')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
</div> | |||
创作视频 | |||
</div> | |||
<div class="myRouter-item" @click="routerTo('/myCreating')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-menu /></el-icon> | |||
</div> | |||
我的视频 | |||
</div> | |||
<div class="myRouter-item pricing" @click="routerTo('/myStore')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-Goods /></el-icon> | |||
</div> | |||
商店 | |||
</div> | |||
</div> | |||
<!-- <el-scrollbar> | |||
<el-menu | |||
style="background-color: #000000" | |||
:default-active="route.path" | |||
:collapse="!appStore.sidebar.opened" | |||
:background-color="variables.menuBg" | |||
@@ -40,6 +69,76 @@ const route = useRoute(); | |||
:is-collapse="!appStore.sidebar.opened" | |||
/> | |||
</el-menu> | |||
</el-scrollbar> | |||
</el-scrollbar> --> | |||
</div> | |||
</template> | |||
<style lang="scss" scoped> | |||
.myRouter { | |||
position: relative; | |||
height: calc(100% - 50px); | |||
padding: 200px 20px 0; | |||
color: #fff; | |||
&-item { | |||
display: flex; | |||
width: 100%; | |||
height: 50px; | |||
padding-left: 20px; | |||
font-size: 20px; | |||
font-weight: 500; | |||
line-height: 50px; | |||
text-align: center; | |||
cursor: pointer; | |||
border-bottom: 2px solid #fff; | |||
.icon { | |||
width: 40px; | |||
height: 40px; | |||
color: #fff; | |||
border-radius: 50%; | |||
.el-icon { | |||
width: 25px; | |||
height: 25px; | |||
font-size: 25px; | |||
color: #fff; | |||
text-align: center; | |||
vertical-align: sub; | |||
} | |||
} | |||
&:hover { | |||
color: #000; | |||
background-color: #fff; | |||
.el-icon { | |||
color: #000; | |||
} | |||
} | |||
} | |||
.pricing { | |||
position: absolute; | |||
bottom: 20px; | |||
width: calc(100% - 40px); | |||
text-align: center; | |||
} | |||
} | |||
:deep(.el-sub-menu__title) { | |||
background-color: #000 !important; | |||
} | |||
:deep(.el-menu-item) { | |||
div { | |||
background-color: #000 !important; | |||
} | |||
background-color: #000 !important; | |||
} | |||
:deep(.el-menu-item.is-active) { | |||
color: #fff; | |||
} | |||
</style> |
@@ -31,8 +31,13 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
path: "createVideo", | |||
component: () => import("@/views/createVideo/index.vue"), | |||
name: "createVideo", | |||
meta: { title: "createVideo", icon: "homepage", affix: true }, | |||
} | |||
meta: { | |||
title: "createVideo", | |||
icon: "homepage", | |||
affix: true, | |||
name: "创作视频", | |||
}, | |||
}, | |||
], | |||
}, | |||
// 视频列表 | |||
@@ -45,8 +50,13 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
path: "myCreating", | |||
component: () => import("@/views/myCreating/index.vue"), | |||
name: "myCreating", | |||
meta: { title: "myCreating", icon: "homepage", affix: true }, | |||
} | |||
meta: { | |||
title: "myCreating", | |||
icon: "homepage", | |||
affix: true, | |||
name: "我的视频", | |||
}, | |||
}, | |||
], | |||
}, | |||
// 个人账户 | |||
@@ -59,36 +69,52 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
path: "myAccount", | |||
component: () => import("@/views/myAccount/index.vue"), | |||
name: "myAccount", | |||
meta: { title: "myAccount", icon: "homepage", affix: true }, | |||
} | |||
meta: { | |||
title: "myAccount", | |||
icon: "homepage", | |||
affix: true, | |||
name: "个人账户", | |||
}, | |||
}, | |||
], | |||
}, | |||
// 商店 | |||
{ | |||
path: "/dashboard", | |||
path: "/", | |||
component: Layout, | |||
redirect: "/dashboard", | |||
redirect: "/myStore", | |||
children: [ | |||
{ | |||
path: "dashboard", | |||
component: () => import("@/views/dashboard/index.vue"), | |||
name: "Dashboard", | |||
meta: { title: "dashboard", icon: "homepage", affix: true }, | |||
}, | |||
{ | |||
path: "401", | |||
component: () => import("@/views/error-page/401.vue"), | |||
meta: { hidden: true }, | |||
}, | |||
{ | |||
path: "404", | |||
component: () => import("@/views/error-page/404.vue"), | |||
meta: { hidden: true }, | |||
path: "myStore", | |||
component: () => import("@/views/myStore/index.vue"), | |||
name: "myStore", | |||
meta: { title: "myStore", icon: "homepage", affix: true, name: "商店" }, | |||
}, | |||
], | |||
}, | |||
// { | |||
// path: "/dashboard", | |||
// component: Layout, | |||
// redirect: "/dashboard", | |||
// children: [ | |||
// { | |||
// path: "dashboard", | |||
// component: () => import("@/views/dashboard/index.vue"), | |||
// name: "Dashboard", | |||
// meta: { title: "dashboard", icon: "homepage", affix: true }, | |||
// }, | |||
// { | |||
// path: "401", | |||
// component: () => import("@/views/error-page/401.vue"), | |||
// meta: { hidden: true }, | |||
// }, | |||
// { | |||
// path: "404", | |||
// component: () => import("@/views/error-page/404.vue"), | |||
// meta: { hidden: true }, | |||
// }, | |||
// ], | |||
// }, | |||
// 外部链接 | |||
/*{ | |||
@@ -43,8 +43,8 @@ interface DefaultSettings { | |||
const defaultSettings: DefaultSettings = { | |||
title: "vue3-element-admin", | |||
showSettings: true, | |||
tagsView: true, | |||
showSettings: false, | |||
tagsView: false, | |||
fixedHeader: false, | |||
sidebarLogo: true, | |||
layout: "left", | |||
@@ -4,6 +4,7 @@ import { useStorage } from "@vueuse/core"; | |||
export const useSettingsStore = defineStore("setting", () => { | |||
// state | |||
const tagsView = useStorage<boolean>("tagsView", defaultSettings.tagsView); | |||
const showSettings = ref<boolean>(defaultSettings.showSettings); | |||
@@ -37,6 +37,8 @@ | |||
} | |||
&.has-logo { | |||
background-color: #000; | |||
.el-scrollbar { | |||
height: calc(100% - 50px); | |||
} | |||
@@ -4,10 +4,15 @@ | |||
--menuBg: #304156; | |||
--menuText: #bfcbd9; | |||
--menuActiveText: #409eff; | |||
--menuHover: #263445; | |||
--subMenuBg: #1f2d3d; | |||
// 左侧菜单鼠标经过颜色 | |||
--menuHover: #000; | |||
// --menuHover: #263445; | |||
// 左侧子菜单颜色 | |||
--subMenuBg: #000; | |||
// --subMenuBg: #1f2d3d; | |||
--subMenuActiveText: #f4f4f5; | |||
--subMenuHover: #001528; | |||
// --subMenuHover: #001528; | |||
--subMenuHover: #000; | |||
} | |||
$menuBg: var(--menuBg); | |||
@@ -5,6 +5,7 @@ declare global { | |||
const ElForm: typeof import("element-plus/es")["ElForm"]; | |||
const ElMessage: typeof import("element-plus/es")["ElMessage"]; | |||
const ElMessageBox: typeof import("element-plus/es")["ElMessageBox"]; | |||
const ElTree: typeof import("element-plus/es")["ElTree"]; | |||
const asyncComputed: typeof import("@vueuse/core")["asyncComputed"]; | |||
const autoResetRef: typeof import("@vueuse/core")["autoResetRef"]; | |||
const computed: typeof import("vue")["computed"]; | |||
@@ -278,6 +279,7 @@ declare module "vue" { | |||
readonly ElMessageBox: UnwrapRef< | |||
typeof import("element-plus/es")["ElMessageBox"] | |||
>; | |||
readonly ElTree: UnwrapRef<typeof import("element-plus/es")["ElTree"]>; | |||
readonly asyncComputed: UnwrapRef< | |||
typeof import("@vueuse/core")["asyncComputed"] | |||
>; | |||
@@ -11,6 +11,8 @@ declare module '@vue/runtime-core' { | |||
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] | |||
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] | |||
ElButton: typeof import('element-plus/es')['ElButton'] | |||
ElCard: typeof import('element-plus/es')['ElCard'] | |||
ElCol: typeof import('element-plus/es')['ElCol'] | |||
ElDialog: typeof import('element-plus/es')['ElDialog'] | |||
ElDivider: typeof import('element-plus/es')['ElDivider'] | |||
ElDropdown: typeof import('element-plus/es')['ElDropdown'] | |||
@@ -20,17 +22,26 @@ declare module '@vue/runtime-core' { | |||
ElFormItem: typeof import('element-plus/es')['ElFormItem'] | |||
ElIcon: typeof import('element-plus/es')['ElIcon'] | |||
ElInput: typeof import('element-plus/es')['ElInput'] | |||
ElLink: typeof import('element-plus/es')['ElLink'] | |||
ElMenu: typeof import('element-plus/es')['ElMenu'] | |||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] | |||
ElOption: typeof import('element-plus/es')['ElOption'] | |||
ElPagination: typeof import('element-plus/es')['ElPagination'] | |||
ElRadio: typeof import('element-plus/es')['ElRadio'] | |||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | |||
ElRow: typeof import('element-plus/es')['ElRow'] | |||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] | |||
ElSelect: typeof import('element-plus/es')['ElSelect'] | |||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] | |||
ElSwitch: typeof import('element-plus/es')['ElSwitch'] | |||
ElTable: typeof import('element-plus/es')['ElTable'] | |||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | |||
ElTabPane: typeof import('element-plus/es')['ElTabPane'] | |||
ElTabs: typeof import('element-plus/es')['ElTabs'] | |||
ElTooltip: typeof import('element-plus/es')['ElTooltip'] | |||
ElTree: typeof import('element-plus/es')['ElTree'] | |||
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] | |||
ElUpload: typeof import('element-plus/es')['ElUpload'] | |||
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | |||
Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | |||
IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | |||
@@ -39,8 +50,15 @@ declare module '@vue/runtime-core' { | |||
IEpDelete: typeof import('~icons/ep/delete')['default'] | |||
IEpDownload: typeof import('~icons/ep/download')['default'] | |||
IEpEdit: typeof import('~icons/ep/edit')['default'] | |||
IEpGoods: typeof import('~icons/ep/goods')['default'] | |||
IEpMenu: typeof import('~icons/ep/menu')['default'] | |||
IEpPlus: typeof import('~icons/ep/plus')['default'] | |||
IEpRefresh: typeof import('~icons/ep/refresh')['default'] | |||
IEpRefreshLeft: typeof import('~icons/ep/refresh-left')['default'] | |||
IEpSearch: typeof import('~icons/ep/search')['default'] | |||
IEpSetting: typeof import('~icons/ep/setting')['default'] | |||
IEpTop: typeof import('~icons/ep/top')['default'] | |||
IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default'] | |||
IEpVideoPlay: typeof import('~icons/ep/video-play')['default'] | |||
LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | |||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | |||
@@ -53,4 +71,7 @@ declare module '@vue/runtime-core' { | |||
SvgIcon: typeof import('./../components/SvgIcon/index.vue')['default'] | |||
WangEditor: typeof import('./../components/WangEditor/index.vue')['default'] | |||
} | |||
export interface ComponentCustomProperties { | |||
vLoading: typeof import('element-plus/es')['ElLoadingDirective'] | |||
} | |||
} |
@@ -156,9 +156,10 @@ let languageOptions = reactive([ | |||
<style lang="scss" scoped> | |||
.page { | |||
// height: calc(100vh - 84px); | |||
height: 844px; | |||
height: 887px; | |||
padding: 20px 0 0 40px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
} | |||
.left { | |||
@@ -79,10 +79,11 @@ | |||
<script setup></script> | |||
<style lang="scss" scoped> | |||
.page { | |||
height: 844px; | |||
height: 887px; | |||
padding: 20px 0 0 20px; | |||
// height: calc(100vh - 84px); | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
} | |||
.left { | |||
@@ -96,9 +96,11 @@ function mouseenter(item) { | |||
<style lang="scss" scoped> | |||
.page { | |||
height: calc(100vh - 84px); | |||
// height: calc(100vh - 84px); | |||
height: 887px; | |||
padding: 20px 0 0 20px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
} | |||
:deep(.el-input__wrapper) { | |||
@@ -0,0 +1,16 @@ | |||
<template> | |||
<div class="page">商店</div> | |||
</template> | |||
<script setup> | |||
let title = ref(""); | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
// height: calc(100vh - 84px); | |||
height: 887px; | |||
padding: 20px 0 0 20px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
} | |||
</style> |