feat: add headerNotice

This commit is contained in:
lrl 2021-11-15 23:19:00 +08:00
parent aa8005a982
commit bcf533af62
8 changed files with 238 additions and 4 deletions

View File

@ -5,6 +5,7 @@ import Hamburger from "./sidebar/hamBurger.vue";
import { useRouter, useRoute } from "vue-router";
import { storageSession } from "/@/utils/storage";
import Breadcrumb from "./sidebar/breadCrumb.vue";
import Notice from "./notice/index.vue";
import { useAppStoreHook } from "/@/store/modules/app";
import { unref, watch, getCurrentInstance } from "vue";
import { deviceDetection } from "/@/utils/deviceDetection";
@ -70,6 +71,8 @@ function translationEn() {
<Breadcrumb class="breadcrumb-container" />
<div class="vertical-header-right">
<!-- 通知 -->
<Notice />
<!-- 全屏 -->
<screenfull v-show="!deviceDetection()" />
<!-- 国际化 -->
@ -156,6 +159,12 @@ function translationEn() {
color: #000000d9;
justify-content: flex-end;
:deep(.dropdown-badge) {
&:hover {
background: #f6f6f6;
}
}
.screen-full {
cursor: pointer;

View File

@ -0,0 +1,110 @@
<script setup lang="ts">
import { ref } from "vue";
import NoticeList from "./noticeList.vue";
const loading = ref(false);
const activeName = ref("first");
function visibleChange(val) {
if (loading.value) {
loading.value = false;
return;
}
if (!val) return; //loading
loading.value = true;
setTimeout(() => {
loading.value = false;
}, 1000);
}
const noticeList = [
{
imgUrl:
"https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png",
title: "你收到了 12 份新周报",
description: "一年前"
},
{
imgUrl:
"https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png",
title: "你推荐的 前端高手 已通过第三轮面试",
description: "一年前"
},
{
imgUrl:
"https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png",
title: "这种模板可以区分多种通知类型",
description: "一年前"
}
];
const newsList = [];
const agencyList = [];
</script>
<template>
<el-dropdown
trigger="click"
placement="bottom-end"
@visible-change="visibleChange"
>
<span class="dropdown-badge">
<el-badge :value="12" :max="99">
<el-icon class="header-notice-icon"><bell /></el-icon>
</el-badge>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-tabs
v-model="activeName"
v-loading="loading"
class="dropdown-tabs"
:style="{ width: '297px' }"
>
<el-tab-pane label="通知" name="first">
<NoticeList :list="noticeList" />
</el-tab-pane>
<el-tab-pane label="消息" name="second">
<NoticeList :list="newsList" />
</el-tab-pane>
<el-tab-pane label="代办" name="third">
<NoticeList :list="agencyList" />
</el-tab-pane>
</el-tabs>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<style lang="scss" scoped>
.dropdown-badge {
display: flex;
align-items: center;
justify-content: center;
height: 48px;
width: 60px;
cursor: pointer;
.header-notice-icon {
font-size: 18px;
}
}
.dropdown-tabs {
background-color: #fff;
box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
border-radius: 4px;
:deep(.el-tabs__nav-scroll) {
display: flex;
justify-content: center;
}
:deep(.el-tabs__nav-wrap)::after {
height: 1px;
}
:deep(.el-tabs__content) {
padding: 0 24px;
}
}
</style>

View File

@ -0,0 +1,62 @@
<script setup lang="ts">
import { PropType } from "vue";
import { noticeItemType } from "../../types";
const props = defineProps({
noticeItem: {
type: Object as PropType<noticeItemType>,
default: () => {}
}
});
</script>
<template>
<div class="notice-container">
<el-avatar
:size="30"
:src="props.noticeItem.imgUrl"
class="notice-container-avatar"
></el-avatar>
<div class="notice-container-text">
<div class="container-text-title">{{ props.noticeItem.title }}</div>
<div class="container-text-description">
{{ props.noticeItem.description }}
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.notice-container {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
.notice-container-avatar {
margin-right: 16px;
}
.notice-container-text {
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
.container-text-title {
margin-bottom: 4px;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
line-height: 22px;
cursor: pointer;
}
.container-text-description {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
line-height: 22px;
}
}
}
</style>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import { PropType } from "vue";
import NoticeItem from "./noticeItem.vue";
import { noticeItemType } from "../../types";
const props = defineProps({
list: {
type: Array as PropType<Array<noticeItemType>>,
default: () => []
}
});
</script>
<template>
<div v-if="props.list.length">
<NoticeItem
v-for="(item, index) in props.list"
:noticeItem="item"
:key="index"
></NoticeItem>
</div>
<el-empty v-else description="暂无数据"></el-empty>
</template>

View File

@ -9,6 +9,7 @@ import {
} from "vue";
import { useI18n } from "vue-i18n";
import { emitter } from "/@/utils/mitt";
import Notice from "../notice/index.vue";
import { templateRef } from "@vueuse/core";
import SidebarItem from "./sidebarItem.vue";
import { algorithm } from "/@/utils/algorithm";
@ -138,6 +139,8 @@ onMounted(() => {
/>
</el-menu>
<div class="horizontal-header-right">
<!-- 通知 -->
<Notice />
<!-- 全屏 -->
<screenfull v-show="!deviceDetection()" />
<!-- 国际化 -->

View File

@ -71,3 +71,9 @@ export type themeColorsType = {
rgb: string;
themeColor: string;
};
export type noticeItemType = {
imgUrl: string;
title: string;
description: string;
};

View File

@ -36,7 +36,12 @@ import {
ElDescriptions,
ElDescriptionsItem,
ElBacktop,
ElSwitch
ElSwitch,
ElBadge,
ElTabs,
ElTabPane,
ElAvatar,
ElEmpty
} from "element-plus";
// https://element-plus.org/zh-CN/component/icon.html
@ -54,7 +59,8 @@ import {
RefreshRight,
ArrowDown,
Close,
CloseBold
CloseBold,
Bell
} from "@element-plus/icons";
const components = [
@ -93,7 +99,12 @@ const components = [
ElDescriptions,
ElDescriptionsItem,
ElBacktop,
ElSwitch
ElSwitch,
ElBadge,
ElTabs,
ElTabPane,
ElAvatar,
ElEmpty
];
// icon
export const iconComponents = [
@ -110,7 +121,8 @@ export const iconComponents = [
RefreshRight,
ArrowDown,
Close,
CloseBold
CloseBold,
Bell
];
const plugins = [ElLoading];

View File

@ -212,6 +212,15 @@
color: $subMenuActiveText;
justify-content: flex-end;
.dropdown-badge {
height: 62px;
color: $subMenuActiveText;
&:hover {
background: $menuHover;
}
}
.screen-full {
cursor: pointer;