vben
2021-01-11 3ad1a4f5a69b4242d55e6bc17aceab7279241e14
提交 | 用户 | age
a65ad9 1 <template>
V 2   <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`">
3     <span :class="[prefixCls, `${prefixCls}--${theme}`]">
4       <img :class="`${prefixCls}__header`" src="/@/assets/images/header.jpg" />
5       <span :class="`${prefixCls}__info`">
6         <span :class="`${prefixCls}__name anticon`">{{ getUserInfo.realName }}</span>
7       </span>
8     </span>
9
10     <template #overlay>
11       <Menu @click="handleMenuClick">
3ad1a4 12         <MenuItem
V 13           key="doc"
14           :text="t('layout.header.dropdownItemDoc')"
15           icon="gg:loadbar-doc"
16           v-if="getShowDoc"
17         />
18         <MenuDivider />
a65ad9 19         <MenuItem
V 20           key="loginOut"
21           :text="t('layout.header.dropdownItemLoginOut')"
22           icon="carbon:power"
23         />
24       </Menu>
25     </template>
26   </Dropdown>
27 </template>
28 <script lang="ts">
29   // components
30   import { Dropdown, Menu } from 'ant-design-vue';
31
32   import { defineComponent, computed } from 'vue';
33
34   // res
35
36   import Icon from '/@/components/Icon/index';
37
38   import { userStore } from '/@/store/modules/user';
39
40   import { DOC_URL } from '/@/settings/siteSetting';
41
42   import { openWindow } from '/@/utils';
43
44   import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
45   import { useI18n } from '/@/hooks/web/useI18n';
46
47   import { useDesign } from '/@/hooks/web/useDesign';
48   import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
49   import { propTypes } from '/@/utils/propTypes';
50
51   type MenuEvent = 'loginOut' | 'doc';
52
53   export default defineComponent({
54     name: 'UserDropdown',
55     components: {
56       Dropdown,
57       Menu,
58       MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
59       MenuDivider: Menu.Divider,
60       Icon,
61     },
62     props: {
63       theme: propTypes.oneOf(['dark', 'light']),
64     },
65     setup() {
66       const { prefixCls } = useDesign('header-user-dropdown');
67       const { t } = useI18n();
68       const { getShowDoc } = useHeaderSetting();
69
70       const getUserInfo = computed(() => {
71         const { realName = '', desc } = userStore.getUserInfoState || {};
72         return { realName, desc };
73       });
74
75       //  login out
76       function handleLoginOut() {
77         userStore.confirmLoginOut();
78       }
79
80       // open doc
81       function openDoc() {
82         openWindow(DOC_URL);
83       }
84
85       function handleMenuClick(e: { key: MenuEvent }) {
86         switch (e.key) {
87           case 'loginOut':
88             handleLoginOut();
89             break;
90           case 'doc':
91             openDoc();
92             break;
93         }
94       }
95
96       return {
97         prefixCls,
98         t,
99         getUserInfo,
100         handleMenuClick,
101         getShowDoc,
102       };
103     },
104   });
105 </script>
106 <style lang="less">
107   @prefix-cls: ~'@{namespace}-header-user-dropdown';
108
109   .@{prefix-cls} {
110     display: flex;
111     height: @header-height;
112     min-width: 100px;
113     padding: 0 0 0 10px;
114     padding-right: 10px;
115     overflow: hidden;
116     font-size: 12px;
117     cursor: pointer;
118     align-items: center;
119
120     &:hover {
121       background: @header-light-bg-hover-color;
122     }
123
124     img {
125       width: 26px;
126       height: 26px;
127       margin-right: 12px;
128     }
129
130     &__header {
131       border-radius: 50%;
132     }
133
134     &__name {
135       font-size: 14px;
136     }
137
138     &--dark {
139       &:hover {
140         background: @header-dark-bg-hover-color;
141       }
142     }
143
144     &--light {
145       .@{prefix-cls}__name {
146         color: @text-color-base;
147       }
148
149       .@{prefix-cls}__desc {
150         color: @header-light-desc-color;
151       }
152     }
153
154     &-dropdown-overlay {
155       .ant-dropdown-menu-item {
156         min-width: 160px;
157       }
158     }
159   }
160 </style>