index.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <n-dropdown
  3. trigger="hover"
  4. @select="handleSelect"
  5. :show-arrow="true"
  6. :options="options"
  7. >
  8. <div class="user-info-box">
  9. <PersonIcon v-if="fallback" />
  10. <n-avatar
  11. v-if="!fallback"
  12. round
  13. object-fit="cover"
  14. size="medium"
  15. :src="imageUrl"
  16. @error="errorHandle"
  17. />
  18. </div>
  19. </n-dropdown>
  20. </template>
  21. <script lang="ts" setup>
  22. import { h, ref } from 'vue'
  23. import { NAvatar, NText } from 'naive-ui'
  24. import { renderIcon } from '@/utils'
  25. import { openDoc, logout } from '@/utils'
  26. import { icon } from '@/plugins'
  27. const { DocumentTextIcon, ChatboxEllipsesIcon, PersonIcon, LogOutOutlineIcon } = icon.ionicons5
  28. const imageUrl = 'https://www.naiveui.com/assets/naivelogo.93278402.svg'
  29. // 是否失败
  30. const fallback = ref(false)
  31. // 用户图标渲染
  32. const renderUserInfo = () => {
  33. return h(
  34. 'div',
  35. {
  36. style: 'display: flex; align-items: center; padding: 8px 12px;'
  37. },
  38. [
  39. h(NAvatar, {
  40. round: true,
  41. style: 'margin-right: 12px;',
  42. src: imageUrl
  43. }),
  44. h('div', null, [
  45. h('div', null, [
  46. h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
  47. ])
  48. ])
  49. ]
  50. )
  51. }
  52. const options = [
  53. {
  54. label: '我的信息',
  55. key: 'info',
  56. type: 'render',
  57. render: renderUserInfo
  58. },
  59. {
  60. type: 'divider',
  61. key: 'd1'
  62. },
  63. {
  64. label: '说明文档',
  65. key: 'doc',
  66. icon: renderIcon(DocumentTextIcon)
  67. },
  68. {
  69. label: '联系我们',
  70. key: 'contact',
  71. icon: renderIcon(ChatboxEllipsesIcon)
  72. },
  73. {
  74. type: 'divider',
  75. key: 'd2'
  76. },
  77. {
  78. label: '退出登录',
  79. key: 'logout',
  80. icon: renderIcon(LogOutOutlineIcon)
  81. }
  82. ]
  83. // 图片渲染错误
  84. const errorHandle = (e: Event) => {
  85. fallback.value = true
  86. }
  87. const handleSelect = (key: string) => {
  88. switch (key) {
  89. case 'doc':
  90. openDoc()
  91. break
  92. case 'contact':
  93. openDoc()
  94. break
  95. case 'logout':
  96. logout()
  97. break
  98. }
  99. }
  100. </script>
  101. <style lang="scss" scoped>
  102. .user-info-box {
  103. cursor: pointer;
  104. transform: scale(.7);
  105. }
  106. </style>