tagpop.nvue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <view class="tagpopcon" >
  3. <view class="tagpopcon-title" :style="{width:width+'px'}">选择标签</view>
  4. <list class="tagpop-box" :show-scrollbar="true" :style="{height:height+'px'}" :scrollable="true">
  5. <cell v-for="(item,index) in tags" :key="index" >
  6. <view class="tag-group">
  7. <view class="tag-label">{{ item.label }}</view>
  8. <image class="close_icon" src="/static/close_icon.png" @click="closePopup"></image>
  9. <view class="child-label-box">
  10. <text
  11. class="tag-item"
  12. v-for="(it,idx) in item.children"
  13. :key="idx"
  14. :class="{'tag-item-active': it.checked}"
  15. @click="handleChooseTag(index,idx)"
  16. >{{ it.label }}</text>
  17. </view>
  18. </view>
  19. </cell>
  20. </list>
  21. </view>
  22. </template>
  23. <script>
  24. import { getTag } from "@/api/expert.js"
  25. export default {
  26. data() {
  27. return {
  28. height: 0,
  29. width: 350,
  30. tags:[]
  31. }
  32. },
  33. onLoad(){
  34. const sysInfo = uni.getSystemInfoSync()
  35. const { screenHeight, statusBarHeight, safeAreaInsets, safeArea } = sysInfo
  36. // 方法1:使用 safeAreaInsets.bottom(推荐,iOS 11+)
  37. const bottomSafeArea = safeAreaInsets?.bottom || 0
  38. this.height = screenHeight / 2 - bottomSafeArea - 20
  39. this.width = uni.getSystemInfoSync().screenWidth
  40. this.getTags()
  41. },
  42. methods: {
  43. getTags() {
  44. getTag().then(res => {
  45. if (res.code == 200) {
  46. this.tags = res.data || []
  47. this.tags = this.addCheckedProperty(this.tags)
  48. uni.$emit('chooseTag',this.tags)
  49. }
  50. })
  51. },
  52. addCheckedProperty(tags) {
  53. return tags.map(tag => {
  54. // 为当前对象添加checked属性
  55. const updatedTag = {
  56. ...tag,
  57. checked: false
  58. };
  59. // 如果有子对象,递归处理
  60. if (updatedTag.children) {
  61. updatedTag.children = this.addCheckedProperty(updatedTag.children);
  62. }
  63. return updatedTag;
  64. });
  65. },
  66. handleChooseTag(index, idx) {
  67. this.tags[index].children[idx].checked = !this.tags[index].children[idx].checked
  68. uni.$emit('chooseTag',this.tags)
  69. },
  70. closePopup() {
  71. const subNVue = uni.getSubNVueById('tagpop');
  72. subNVue.hide('slide-out-bottom');
  73. },
  74. }
  75. }
  76. </script>
  77. <style scoped>
  78. .tagpopcon {
  79. background-color: #fff;
  80. border-radius: 16rpx 16rpx 0 0;
  81. padding: 24rpx;
  82. position: relative;
  83. }
  84. .tagpopcon-title {
  85. text-align: center;
  86. position: fixed;
  87. top: 0;
  88. left: 0;
  89. height: 44px;
  90. display: flex;
  91. align-items: center;
  92. flex-direction: row;
  93. justify-content: center;
  94. background-color: #fff;
  95. border-bottom: 1rpx solid #eee;
  96. }
  97. .close_icon {
  98. position: fixed;
  99. top: 10px;
  100. right: 10px;
  101. width: 22px;
  102. height: 22px;
  103. }
  104. .tagpop-box {
  105. padding-top: 44px;
  106. }
  107. .tag-label {
  108. font-size: 16px;
  109. font-weight: bold;
  110. margin-bottom: 5px;
  111. // background-color: #f7f7f7;
  112. }
  113. .child-label-box {
  114. display: flex;
  115. flex-direction: row;
  116. align-items: center;
  117. flex-wrap: wrap;
  118. }
  119. .child-label {
  120. margin: 0 16rpx 16rpx 0;
  121. }
  122. .tag-item {
  123. margin-right: 16rpx;
  124. margin-bottom: 16rpx;
  125. padding: 12rpx 24rpx;
  126. background-color: #fff;
  127. border-radius: 8rpx;
  128. border-width: 2rpx;
  129. border-style: solid;
  130. border-color: #eee;
  131. font-size: 28rpx;
  132. color: #666;
  133. }
  134. .tag-item-active {
  135. background-color: #ffe8dc;
  136. border-color: #ffe8dc;
  137. color: #FF5030;
  138. }
  139. </style>