index.vue 7.0 KB

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