Carousel.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template lang="pug">
  2. .carousel-wrapper#carousel
  3. b-carousel(
  4. v-model="curIndex"
  5. :arrow="false"
  6. :pause-hover="false"
  7. :indicator="list.length > 1"
  8. indicator-style="is-lines"
  9. @change="onChange"
  10. )
  11. b-carousel-item(
  12. v-for="(item, idx) in list"
  13. :key="idx"
  14. )
  15. .pic(
  16. :class="{clickable: item.jump_target && !item.button_text}"
  17. :style="{backgroundImage: `url('${item.image_url}')`, backgroundColor: item.theme_color || 'transparent'}"
  18. @click="onClick(item, false)"
  19. )
  20. .container.is-content(v-if="item.title || item.desc" :style="{textAlign: item.cont_position || 'left'}")
  21. .text-content
  22. .title {{item.title}}
  23. .desc {{item.desc}}
  24. .button.is-primary.is-inverted.is-outlined(
  25. v-if="item.button_text"
  26. @click.stop.prevent="onClick(item, true)"
  27. ) {{item.button_text}}
  28. </template>
  29. <script lang="ts">
  30. import Vue from 'vue'
  31. const insertOrUpdateStyleTag = (item) => {
  32. const id = `carousel-style`
  33. const css = `.kaifain-view .carousel {background: ${item && item.theme_color || '#eee'}} .kaifain-view .carousel .carousel-item .text-content .button.is-primary:hover{color:${item && item.theme_color || '#20242d'}}`
  34. let dom = document.getElementById(id)
  35. if (!dom) {
  36. const wrapper = document.querySelector('#carousel')
  37. if (wrapper) {
  38. dom = document.createElement('style')
  39. dom.id = id
  40. dom.innerHTML = css
  41. wrapper.appendChild(dom)
  42. }
  43. } else {
  44. dom.innerHTML = css
  45. }
  46. }
  47. let lastClickedAt = 0
  48. export default Vue.extend({
  49. name: 'Carousel',
  50. components: {
  51. },
  52. props: {
  53. list: Array
  54. },
  55. data() {
  56. return {
  57. curIndex: 1
  58. }
  59. },
  60. methods: {
  61. onClick(item: any, isButton: boolean) {
  62. if (!isButton && item.button_text || !item.jump_target || Date.now() - lastClickedAt < 300) {
  63. return false
  64. }
  65. const win = window.open(item.jump_target, '_blank')
  66. if (win) {
  67. lastClickedAt = Date.now()
  68. }
  69. },
  70. onChange(idx: number) {
  71. const item = this.list[idx]
  72. item && insertOrUpdateStyleTag(item)
  73. }
  74. }
  75. })
  76. </script>
  77. <style lang="scss">
  78. .kaifain-view .carousel {
  79. width: 100%;
  80. height: 400px;
  81. background: #eee;
  82. .carousel-indicator {
  83. margin-bottom: 16px;
  84. .indicator-item {
  85. .indicator-style.is-lines {
  86. width: 48px;
  87. height: 4px;
  88. opacity: 0.2;
  89. }
  90. &.is-active .indicator-style {
  91. opacity: 0.8;
  92. }
  93. }
  94. }
  95. .carousel-item {
  96. width: 100%;
  97. height: 400px;
  98. .pic {
  99. background-position: center center;
  100. background-repeat: no-repeat;
  101. background-size: auto 100%;
  102. position: absolute;
  103. top: 0;
  104. left: 0;
  105. width: 100%;
  106. height: 100%;
  107. &.clickable {
  108. cursor: pointer;
  109. }
  110. }
  111. .text-content {
  112. position: relative;
  113. z-index: 1;
  114. margin-top: 140px;
  115. > * {
  116. color: #fff;
  117. }
  118. .desc {
  119. opacity: 0.76;
  120. }
  121. .button {
  122. margin-top: 44px;
  123. min-width: 128px;
  124. height: 2.572em;
  125. &.is-primary {
  126. font-size: 0.875rem;
  127. &:hover {
  128. color: #2487ff;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135. </style>