HeadImage.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <div class="head-image" @click="showUserInfo($event)" :style="{ cursor: isShowUserInfo ? 'pointer' : null }">
  3. <img class="avatar-image" v-show="url" :src="url" :style="avatarImageStyle" loading="lazy" />
  4. <div class="avatar-text" v-show="!url" :style="avatarTextStyle">
  5. {{ avaterText }}</div>
  6. <div v-show="online" class="online" title="用户当前在线"></div>
  7. <slot></slot>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. name: "headImage",
  13. data() {
  14. return {
  15. colors: ["#5daa31", "#c7515a", "#e03697", "#85029b",
  16. "#c9b455", "#326eb6"]
  17. }
  18. },
  19. props: {
  20. id: {
  21. type: Number
  22. },
  23. size: {
  24. type: Number,
  25. default: 42
  26. },
  27. width: {
  28. type: Number
  29. },
  30. height: {
  31. type: Number
  32. },
  33. radius: {
  34. type: String,
  35. default: "50%"
  36. },
  37. url: {
  38. type: String
  39. },
  40. name: {
  41. type: String,
  42. default: null
  43. },
  44. online: {
  45. type: Boolean,
  46. default: false
  47. },
  48. isShowUserInfo: {
  49. type: Boolean,
  50. default: true
  51. }
  52. },
  53. methods: {
  54. showUserInfo(e) {
  55. if (!this.isShowUserInfo) return;
  56. if (this.id && this.id > 0) {
  57. this.$http({
  58. url: `/user/find/${this.id}`,
  59. method: 'get'
  60. }).then((user) => {
  61. let pos = {
  62. x: e.x + 30,
  63. y: e.y
  64. }
  65. this.$eventBus.$emit("openUserInfo", user, pos);
  66. })
  67. }
  68. },
  69. isChinese(charCode) {
  70. return charCode >= 0x4e00 && charCode <= 0x9fa5;
  71. }
  72. },
  73. computed: {
  74. avatarImageStyle() {
  75. let w = this.width ? this.width : this.size;
  76. let h = this.height ? this.height : this.size;
  77. return `width:${w}px; height:${h}px;
  78. border-radius: ${this.radius};`
  79. },
  80. avatarTextStyle() {
  81. let w = this.width ? this.width : this.size;
  82. let h = this.height ? this.height : this.size;
  83. return `width: ${w}px;height:${h}px;
  84. background: linear-gradient(145deg,#ffffff20 25%,#00000060),${this.textColor};
  85. font-size:${w * 0.4}px;
  86. border-radius: ${this.radius};`
  87. },
  88. avaterText() {
  89. if (!this.name) return '';
  90. if (this.isChinese(this.name.charCodeAt(0))) {
  91. return this.name.charAt(0)
  92. } else {
  93. return this.name.charAt(0).toUpperCase() + this.name.charAt(1)
  94. }
  95. },
  96. textColor() {
  97. if (!this.name) return 'fff';
  98. let hash = 0;
  99. for (var i = 0; i < this.name.length; i++) {
  100. hash += this.name.charCodeAt(i);
  101. }
  102. return this.colors[hash % this.colors.length];
  103. }
  104. }
  105. }
  106. </script>
  107. <style scoped lang="scss">
  108. .head-image {
  109. position: relative;
  110. .avatar-image {
  111. position: relative;
  112. overflow: hidden;
  113. display: block;
  114. }
  115. .avatar-text {
  116. color: white;
  117. display: flex;
  118. align-items: center;
  119. justify-content: center;
  120. }
  121. .online {
  122. position: absolute;
  123. right: -5px;
  124. bottom: 0;
  125. width: 12px;
  126. height: 12px;
  127. background: limegreen;
  128. border-radius: 50%;
  129. border: 2px solid white;
  130. }
  131. }
  132. </style>