RelicDetail.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <div class="relic-detail">
  3. <button
  4. class="return"
  5. @click="router.go(-1)"
  6. />
  7. <div class="left">
  8. <div
  9. class="swiper-root"
  10. >
  11. <div
  12. v-viewer
  13. class="swiper-wrapper"
  14. >
  15. <img
  16. v-for="(item, index) in imageList"
  17. :key="index"
  18. class="swiper-slide"
  19. :src="item"
  20. alt=""
  21. draggable="false"
  22. >
  23. </div>
  24. <!-- <div class="swiper-button-prev" />
  25. <div class="swiper-button-next" /> -->
  26. <div class="swiper-pagination" />
  27. </div>
  28. <img
  29. class="full"
  30. src="@/assets/images/full.png"
  31. @click="handleFull"
  32. >
  33. </div>
  34. <div
  35. class="right"
  36. :class="{
  37. hide: !isShowDesc,
  38. }"
  39. >
  40. <h1 :title="relicInfo['名称']">
  41. {{ relicInfo['名称'] }}
  42. </h1>
  43. <div class="age text-indent">
  44. {{ relicInfo['年份'] }}
  45. </div>
  46. <div
  47. class="detail text-indent"
  48. v-html="relicInfo['详细描述']"
  49. />
  50. <button
  51. class="show-hide"
  52. :class="{
  53. right: isShowDesc,
  54. left: !isShowDesc,
  55. }"
  56. @click="isShowDesc = !isShowDesc"
  57. />
  58. </div>
  59. </div>
  60. </template>
  61. <script setup>
  62. import { ref, computed, getCurrentInstance, onMounted, nextTick } from "vue"
  63. import { useRoute, useRouter } from "vue-router"
  64. import { useStore } from "vuex"
  65. import Swiper from 'swiper/bundle'
  66. import 'swiper/css/bundle'
  67. const route = useRoute()
  68. const router = useRouter()
  69. const store = useStore()
  70. const relicInfo = computed(() => {
  71. return store.getters[route.query.hot === '1' ? 'hotRelicData' : 'relicData'][route.query.relicIdx]
  72. })
  73. const imageList = computed(() => {
  74. if (Array.isArray(relicInfo.value['图片名'])) {
  75. return relicInfo.value['图片名'].map((item) => {
  76. return `${process.env.BASE_URL}relic-data/big-photo/${item}`
  77. })
  78. } else {
  79. return []
  80. }
  81. })
  82. const isShowDesc = ref(true)
  83. /**
  84. * swiper 相关
  85. */
  86. let swiper = null
  87. const activeSwiperItemIndex = ref(0)
  88. function initSwiper() {
  89. swiper = new Swiper('.swiper-root', {
  90. pagination: {
  91. el: '.swiper-pagination',
  92. },
  93. // Navigation arrows
  94. navigation: {
  95. nextEl: '.swiper-button-next',
  96. prevEl: '.swiper-button-prev',
  97. },
  98. on: {
  99. // afterInit: function (e) {
  100. // activeSwiperItemIndex.value = e.activeIndex
  101. // },
  102. slideChange: function(e) {
  103. activeSwiperItemIndex.value = e.activeIndex
  104. }
  105. }
  106. })
  107. }
  108. onMounted(() => {
  109. nextTick(() => {
  110. initSwiper()
  111. })
  112. })
  113. const instance = getCurrentInstance()
  114. const handleFull = () => {
  115. instance.appContext.config.globalProperties.$viewerApi({
  116. options: {},
  117. images: [
  118. imageList.value[activeSwiperItemIndex.value]
  119. ]
  120. })
  121. }
  122. </script>
  123. <style lang="less" scoped>
  124. @page-height-design-px: 970;
  125. @page-width-design-px: 1920;
  126. .relic-detail{
  127. height: 100%;
  128. position: relative;
  129. background-color: #2F2C2C;
  130. display: flex;
  131. >button.return{
  132. position: absolute;
  133. width: 58px;
  134. height: 58px;
  135. left: 42px;
  136. top: 68px;
  137. background-image: url(@/assets/images/btn-return.png);
  138. background-size: contain;
  139. background-repeat: no-repeat;
  140. background-position: center center;
  141. z-index: 1;
  142. }
  143. >.left{
  144. position: relative;
  145. flex: 1 0 1px;
  146. height: 100%;
  147. .full {
  148. position: absolute;
  149. right: 30px;
  150. bottom: 30px;
  151. width: 26px;
  152. cursor: pointer;
  153. }
  154. >.swiper-root{
  155. position: absolute;
  156. left: 50%;
  157. top: 50%;
  158. transform: translate(-50%, -50%);
  159. width: 688px;
  160. height: 688px;
  161. max-width: 80%;
  162. max-height: 80%;
  163. overflow: hidden;
  164. >.swiper-wrapper{
  165. width: 100%;
  166. height: 100%;
  167. >img.swiper-slide {
  168. width: 100%;
  169. height: 100%;
  170. object-fit: contain;
  171. cursor: pointer;
  172. }
  173. }
  174. >:deep(.swiper-pagination){
  175. bottom: 0;
  176. >span{
  177. width: 20px;
  178. height: 5px;
  179. border-radius: 0;
  180. background-color: #666;
  181. border-radius: 2.5px;
  182. }
  183. >span.swiper-pagination-bullet-active{
  184. background-color: #f4d085;
  185. opacity: 1;
  186. }
  187. }
  188. }
  189. }
  190. >.right{
  191. height: 100%;
  192. flex: 0 0 auto;
  193. width: calc(577 / @page-width-design-px * 100vw);
  194. background-image: url(@/assets/images/relic-detail-bg-right.jpg);
  195. background-size: cover;
  196. background-repeat: no-repeat;
  197. background-position: center center;
  198. display: flex;
  199. flex-direction: column;
  200. position: relative;
  201. margin-right: 0;
  202. transition: margin-right 0.5s;
  203. >h1{
  204. flex: 0 0 auto;
  205. margin-top: 100px;
  206. margin-left: calc(40 / 577 * 100%);
  207. margin-right: calc(40 / 577 * 100%);
  208. padding-left: calc(32 / 577 * 100%);
  209. padding-right: calc(32 / 577 * 100%);
  210. background: linear-gradient(90deg, rgba(255,226,122,0) 0%, #C9AD83 49%, rgba(249,226,148,0) 100%);
  211. font-size: 30px;
  212. line-height: 62px;
  213. font-family: Source Han Serif CN, Source Han Serif CN;
  214. font-weight: 800;
  215. color: #43310E;
  216. line-height: 62px;
  217. letter-spacing: 3px;
  218. display: -webkit-box;
  219. -webkit-box-orient: vertical;
  220. -webkit-line-clamp: 3;
  221. overflow: hidden;
  222. }
  223. >.age{
  224. flex: 0 0 auto;
  225. margin-top: 100px;
  226. font-size: 20px;
  227. font-family: Source Han Sans SC, Source Han Sans SC;
  228. font-weight: 300;
  229. color: #000000;
  230. line-height: 23px;
  231. letter-spacing: 4px;
  232. margin-left: calc(70 / 577 * 100%);
  233. margin-right: calc(70 / 577 * 100%);
  234. display: -webkit-box;
  235. -webkit-box-orient: vertical;
  236. -webkit-line-clamp: 3;
  237. overflow: hidden;
  238. }
  239. >.detail{
  240. display: flex;
  241. flex-direction: column;
  242. flex: 0 1 auto;
  243. margin-top: 30px;
  244. margin-bottom: 30px;
  245. margin-left: calc(70 / 577 * 100%);
  246. margin-right: calc(35 / 577 * 100%);
  247. font-size: 20px;
  248. font-family: Source Han Sans SC, Source Han Sans SC;
  249. font-weight: 300;
  250. color: #000000;
  251. // letter-spacing: 4px;
  252. overflow: auto;
  253. padding-right: calc(35 / 577 * 100%);
  254. word-wrap: break-word;
  255. white-space: pre-wrap;
  256. :deep(p) {
  257. line-height: 30px;
  258. }
  259. }
  260. >button.show-hide{
  261. position: absolute;
  262. left: 0;
  263. top: 50%;
  264. transform: translate(-50%, -50%);
  265. width: 60px;
  266. height: 60px;
  267. background-size: cover;
  268. background-repeat: no-repeat;
  269. background-position: center center;
  270. }
  271. >button.show-hide.left{
  272. background-image: url(@/assets/images/btn-left.png);
  273. }
  274. >button.show-hide.right{
  275. background-image: url(@/assets/images/btn-right.png);
  276. }
  277. }
  278. >.right.hide{
  279. margin-right: calc(-577 / @page-width-design-px * 100vw);
  280. }
  281. }
  282. </style>