index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <script setup lang="ts">
  2. // const searchValue = ref('')
  3. import bg from '@/static/image/feed-plan/bg.png'
  4. import circle from '@/static/image/feed-plan/circle.png'
  5. import message from '@/static/image/feed-plan/message.png'
  6. import ToolFun from '@/utils'
  7. interface ListItem {
  8. img: string
  9. title: string
  10. desc: string
  11. time: string
  12. }
  13. interface Item {
  14. content: string
  15. }
  16. interface DotStyle {
  17. backgroundColor: string
  18. selectedBackgroundColor: string
  19. selectedBorder: string
  20. border: string
  21. }
  22. interface TypeItem {
  23. name: string
  24. isClick: boolean
  25. }
  26. const titleName = ref<string>('喂养计划')
  27. const listModel = ref<ListItem[]>([
  28. {
  29. img: bg,
  30. title: '猫咪食物禁忌',
  31. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  32. time: '2025年1月1日',
  33. },
  34. {
  35. img: bg,
  36. title: '猫咪食物禁忌',
  37. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  38. time: '2025年1月1日',
  39. },
  40. {
  41. img: bg,
  42. title: '猫咪食物禁忌',
  43. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  44. time: '2025年1月1日',
  45. },
  46. {
  47. img: bg,
  48. title: '猫咪食物禁忌',
  49. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  50. time: '2025年1月1日',
  51. },
  52. {
  53. img: bg,
  54. title: '猫咪食物禁忌',
  55. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  56. time: '2025年1月1日',
  57. },
  58. {
  59. img: bg,
  60. title: '猫咪食物禁忌',
  61. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  62. time: '2025年1月1日',
  63. },
  64. {
  65. img: bg,
  66. title: '猫咪食物禁忌',
  67. desc: '1 饮食不慎 2 寄生虫\n 3 病毒感染 4 细菌和毒素感染',
  68. time: '2025年1月1日',
  69. },
  70. ])
  71. const safeHeight = ToolFun.getSafeHeight()
  72. const searchValue = ref<string>('')
  73. const info = ref<Item[]>([
  74. { content: '内容 A' },
  75. { content: '内容 B' },
  76. { content: '内容 C' },
  77. ])
  78. const current = ref<number>(0)
  79. const dotStyle = ref<DotStyle>({
  80. backgroundColor: '#DCDCDC',
  81. selectedBackgroundColor: '#0052D9',
  82. selectedBorder: 'none',
  83. border: 'none',
  84. })
  85. function change(e: CustomEvent<{ current: number }>): void {
  86. current.value = e.detail.current
  87. }
  88. const typeList = ref<TypeItem[]>([
  89. { name: '趣味科普', isClick: true },
  90. { name: '科学喂养', isClick: false },
  91. { name: '科学喂养', isClick: false },
  92. { name: '科学喂养', isClick: false },
  93. ])
  94. function handleClickType(item: TypeItem) {
  95. typeList.value.forEach(i => (i.isClick = false))
  96. item.isClick = true
  97. }
  98. </script>
  99. <template>
  100. <TitleBar :title-name="titleName" />
  101. <view class="flex flex-col bg-[#F5F6F7] overflow-y-auto" :style="`height:calc(100vh - ${safeHeight}px)`">
  102. <view class="mx-[6px]">
  103. <uni-search-bar
  104. v-model="searchValue" :focus="true" bg-color="white" clear-button="auto" cancel-button="none" :radius="20"
  105. />
  106. </view>
  107. <view class="ml-4 mt-4 text-[20px] font-600">
  108. 热门推荐
  109. </view>
  110. <view class="mx-4 mt-4">
  111. <uni-swiper-dot :info="info" :current="current" field="content" mode="dot" :dots-styles="dotStyle">
  112. <swiper class="swiper-box" @change="change">
  113. <swiper-item v-for="(item, index) in info" :key="index" style="background: rgba(0, 0, 0, 0.20)">
  114. <view class="swiper-item">
  115. {{ item.content }}
  116. </view>
  117. </swiper-item>
  118. </swiper>
  119. </uni-swiper-dot>
  120. </view>
  121. <view class="ml-4 mt-5 text-[20px] font-600">
  122. 养宠贴士
  123. </view>
  124. <view class="mx-4">
  125. <scroll-view class="scroll mt-2" scroll-x="auto">
  126. <view class="group h-[40px] mt-1">
  127. <view
  128. v-for="(item, index) in typeList" :key="index" class="item h-[30px] w-[28%] rounded-15px relative" style="border: 1px solid #E7E7E7"
  129. @tap="handleClickType(item)"
  130. >
  131. <view v-if="item.isClick">
  132. <image :src="message" class="absolute w-full" style="height: calc(100% + 5px)" />
  133. <image :src="circle" class="w-[14px] h-[14px] absolute right-2 top-[-4px]" />
  134. </view>
  135. <view class="w-full h-full flex items-center justify-center text-[14px] z-20 relative font-600" :class="item.isClick ? 'type_select_span' : 'type_span'">
  136. {{ item.name }}
  137. </view>
  138. </view>
  139. </view>
  140. </scroll-view>
  141. </view>
  142. <view
  143. v-for="(item, index) in listModel" :key="index" class="bg-[white] rounded-md shadow-lg mx-4 mb-4 w-[calc(100% - 32px)] mt-3"
  144. >
  145. <view class="flex">
  146. <image class="w-28 h-28 rounded-l-md" :src="item.img" />
  147. <view class="p-4">
  148. <view class="text-[14px]">
  149. {{ item.title }}
  150. </view>
  151. <view class="mt-2 text-[11px] text-[#999] whitespace-pre-line">
  152. {{ item.desc }}
  153. </view>
  154. <view class="mt-3 text-[10px] text-[#D8D8D8]">
  155. {{ item.time }}
  156. </view>
  157. </view>
  158. </view>
  159. </view>
  160. </view>
  161. </template>
  162. <style scoped>
  163. .scroll{
  164. box-sizing: border-box;
  165. .group{
  166. white-space: nowrap;
  167. .item{
  168. display: inline-block;
  169. margin-right: 10px;
  170. }
  171. }
  172. }
  173. .type_span{
  174. color:#999
  175. }
  176. .type_select_span{
  177. color:#FFF
  178. }
  179. </style>