index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <view class="uni-swiper__warp">
  3. <slot />
  4. <view
  5. v-if="mode === 'default'"
  6. :style="{ bottom: dots.bottom + 'px' }"
  7. class="uni-swiper__dots-box"
  8. >
  9. <view
  10. v-for="(item, index) in info"
  11. :style="{
  12. width: (index === current ? dots.width * 2 : dots.width) + 'px',
  13. height: dots.width / 3 + 'px',
  14. 'background-color':
  15. index !== current
  16. ? dots.backgroundColor
  17. : dots.selectedBackgroundColor,
  18. 'border-radius': '0px'
  19. }"
  20. :key="index"
  21. class="uni-swiper__dots-item uni-swiper__dots-bar"
  22. />
  23. </view>
  24. <view
  25. v-if="mode === 'dot'"
  26. :style="{ bottom: dots.bottom + 'px' }"
  27. class="uni-swiper__dots-box"
  28. >
  29. <view
  30. v-for="(item, index) in info"
  31. :style="{
  32. width: dots.width + 'px',
  33. height: dots.height + 'px',
  34. 'background-color':
  35. index !== current
  36. ? dots.backgroundColor
  37. : dots.selectedBackgroundColor,
  38. border: index !== current ? dots.border : dots.selectedBorder
  39. }"
  40. :key="index"
  41. class="uni-swiper__dots-item"
  42. />
  43. </view>
  44. <view
  45. v-if="mode === 'round'"
  46. :style="{ bottom: dots.bottom + 'px' }"
  47. class="uni-swiper__dots-box"
  48. >
  49. <view
  50. v-for="(item, index) in info"
  51. :class="[index === current && 'uni-swiper__dots-long']"
  52. :style="{
  53. width: (index === current ? dots.width * 3 : dots.width) + 'px',
  54. height: dots.height + 'px',
  55. 'background-color':
  56. index !== current
  57. ? dots.backgroundColor
  58. : dots.selectedBackgroundColor,
  59. border: index !== current ? dots.border : dots.selectedBorder
  60. }"
  61. :key="index"
  62. class="uni-swiper__dots-item "
  63. />
  64. </view>
  65. <view
  66. v-if="mode === 'nav'"
  67. :style="{ 'background-color': dotsStyles.backgroundColor }"
  68. class="uni-swiper__dots-box uni-swiper__dots-nav"
  69. >
  70. <view
  71. :style="{ color: dotsStyles.color }"
  72. class="uni-swiper__dots-nav-item"
  73. >{{ current + 1 + '/' + info.length }}
  74. {{ info[current] && info[current][field] }}</view
  75. >
  76. </view>
  77. <view
  78. v-if="mode === 'indexes'"
  79. :style="{ bottom: dots.bottom + 'px' }"
  80. class="uni-swiper__dots-box"
  81. >
  82. <view
  83. v-for="(item, index) in info"
  84. :style="{
  85. width: dots.width + 'px',
  86. height: dots.height + 'px',
  87. color: index === current ? dots.selectedColor : dots.color,
  88. 'background-color':
  89. index !== current
  90. ? dots.backgroundColor
  91. : dots.selectedBackgroundColor,
  92. border: index !== current ? dots.border : dots.selectedBorder
  93. }"
  94. :key="index"
  95. class="uni-swiper__dots-item uni-swiper__dots-indexes"
  96. >{{ index + 1 }}</view
  97. >
  98. </view>
  99. </view>
  100. </template>
  101. <script>
  102. export default {
  103. name: 'UniSwiperDot',
  104. props: {
  105. info: {
  106. type: Array,
  107. default() {
  108. return [];
  109. }
  110. },
  111. current: {
  112. type: Number,
  113. default: 0
  114. },
  115. dotsStyles: {
  116. type: Object,
  117. default() {
  118. return {};
  119. }
  120. },
  121. // 类型 :default(默认) indexes long nav
  122. mode: {
  123. type: String,
  124. default: 'default'
  125. },
  126. // 只在 nav 模式下生效,变量名称
  127. field: {
  128. type: String,
  129. default: ''
  130. }
  131. },
  132. data() {
  133. return {
  134. dots: {
  135. width: 8,
  136. height: 8,
  137. bottom: 10,
  138. color: '#fff',
  139. backgroundColor: 'rgba(0, 0, 0, .3)',
  140. border: '1px rgba(0, 0, 0, .3) solid',
  141. selectedBackgroundColor: '#333',
  142. selectedBorder: '1px rgba(0, 0, 0, .9) solid'
  143. }
  144. };
  145. },
  146. watch: {
  147. dotsStyles(newVal) {
  148. this.dots = Object.assign(this.dots, this.dotsStyles);
  149. },
  150. mode(newVal) {
  151. if (newVal === 'indexes') {
  152. this.dots.width = 20;
  153. this.dots.height = 20;
  154. } else {
  155. this.dots.width = 8;
  156. this.dots.height = 8;
  157. }
  158. }
  159. },
  160. created() {
  161. if (this.mode === 'indexes') {
  162. this.dots.width = 20;
  163. this.dots.height = 20;
  164. }
  165. this.dots = Object.assign(this.dots, this.dotsStyles);
  166. }
  167. };
  168. </script>
  169. <style>
  170. .uni-swiper__warp {
  171. position: relative;
  172. width: 100%;
  173. box-sizing: border-box;
  174. overflow: hidden;
  175. }
  176. .uni-swiper__dots-box {
  177. position: absolute;
  178. bottom: 20rpx;
  179. display: flex;
  180. justify-content: center;
  181. align-items: center;
  182. box-sizing: box-sizing;
  183. width: 100%;
  184. }
  185. .uni-swiper__dots-item {
  186. flex-shrink: 0;
  187. width: 16rpx;
  188. border-radius: 50%;
  189. margin-left: 12rpx;
  190. background: rgba(0, 0, 0, 0.3);
  191. transition: all 0.2s linear;
  192. }
  193. .uni-swiper__dots-item:first-child {
  194. margin: 0;
  195. }
  196. .uni-swiper__dots-default {
  197. border-radius: 50%;
  198. }
  199. .uni-swiper__dots-long {
  200. border-radius: 100rpx;
  201. }
  202. .uni-swiper__dots-bar {
  203. border-radius: 100rpx;
  204. }
  205. .uni-swiper__dots-nav {
  206. bottom: 0;
  207. height: 60rpx;
  208. justify-content: flex-start;
  209. background: rgba(0, 0, 0, 0.2);
  210. box-sizing: box-sizing;
  211. overflow: hidden;
  212. z-index: 10;
  213. }
  214. .uni-swiper__dots-nav-item {
  215. overflow: hidden;
  216. text-overflow: ellipsis;
  217. white-space: nowrap;
  218. font-size: 28rpx;
  219. color: #fff;
  220. box-sizing: box-sizing;
  221. margin: 0 30rpx;
  222. }
  223. .uni-swiper__dots-indexes {
  224. display: flex;
  225. justify-content: center;
  226. align-items: center;
  227. color: #fff;
  228. font-size: 24rpx;
  229. }
  230. </style>