search-group-resources.tsx 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import {
  2. PropType,
  3. computed,
  4. defineComponent,
  5. nextTick,
  6. onMounted,
  7. reactive,
  8. ref
  9. } from 'vue';
  10. import styles from './index.module.less';
  11. import {
  12. NButton,
  13. NCarousel,
  14. NCarouselItem,
  15. NForm,
  16. NFormItem,
  17. NImage,
  18. NPopselect,
  19. NSpace
  20. } from 'naive-ui';
  21. import TheSearch from '/src/components/TheSearch';
  22. import iconSlideRight from '/src/views/prepare-lessons/images/icon-slide-right.png';
  23. export default defineComponent({
  24. name: 'search-group',
  25. props: {
  26. categoryChildList: {
  27. type: Array as PropType<any>,
  28. default: () => []
  29. },
  30. wikiCategoryId: {
  31. type: String,
  32. default: ''
  33. }
  34. },
  35. emits: ['search', 'add'],
  36. expose: ['init'],
  37. setup(props, { emit }) {
  38. // const catchStore = useCatchStore();
  39. const forms = reactive({
  40. keyword: '',
  41. wikiCategoryId: props.wikiCategoryId || '',
  42. wikiCategoryIdChild: '',
  43. childIds: [] as any,
  44. currentIndex: 0
  45. });
  46. const carouselRef = ref();
  47. const onSearch = () => {
  48. emit('search', forms);
  49. };
  50. const selectChildObj = (item: any, index: number) => {
  51. const obj: any = {};
  52. item?.forEach((child: any) => {
  53. if (child.id === forms.wikiCategoryIdChild) {
  54. obj.selected = true;
  55. obj.name = child.name;
  56. }
  57. });
  58. return obj;
  59. };
  60. const childList = computed(() => {
  61. const categoryChildList = props.categoryChildList || [];
  62. const child = categoryChildList.find(
  63. (item: any) => item.id === forms.wikiCategoryId
  64. );
  65. if (child && child.childrenList.length) {
  66. child.childrenList.forEach((child: any) => {
  67. const i = child.childrenList;
  68. if (i && i.length > 0) {
  69. i.forEach((j: any) => {
  70. j.label = j.name;
  71. j.value = j.id;
  72. });
  73. i.unshift({
  74. label: '全部',
  75. value: child.id,
  76. name: child.name,
  77. id: child.id
  78. });
  79. }
  80. });
  81. return (
  82. [
  83. {
  84. label: '全部',
  85. value: '',
  86. id: '',
  87. name: '全部',
  88. childrenList: []
  89. },
  90. ...child.childrenList
  91. ] || []
  92. );
  93. }
  94. return [];
  95. });
  96. const state = reactive({
  97. showSlide: false
  98. });
  99. const onChangeSlide = (type: string) => {
  100. if (type === 'left') {
  101. carouselRef.value?.prev();
  102. } else if (type === 'right') {
  103. carouselRef.value?.next();
  104. }
  105. };
  106. onMounted(() => {
  107. nextTick(() => {
  108. // 最外层宽度
  109. const carouselContainer = document.querySelector('.carouselContainer');
  110. const carouselContainerWidth =
  111. (carouselContainer &&
  112. carouselContainer.getBoundingClientRect().width) ||
  113. 0;
  114. const slideDoms = document.querySelectorAll('.n-carousel__slide');
  115. let slideWidth = 0;
  116. slideDoms.forEach(doom => {
  117. const rect = doom.getBoundingClientRect();
  118. slideWidth += rect.width;
  119. });
  120. if (slideWidth >= carouselContainerWidth) {
  121. state.showSlide = true;
  122. }
  123. });
  124. });
  125. return () => (
  126. <div class={styles.searchGroup}>
  127. <div
  128. class={[
  129. styles.searchCatatory,
  130. childList.value.length > 0 ? styles.border : ''
  131. ]}>
  132. <NSpace size="small" class={styles.btnType}>
  133. {props.categoryChildList.length > 0 ? (
  134. <NButton
  135. type={
  136. forms.wikiCategoryId === props.wikiCategoryId
  137. ? 'primary'
  138. : 'default'
  139. }
  140. secondary={
  141. forms.wikiCategoryId === props.wikiCategoryId ? false : true
  142. }
  143. round
  144. size="small"
  145. focusable={false}
  146. onClick={() => {
  147. forms.wikiCategoryId = props.wikiCategoryId;
  148. forms.wikiCategoryIdChild = '';
  149. onSearch();
  150. }}>
  151. 全部
  152. </NButton>
  153. ) : (
  154. <span></span>
  155. )}
  156. <div class={[styles.carouselGroup]}>
  157. <NCarousel
  158. ref={carouselRef}
  159. slidesPerView={'auto'}
  160. loop={false}
  161. class={[styles.carouselContainer, 'carouselContainer']}
  162. showDots={false}
  163. // spaceBetween={20}
  164. draggable={state.showSlide}
  165. currentIndex={forms.currentIndex}
  166. onUpdate:currentIndex={(val: any) => {
  167. //
  168. // if (val > forms.maxIndex) {
  169. // forms.maxIndex = val;
  170. // carouselRef.value?.to(0);
  171. // }
  172. forms.currentIndex = val;
  173. }}>
  174. {props.categoryChildList.map((item: any) => (
  175. <NCarouselItem>
  176. <NButton
  177. type={
  178. forms.wikiCategoryId === item.id ? 'primary' : 'default'
  179. }
  180. secondary={
  181. forms.wikiCategoryId === item.id ? false : true
  182. }
  183. round
  184. size="small"
  185. focusable={false}
  186. onClick={() => {
  187. forms.wikiCategoryId = item.id;
  188. onSearch();
  189. }}>
  190. {item.name}
  191. </NButton>
  192. </NCarouselItem>
  193. ))}
  194. </NCarousel>
  195. {state.showSlide && (
  196. <NSpace class={styles.swipeControll}>
  197. <div onClick={() => onChangeSlide('left')}>
  198. <NImage
  199. previewDisabled
  200. class={[
  201. styles.leftIcon
  202. // forms.currentIndex === 0 && styles.disabled
  203. ]}
  204. src={iconSlideRight}
  205. />
  206. </div>
  207. <div onClick={() => onChangeSlide('right')}>
  208. <NImage
  209. // class={
  210. // // forms.currentIndex == forms.openTableList.length - 4 &&
  211. // styles.disabled
  212. // }
  213. previewDisabled
  214. src={iconSlideRight}
  215. />
  216. </div>
  217. </NSpace>
  218. )}
  219. </div>
  220. </NSpace>
  221. <TheSearch
  222. class={styles.inputSearch}
  223. placeholder="请输入名曲鉴赏关键词"
  224. round
  225. onSearch={(val: string) => {
  226. forms.keyword = val;
  227. onSearch();
  228. }}
  229. />
  230. </div>
  231. {childList.value.length > 0 && (
  232. <div class={[styles.collapseWrap]}>
  233. <NSpace class={[styles.spaceSection]}>
  234. {childList.value.map((music: any, index: number) => (
  235. <>
  236. {music.childrenList.length > 0 ? (
  237. <NPopselect
  238. options={music.childrenList}
  239. trigger="hover"
  240. v-model:value={forms.wikiCategoryIdChild}
  241. onUpdate:value={() => {
  242. onSearch();
  243. }}
  244. key={music.id}
  245. class={styles.popSelect}>
  246. <span
  247. class={[
  248. styles.textBtn,
  249. selectChildObj(music.childrenList, index).selected &&
  250. styles.textBtnActive
  251. ]}>
  252. {selectChildObj(music.childrenList, index).name ||
  253. music.name}
  254. <i class={styles.iconArrow}></i>
  255. </span>
  256. </NPopselect>
  257. ) : (
  258. <span
  259. class={[
  260. styles.textBtn,
  261. forms.wikiCategoryIdChild === music.id &&
  262. styles.textBtnActive
  263. ]}
  264. onClick={() => {
  265. forms.wikiCategoryIdChild = music.id;
  266. onSearch();
  267. }}>
  268. {music.name}
  269. </span>
  270. )}
  271. </>
  272. ))}
  273. </NSpace>
  274. </div>
  275. )}
  276. </div>
  277. );
  278. }
  279. });