friend.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <view class="tab-page friend">
  3. <nav-bar add search @add="onAddNewFriends" @search="showSearch = !showSearch">好友</nav-bar>
  4. <view class="nav-bar" v-if="showSearch">
  5. <view class="nav-search">
  6. <uni-search-bar v-model="searchText" radius="100" cancelButton="none"
  7. placeholder="点击搜索好友"></uni-search-bar>
  8. </view>
  9. </view>
  10. <view class="friend-tip" v-if="!hasFriends">
  11. 温馨提示:您现在还没有任何好友,快点击右上方'+'按钮添加好友吧~
  12. </view>
  13. <view class="friend-items" v-else>
  14. <up-index-list :index-list="friendIdx">
  15. <template v-for="(friends, i) in friendGroups">
  16. <up-index-item>
  17. <up-index-anchor :text="friendIdx[i] == '*' ? '在线' : friendIdx[i]"></up-index-anchor>
  18. <view v-for="(friend, idx) in friends" :key="idx">
  19. <friend-item :friend="friend"></friend-item>
  20. </view>
  21. </up-index-item>
  22. </template>
  23. </up-index-list>
  24. </view>
  25. </view>
  26. </template>
  27. <script>
  28. import { pinyin } from 'pinyin-pro';
  29. export default {
  30. data() {
  31. return {
  32. showSearch: false,
  33. searchText: ''
  34. }
  35. },
  36. methods: {
  37. onAddNewFriends() {
  38. uni.navigateTo({
  39. url: "/pages/friend/friend-add"
  40. })
  41. },
  42. firstLetter(strText) {
  43. // 使用pinyin-pro库将中文转换为拼音
  44. let pinyinOptions = {
  45. toneType: 'none', // 无声调
  46. type: 'normal' // 普通拼音
  47. };
  48. let pyText = pinyin(strText, pinyinOptions);
  49. return pyText[0];
  50. },
  51. isEnglish(character) {
  52. return /^[A-Za-z]+$/.test(character);
  53. }
  54. },
  55. computed: {
  56. friendGroupMap() {
  57. // 按首字母分组
  58. let groupMap = new Map();
  59. this.friendStore.friends.forEach((f) => {
  60. if (f.deleted || (this.searchText && !f.nickName.includes(this.searchText))) {
  61. return;
  62. }
  63. let letter = this.firstLetter(f.nickName).toUpperCase();
  64. // 非英文一律为#组
  65. if (!this.isEnglish(letter)) {
  66. letter = "#"
  67. }
  68. if (f.online) {
  69. letter = '*'
  70. }
  71. if (groupMap.has(letter)) {
  72. groupMap.get(letter).push(f);
  73. } else {
  74. groupMap.set(letter, [f]);
  75. }
  76. })
  77. // 排序
  78. let arrayObj = Array.from(groupMap);
  79. arrayObj.sort((a, b) => {
  80. // #组在最后面
  81. if (a[0] == '#' || b[0] == '#') {
  82. return b[0].localeCompare(a[0])
  83. }
  84. return a[0].localeCompare(b[0])
  85. })
  86. groupMap = new Map(arrayObj.map(i => [i[0], i[1]]));
  87. return groupMap;
  88. },
  89. friendIdx() {
  90. return Array.from(this.friendGroupMap.keys());
  91. },
  92. friendGroups() {
  93. return Array.from(this.friendGroupMap.values());
  94. },
  95. hasFriends() {
  96. return this.friendStore.friends.some(f => !f.deleted);
  97. }
  98. }
  99. }
  100. </script>
  101. <style lang="scss" scoped>
  102. .friend {
  103. position: relative;
  104. display: flex;
  105. flex-direction: column;
  106. :deep(.u-index-anchor) {
  107. height: 60rpx !important;
  108. background-color: unset !important;
  109. border-bottom: none !important;
  110. }
  111. :deep(.u-index-anchor__text) {
  112. color: $im-text-color !important;
  113. }
  114. :deep(.u-index-list__letter) {
  115. margin-top: 50px;
  116. }
  117. :deep(.u-index-list__letter__item) {
  118. width: 40rpx !important;
  119. height: 40rpx !important;
  120. }
  121. :deep(.u-index-list__letter__item__index) {
  122. font-size: $im-font-size-small !important;
  123. }
  124. .friend-tip {
  125. position: absolute;
  126. top: 400rpx;
  127. padding: 50rpx;
  128. text-align: center;
  129. line-height: 50rpx;
  130. color: $im-text-color-lighter;
  131. }
  132. .friend-items {
  133. flex: 1;
  134. padding: 0;
  135. overflow: hidden;
  136. position: relative;
  137. .scroll-bar {
  138. height: 100%;
  139. }
  140. }
  141. }
  142. </style>