index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div
  3. class="com-main"
  4. element-loading-text="Loading"
  5. v-loading="listLoading">
  6. <div
  7. class="com-width-1400 com-margin-auto"
  8. v-loading="listLoading">
  9. <div
  10. class="select-category"
  11. v-if="cate.length">
  12. <p class="select-category-title">Select a Category</p>
  13. <ul>
  14. <li
  15. v-for="item in cate.filter(i => i.pid !== 0)"
  16. :key="item.id">
  17. <nuxt-link
  18. v-if="item.pid == 0"
  19. :to="{
  20. name: 'category-firstCategory',
  21. params: {
  22. firstCategory: item.name
  23. .replace(/\s+/g, '-')
  24. .replace('-&', '')
  25. .toLowerCase(),
  26. },
  27. }">
  28. <div class="image">
  29. <img
  30. :src="
  31. item.style && !$mediaRegExp.test(item.style)
  32. ? $OSS_PREFIX + item.style
  33. : item.style
  34. " />
  35. </div>
  36. <p>{{ item.name }}</p>
  37. </nuxt-link>
  38. <nuxt-link
  39. v-else-if="item.pid > 0 && item.parent?.pid == 0"
  40. :to="{
  41. name: 'category-firstCategory-secondCategory',
  42. params: {
  43. firstCategory: item.parent.name
  44. .replace(/\s+/g, '-')
  45. .replace('-&', '')
  46. .toLowerCase(),
  47. secondCategory: item.name
  48. .replace(/\s+/g, '-')
  49. .replace('-&', '')
  50. .toLowerCase(),
  51. },
  52. }">
  53. <div class="image">
  54. <img
  55. :src="
  56. item.style && !$mediaRegExp.test(item.style)
  57. ? $OSS_PREFIX + item.style
  58. : item.style
  59. " />
  60. </div>
  61. <p>{{ item.name }}</p>
  62. </nuxt-link>
  63. <nuxt-link
  64. v-else
  65. :to="{
  66. name: 'category-firstCategory-secondCategory-thirdCategory',
  67. params: {
  68. firstCategory: item.parent?.parent?.name
  69. .replace(/\s+/g, '-')
  70. .replace('-&', '')
  71. .toLowerCase(),
  72. secondCategory: item.parent.name
  73. .replace(/\s+/g, '-')
  74. .replace('-&', '')
  75. .toLowerCase(),
  76. thirdCategory: item.name
  77. .replace(/\s+/g, '-')
  78. .replace('-&', '')
  79. .toLowerCase(),
  80. },
  81. }">
  82. <div class="image">
  83. <img
  84. :src="
  85. item.style && !$mediaRegExp.test(item.style)
  86. ? $OSS_PREFIX + item.style
  87. : item.style
  88. " />
  89. </div>
  90. <p>{{ item.name }}</p>
  91. </nuxt-link>
  92. </li>
  93. </ul>
  94. </div>
  95. <div class="metal-hardPlastic">
  96. <div class="metal-title">
  97. <p>
  98. Search Results<span v-show="$route.query.keyword">
  99. for "{{ decodeURIComponent($route.query.keyword) }}"</span
  100. >
  101. </p>
  102. <div>
  103. <div class="sort">
  104. <el-dropdown
  105. trigger="click"
  106. @command="handleCommand">
  107. <span class="el-dropdown-link">
  108. Sort by {{ command }}
  109. <i class="el-icon-arrow-down el-icon--right"></i>
  110. </span>
  111. <el-dropdown-menu slot="dropdown">
  112. <el-dropdown-item
  113. v-for="command in commandList"
  114. :command="command.value"
  115. :key="command.label"
  116. >{{ command.label }}
  117. </el-dropdown-item>
  118. </el-dropdown-menu>
  119. </el-dropdown>
  120. </div>
  121. <!-- <div class="arrangement">
  122. <span class="iconfont">&#xe920;</span>
  123. <span class="iconfont">&#xe600;</span>
  124. </div> -->
  125. </div>
  126. </div>
  127. <div class="metal-content">
  128. <div class="metal-content-left">
  129. <category-filter
  130. :leadTimeList="leadTimeList"
  131. :colourList="colourList"
  132. :collectionsList="collectionsList"
  133. :complianceList="complianceList"
  134. :featureList="featureList"
  135. :decorationList="decorationList"
  136. :priceRange1="priceRange1"
  137. :priceRange2="priceRange2"
  138. @reset="reset"
  139. @getList="getList"
  140. @handleChangeColor="handleChangeColor"
  141. @handleChangeFeature="handleChangeFeature"
  142. @handleChangePrice="handleChangePrice"
  143. @handleChangeCollection="handleChangeCollection"
  144. @handleChangeCompliance="handleChangeCompliance"
  145. @handleChangeDecoration="handleChangeDecoration"
  146. @handleChangeLeadtime="handleChangeLeadtime"
  147. @handleChangeQuantity="handleChangeQuantity"></category-filter>
  148. </div>
  149. <div
  150. v-if="listLoading"
  151. class="metal-content-right"></div>
  152. <div
  153. class="metal-content-right"
  154. v-show="cardList.length > 0 && !listLoading">
  155. <div class="metal-content-right-item">
  156. <card
  157. class="card"
  158. v-for="(item, index) in cardList"
  159. :key="parseInt(index)"
  160. :cardData="item"
  161. @addCompare="addCompareList"></card>
  162. <transition
  163. @before-enter="beforeEnter"
  164. @enter="enter"
  165. @after-enter="afterEnter">
  166. <div
  167. class="ball"
  168. v-show="shopCarBall"
  169. ref="ball">
  170. <div class="linner_ball"></div>
  171. </div>
  172. </transition>
  173. </div>
  174. <no-ssr>
  175. <infinite-loading
  176. spinner="spiral"
  177. @infinite="infiniteHandler"
  178. :identifier="computedProductList"
  179. :distance="200"
  180. class="infinite-loading-wrap">
  181. <div
  182. v-loading="true"
  183. slot="spinner"
  184. element-loading-text="Loading"
  185. element-loading-spinner="el-icon-loading"></div>
  186. <div
  187. class="loading-text"
  188. slot="no-more"></div>
  189. <div
  190. slot="error"
  191. slot-scope="{ trigger }">
  192. Error Data, click
  193. <a
  194. href="javascript:;"
  195. @click="trigger"
  196. >here</a
  197. >
  198. toretry
  199. </div>
  200. </infinite-loading>
  201. </no-ssr>
  202. </div>
  203. <div
  204. class="metal-content-right-item empty"
  205. v-show="cardList.length === 0 && !listLoading">
  206. <category-no-data></category-no-data>
  207. </div>
  208. </div>
  209. </div>
  210. </div>
  211. </div>
  212. </template>
  213. <script>
  214. import InfiniteLoading from 'vue-infinite-loading'
  215. import categoryMixin from '@/mixins/category'
  216. export default {
  217. components: {
  218. InfiniteLoading,
  219. },
  220. mixins: [categoryMixin],
  221. data() {
  222. return {
  223. listLoading: true,
  224. activeNames: ['1'],
  225. cardList: [],
  226. shopCarBall: false,
  227. shopCarBallEl: null,
  228. ss: null,
  229. }
  230. },
  231. watch: {},
  232. async mounted() {
  233. // await this.getGoodsFilterList()
  234. },
  235. methods: {
  236. addCompareList(target) {
  237. this.shopCarBallEl = target
  238. this.shopCarBall = true
  239. },
  240. // 动画开始
  241. beforeEnter(el) {
  242. // 获取元素的大小及其相对于视口的位置
  243. if (process.client) {
  244. const dom = this.shopCarBallEl.getBoundingClientRect()
  245. const comparePosition = document
  246. .querySelector('.compare-list')
  247. .getBoundingClientRect()
  248. const offsetX = comparePosition.left - dom.left
  249. const offsetY = dom.top - comparePosition.top - 20
  250. el.style.display = ''
  251. // y轴是曲直向上的,x轴是蜿蜒的向右的
  252. el.style.transform = `translate3D( -${offsetX}px,${offsetY}px,0)`
  253. }
  254. },
  255. enter(el, done) {
  256. // 触发重绘,来实现动画的移动过程
  257. if (process.client) {
  258. this.ss = document.body.offsetHeight
  259. el.style.transform = `translate3D( 0,0,0)`
  260. el.addEventListener('transitionend', done)
  261. }
  262. },
  263. afterEnter(el) {
  264. this.shopCarBall = false
  265. el.style.display = 'none'
  266. },
  267. },
  268. }
  269. </script>
  270. <style lang="scss" scoped>
  271. .com-main a img {
  272. width: 100%;
  273. height: 450px;
  274. }
  275. @import '../category.scss';
  276. </style>