uni-swiper-dot.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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. key="default"
  9. >
  10. <view
  11. v-for="(item, index) in info"
  12. @click="clickItem(index)"
  13. :style="{
  14. width: (index === current ? dots.width * 2 : dots.width) + 'px',
  15. height: dots.width / 3 + 'px',
  16. 'background-color': index !== current ? dots.backgroundColor : dots.selectedBackgroundColor,
  17. 'border-radius': '0px'
  18. }"
  19. :key="index"
  20. class="uni-swiper__dots-item uni-swiper__dots-bar"
  21. />
  22. </view>
  23. <view v-if="mode === 'dot'" :style="{ bottom: dots.bottom + 'px' }" class="uni-swiper__dots-box" key="dot">
  24. <view
  25. v-for="(item, index) in info"
  26. @click="clickItem(index)"
  27. :style="{
  28. width: dots.width + 'px',
  29. height: dots.height + 'px',
  30. 'background-color': index !== current ? dots.backgroundColor : dots.selectedBackgroundColor,
  31. border: index !== current ? dots.border : dots.selectedBorder
  32. }"
  33. :key="index"
  34. class="uni-swiper__dots-item"
  35. />
  36. </view>
  37. <view v-if="mode === 'round'" :style="{ bottom: dots.bottom + 'px' }" class="uni-swiper__dots-box" key="round">
  38. <view
  39. v-for="(item, index) in info"
  40. @click="clickItem(index)"
  41. :class="[index === current && 'uni-swiper__dots-long']"
  42. :style="{
  43. width: (index === current ? dots.width * 3 : dots.width) + 'px',
  44. height: dots.height + 'px',
  45. 'background-color': index !== current ? dots.backgroundColor : dots.selectedBackgroundColor,
  46. border: index !== current ? dots.border : dots.selectedBorder
  47. }"
  48. :key="index"
  49. class="uni-swiper__dots-item "
  50. />
  51. </view>
  52. <view
  53. v-if="mode === 'nav'"
  54. key="nav"
  55. :style="{ 'background-color': dotsStyles.backgroundColor, bottom: '0' }"
  56. class="uni-swiper__dots-box uni-swiper__dots-nav"
  57. >
  58. <text :style="{ color: dotsStyles.color }" class="uni-swiper__dots-nav-item">{{
  59. current + 1 + '/' + info.length + ' ' + info[current][field]
  60. }}</text>
  61. </view>
  62. <view
  63. v-if="mode === 'indexes'"
  64. key="indexes"
  65. :style="{ bottom: dots.bottom + 'px' }"
  66. class="uni-swiper__dots-box"
  67. >
  68. <view
  69. v-for="(item, index) in info"
  70. @click="clickItem(index)"
  71. :style="{
  72. width: dots.width + 'px',
  73. height: dots.height + 'px',
  74. color: index === current ? dots.selectedColor : dots.color,
  75. 'background-color': index !== current ? dots.backgroundColor : dots.selectedBackgroundColor,
  76. border: index !== current ? dots.border : dots.selectedBorder
  77. }"
  78. :key="index"
  79. class="uni-swiper__dots-item uni-swiper__dots-indexes"
  80. ><text class="uni-swiper__dots-indexes-text">{{ index + 1 }}</text></view
  81. >
  82. </view>
  83. <view v-if="mode === 'left'" key="left" class="uni-swiper__dots-box uni-swiper__dots-left">
  84. <text class="uni-swiper__dots-left-text"> {{ current + 1 + '/' + info.length }} </text>
  85. </view>
  86. </view>
  87. </template>
  88. <script>
  89. /**
  90. * SwiperDod 轮播图指示点
  91. * @description 自定义轮播图指示点
  92. * @tutorial https://ext.dcloud.net.cn/plugin?id=284
  93. * @property {Number} current 当前指示点索引,必须是通过 `swiper` 的 `change` 事件获取到的 `e.detail.current`
  94. * @property {String} mode = [default|round|nav|indexes] 指示点的类型
  95. * @value defualt 默认指示点
  96. * @value round 圆形指示点
  97. * @value nav 条形指示点
  98. * @value indexes 索引指示点
  99. * @property {String} field mode 为 nav 时,显示的内容字段(mode = nav 时必填)
  100. * @property {String} info 轮播图的数据,通过数组长度决定指示点个数
  101. * @property {Object} dotsStyles 指示点样式
  102. * @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
  103. */
  104. export default {
  105. name: 'UniSwiperDot',
  106. emits: ['clickItem'],
  107. props: {
  108. info: {
  109. type: Array,
  110. default() {
  111. return []
  112. }
  113. },
  114. current: {
  115. type: Number,
  116. default: 0
  117. },
  118. dotsStyles: {
  119. type: Object,
  120. default() {
  121. return {}
  122. }
  123. },
  124. // 类型 :default(默认) indexes long nav
  125. mode: {
  126. type: String,
  127. default: 'default'
  128. },
  129. // 只在 nav 模式下生效,变量名称
  130. field: {
  131. type: String,
  132. default: ''
  133. }
  134. },
  135. data() {
  136. return {
  137. dots: {
  138. width: 8,
  139. height: 8,
  140. bottom: 10,
  141. color: '#fff',
  142. backgroundColor: 'rgba(0, 0, 0, .3)',
  143. border: '1px rgba(0, 0, 0, .3) solid',
  144. selectedBackgroundColor: '#333',
  145. selectedBorder: '1px rgba(0, 0, 0, .9) solid'
  146. }
  147. }
  148. },
  149. watch: {
  150. dotsStyles(newVal) {
  151. this.dots = Object.assign(this.dots, this.dotsStyles)
  152. },
  153. mode(newVal) {
  154. if (newVal === 'indexes') {
  155. this.dots.width = 20
  156. this.dots.height = 20
  157. } else {
  158. this.dots.width = 8
  159. this.dots.height = 8
  160. }
  161. }
  162. },
  163. created() {
  164. if (this.mode === 'indexes') {
  165. this.dots.width = 20
  166. this.dots.height = 20
  167. }
  168. this.dots = Object.assign(this.dots, this.dotsStyles)
  169. },
  170. methods: {
  171. clickItem(index) {
  172. this.$emit('clickItem', index)
  173. }
  174. }
  175. }
  176. </script>
  177. <style lang="scss" scoped>
  178. .uni-swiper__warp {
  179. /* #ifndef APP-NVUE */
  180. display: flex;
  181. /* #endif */
  182. flex: 1;
  183. flex-direction: column;
  184. position: relative;
  185. overflow: hidden;
  186. }
  187. .uni-swiper__dots-box {
  188. position: absolute;
  189. bottom: 10px;
  190. left: 0;
  191. right: 0;
  192. /* #ifndef APP-NVUE */
  193. display: flex;
  194. /* #endif */
  195. flex: 1;
  196. flex-direction: row;
  197. justify-content: center;
  198. align-items: center;
  199. }
  200. .uni-swiper__dots-item {
  201. width: 8px;
  202. border-radius: 100px;
  203. margin-left: 6px;
  204. background-color: $uni-bg-color-mask;
  205. /* #ifndef APP-NVUE */
  206. cursor: pointer;
  207. /* #endif */
  208. /* #ifdef H5 */
  209. // border-width: 5px 0;
  210. // border-style: solid;
  211. // border-color: transparent;
  212. // background-clip: padding-box;
  213. /* #endif */
  214. // transition: width 0.2s linear; 不要取消注释,不然会不能变色
  215. }
  216. .uni-swiper__dots-item:first-child {
  217. margin: 0;
  218. }
  219. .uni-swiper__dots-default {
  220. border-radius: 100px;
  221. }
  222. .uni-swiper__dots-long {
  223. border-radius: 50px;
  224. }
  225. .uni-swiper__dots-bar {
  226. border-radius: 50px;
  227. }
  228. .uni-swiper__dots-nav {
  229. bottom: 0px;
  230. height: 40px;
  231. /* #ifndef APP-NVUE */
  232. display: flex;
  233. /* #endif */
  234. flex: 1;
  235. flex-direction: row;
  236. justify-content: flex-start;
  237. align-items: center;
  238. background-color: rgba(0, 0, 0, 0.2);
  239. }
  240. .uni-swiper__dots-nav-item {
  241. /* overflow: hidden;
  242. text-overflow: ellipsis;
  243. white-space: nowrap; */
  244. font-size: $uni-font-size-base;
  245. color: #fff;
  246. margin: 0 15px;
  247. }
  248. .uni-swiper__dots-indexes {
  249. /* #ifndef APP-NVUE */
  250. display: flex;
  251. /* #endif */
  252. // flex: 1;
  253. justify-content: center;
  254. align-items: center;
  255. }
  256. .uni-swiper__dots-left {
  257. left: unset;
  258. right: 24rpx;
  259. }
  260. .uni-swiper__dots-left-text {
  261. display: block;
  262. height: 48rpx;
  263. border-radius: 24rpx;
  264. line-height: 48rpx;
  265. padding: 0 24rpx;
  266. font-size: 26rpx;
  267. font-family: PingFangSC;
  268. color: #ffffff;
  269. background-color: rgba(0, 0, 0, 0.3);
  270. }
  271. .uni-swiper__dots-indexes-text {
  272. color: #fff;
  273. font-size: $uni-font-size-sm;
  274. }
  275. </style>