You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
8.2 KiB

2 years ago
  1. <template>
  2. <section :class="['tw-relative xl:tw-max-w-[1246px] xl:tw-mx-auto']">
  3. <div class="tw-relative tw-grid tw-grid-cols-2 tw-gap-[10px] tw-float-right tw-top-[4px]">
  4. <div :class="[
  5. 'swiper-button-prev highlightExhibitions tw-relative tw-text-black tw-w-[40px] tw-h-[40px] tw-left-0 tw-text-center tw-border-solid tw-border tw-border-neutrals-300 tw-rounded-[10px] tw-p-[8px] tw-hidden md:tw-block',
  6. ]"></div>
  7. <div :class="[
  8. 'swiper-button-next highlightExhibitions tw-relative tw-text-black tw-w-[40px] tw-h-[40px] tw-right-0 tw-text-center tw-border-solid tw-border tw-border-neutrals-300 tw-rounded-[10px] tw-p-[8px] tw-hidden md:tw-block',
  9. ]"></div>
  10. </div>
  11. <div class="swiper-container highlightExhibitions" ref="highlightExhibitions">
  12. <div :class="[
  13. 'swiper-wrapper tw-grid tw-grid-cols-2 tw-gap-y-[25px] md:tw-flex md:tw-grid-cols-none md:tw-gap-0',
  14. ]">
  15. <template v-for="(item, index) in exhibitions">
  16. <div :key="index" :class="['swiper-slide']" v-if="index <= useSwiper">
  17. <skeletonSlot>
  18. <template #default>
  19. <hightlightExhibitionsCard :item="item"></hightlightExhibitionsCard>
  20. </template>
  21. <template #fallback>
  22. <sk></sk>
  23. </template>
  24. </skeletonSlot>
  25. </div>
  26. </template>
  27. <template v-for="n in exhibitionsLength" >
  28. <div :key="n" :class="['swiper-slide']" v-if="windewWidth >= 1366">
  29. </div>
  30. </template>
  31. </div>
  32. </div>
  33. <a class="tw-block tw-border tw-border-solid tw-text-black tw-text-center tw-border-black tw-bg-white tw-py-[9px] tw-w-full tw-rounded-[12px] tw-mt-[44px] md:tw-hidden"
  34. :href="localePath('/exhibition')">
  35. {{ $t("See more") }}
  36. </a>
  37. </section>
  38. </template>
  39. <script>
  40. import { dateCountDown } from "~/utils/assist";
  41. import skeletonSlot from "~/components/newComponent/skeleton/skeletonSlot.vue";
  42. import hightlightExhibitionsCard from "~/components/home/HightlightExhibitionsCard.vue";
  43. import sk from '~/components/newComponent/skeleton/homeExhibitionCardSkeleton.vue';
  44. import TrendingServiceVue from "./TrendingService.vue";
  45. import Swiper from "swiper/bundle";
  46. export default {
  47. components: {
  48. hightlightExhibitionsCard,
  49. sk,
  50. skeletonSlot,
  51. Swiper
  52. },
  53. data() {
  54. return {
  55. highlightExhibitionsSwiper: undefined,
  56. carousel: 0,
  57. carouselPagesNum: 3,
  58. exhibitions: [],
  59. windewWidth: "",
  60. };
  61. },
  62. async created() {
  63. // await this.getData();
  64. this.exhibitions = [
  65. {
  66. id: '1',
  67. name: 'VISA',
  68. logo: require('/assets/img/thems/Frame33.png'),
  69. startdate: '2023-03-01',
  70. enddate: '2023-03-30',
  71. region:{
  72. name: 'Vietnam'
  73. },
  74. country:{
  75. name: 'Vietnam'
  76. },
  77. city:{
  78. name: 'Vietnam'
  79. }
  80. },
  81. {
  82. id: '1',
  83. name: 'VISA',
  84. logo: require('/assets/img/thems/Frame33.png'),
  85. startdate: '2023-03-01',
  86. enddate: '2023-03-30',
  87. region:{
  88. name: 'Vietnam'
  89. },
  90. country:{
  91. name: 'Vietnam'
  92. },
  93. city:{
  94. name: 'Vietnam'
  95. }
  96. },{
  97. id: '1',
  98. name: 'VISA',
  99. logo: require('/assets/img/thems/Frame33.png'),
  100. startdate: '2023-03-01',
  101. enddate: '2023-03-30',
  102. region:{
  103. name: 'Vietnam'
  104. },
  105. country:{
  106. name: 'Vietnam'
  107. },
  108. city:{
  109. name: 'Vietnam'
  110. }
  111. }
  112. ];
  113. if (process.browser) {
  114. window.addEventListener("resize", this.handleResize);
  115. }
  116. this.handleResize();
  117. },
  118. mounted() {
  119. let vm = this;
  120. vm.$nextTick(function () {
  121. vm.initSwiper();
  122. });
  123. },
  124. destroyed() {
  125. if (process.browser) {
  126. window.removeEventListener("resize", this.handleResize);
  127. }
  128. },
  129. computed: {
  130. useSwiper() {
  131. if (this.windewWidth < 768) {
  132. return 5;
  133. } else {
  134. return this.exhibitions.length;
  135. }
  136. },
  137. exhibitionsLength() {
  138. if (this.exhibitions.length > 6 && this.exhibitions.length < 12) {
  139. return 12 - this.exhibitions.length;
  140. }
  141. if (this.exhibitions.length > 9 && this.exhibitions.length < 18) {
  142. return 18 - this.exhibitions.length;
  143. }
  144. },
  145. },
  146. methods: {
  147. async getData() {
  148. let langQuery = "?lang=" + this.$i18n.localeProperties["langQuery"] + "&";
  149. this.$axios
  150. .get("/trending/exhibitions" + langQuery)
  151. .then((res) => {
  152. this.exhibitions = res.data.exhibitions;
  153. this.exhibitions = this.exhibitions.filter((item) => {
  154. let day = this.dateCountDown(item.startdate);
  155. return day > 0;
  156. })
  157. })
  158. .catch((err) => {
  159. console.error(err);
  160. });
  161. },
  162. handleResize() {
  163. if (process.browser) {
  164. this.windewWidth = window.innerWidth;
  165. this.initSwiper();
  166. }
  167. },
  168. initSwiper() {
  169. let vm = this;
  170. vm.$nextTick(function () {
  171. vm.highlightExhibitionsSwiper = new Swiper(
  172. ".swiper-container.highlightExhibitions",
  173. {
  174. direction: "horizontal",
  175. initialSlide: 0,
  176. slidesPerView: 2,
  177. slidesPerColumn: 3,
  178. // slidesPerGroup: 3,
  179. slidesPerColumnFill: 'row',
  180. allowTouchMove: false,
  181. grabCursor: true,
  182. observer: true, //修改swiper自己或子元素时,自动初始化swiper
  183. observeParents: true, //修改swiper的父元素时,自动初始化swiper
  184. rebuildOnUpdate: true,
  185. preloadImages: false,
  186. spaceBetween: 10,
  187. lazy: {
  188. loadPrevNext: true,
  189. loadOnTransitionStart: true,
  190. loadPrevNextAmount: 6,
  191. },
  192. navigation: {
  193. prevEl: ".swiper-button-prev.highlightExhibitions",
  194. nextEl: ".swiper-button-next.highlightExhibitions",
  195. },
  196. breakpoints: {
  197. 768: {
  198. slidesPerView: 1,
  199. slidesPerColumn: 6,
  200. slidesPerGroup: 1,
  201. spaceBetween: 20,
  202. allowTouchMove: true,
  203. lazy: {
  204. loadPrevNext: true,
  205. loadOnTransitionStart: true,
  206. loadPrevNextAmount: 10,
  207. },
  208. },
  209. 1366: {
  210. slidesPerView: 2,
  211. slidesPerColumn: 3,
  212. slidesPerGroup: 2,
  213. spaceBetween: 20,
  214. slidesPerColumnFill: 'row',
  215. allowTouchMove: true,
  216. },
  217. },
  218. }
  219. );
  220. vm.highlightExhibitionsSwiper.init();
  221. vm.highlightExhibitionsSwiper.update();
  222. });
  223. },
  224. dateCountDown
  225. },
  226. };
  227. </script>
  228. <style lang="scss" scoped>
  229. .swiper-container {
  230. width: 100% !important;
  231. }
  232. .swiper-slide {
  233. margin-right: 20px;
  234. // @media screen and (min-width:768px) {
  235. // &:first-child {
  236. // margin-bottom: 20px;
  237. // }
  238. // }
  239. }
  240. .swiper-button {
  241. &-prev.highlightExhibitions {
  242. z-index: 4;
  243. &:focus-visible {
  244. outline: none;
  245. }
  246. &::after {
  247. font-size: 24px;
  248. font-weight: bold;
  249. text-align: center;
  250. color: transparent;
  251. background-image: url('~/assets/svg/u-angle-left-b.svg');
  252. background-position: center;
  253. background-repeat: no-repeat;
  254. background-size: cover;
  255. }
  256. &:focus-visible,
  257. &:focus {
  258. outline: none;
  259. }
  260. }
  261. &-next.highlightExhibitions {
  262. z-index: 4;
  263. &:focus-visible {
  264. outline: none;
  265. }
  266. &::after {
  267. font-size: 24px;
  268. font-weight: bold;
  269. text-align: center;
  270. color: transparent;
  271. background-image: url('~/assets/svg/u-angle-right-b.svg');
  272. background-position: center;
  273. background-repeat: no-repeat;
  274. background-size: cover;
  275. }
  276. &:focus-visible,
  277. &:focus {
  278. outline: none;
  279. }
  280. }
  281. }
  282. .active {
  283. position: relative;
  284. &::after {
  285. content: "";
  286. display: block;
  287. position: absolute;
  288. bottom: -12px;
  289. width: 100%;
  290. height: 2px;
  291. background-color: #f48800;
  292. }
  293. }
  294. </style>