Segmented.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <view
  3. :class="[styleType === 'text' ? 'segmented-control--text' : 'segmented-control--button']"
  4. :style="{ borderColor: styleType === 'text' ? '' : activeColor }"
  5. class="segmented-control"
  6. >
  7. <view
  8. v-for="(item, index) in values"
  9. :class="[
  10. styleType === 'text' ? '' : 'segmented-control__item--button',
  11. index === currentIndex && styleType === 'button' ? 'segmented-control__item--button--active' : '',
  12. index === 0 && styleType === 'button' ? 'segmented-control__item--button--first' : '',
  13. index === values.length - 1 && styleType === 'button' ? 'segmented-control__item--button--last' : ''
  14. ]"
  15. :key="index"
  16. :style="{
  17. backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',
  18. borderColor: (index === currentIndex && styleType === 'text') || styleType === 'button' ? activeColor : 'transparent'
  19. }"
  20. class="segmented-control__item"
  21. @click="_onClick(index)"
  22. >
  23. <view>
  24. <text
  25. :style="{ color: index === currentIndex ? (styleType === 'text' ? activeColor : '#fff') : styleType === 'text' ? '#000' : activeColor }"
  26. class="segmented-control__text"
  27. :class="styleType === 'text' && index === currentIndex ? 'segmented-control__item--text' : ''"
  28. >
  29. {{ item }}
  30. </text>
  31. </view>
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. /**
  37. * SegmentedControl 分段器
  38. * @description 用作不同视图的显示
  39. * @tutorial https://ext.dcloud.net.cn/plugin?id=54
  40. * @property {Number} current 当前选中的tab索引值,从0计数
  41. * @property {String} styleType = [button|text] 分段器样式类型
  42. * @value button 按钮类型
  43. * @value text 文字类型
  44. * @property {String} activeColor 选中的标签背景色与边框颜色
  45. * @property {Array} values 选项数组
  46. * @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
  47. */
  48. export default {
  49. name: 'Segmented',
  50. emits: ['clickItem'],
  51. props: {
  52. current: {
  53. type: Number,
  54. default: 0
  55. },
  56. target: {
  57. type: Object,
  58. default: {}
  59. },
  60. values: {
  61. type: Array,
  62. default() {
  63. return [];
  64. }
  65. },
  66. activeColor: {
  67. type: String,
  68. default: '#2979FF'
  69. },
  70. styleType: {
  71. type: String,
  72. default: 'button'
  73. }
  74. },
  75. data() {
  76. return {
  77. currentIndex: 0
  78. };
  79. },
  80. watch: {
  81. current(val) {
  82. if (val !== this.currentIndex) {
  83. this.currentIndex = val;
  84. }
  85. }
  86. },
  87. created() {
  88. this.currentIndex = this.current;
  89. },
  90. methods: {
  91. _onClick(index) {
  92. //if (this.currentIndex !== index) {
  93. this.currentIndex = index;
  94. this.$emit('clickItem', {
  95. currentIndex: index,
  96. target: this.target
  97. });
  98. //}
  99. }
  100. }
  101. };
  102. </script>
  103. <style lang="scss" scoped>
  104. .segmented-control {
  105. /* #ifndef APP-NVUE */
  106. display: flex;
  107. box-sizing: border-box;
  108. /* #endif */
  109. flex-direction: row;
  110. height: 36px;
  111. overflow: hidden;
  112. /* #ifdef H5 */
  113. cursor: pointer;
  114. /* #endif */
  115. }
  116. .segmented-control__item {
  117. /* #ifndef APP-NVUE */
  118. display: inline-flex;
  119. box-sizing: border-box;
  120. /* #endif */
  121. position: relative;
  122. flex: 1;
  123. justify-content: center;
  124. align-items: center;
  125. }
  126. .segmented-control__item--button {
  127. border-style: solid;
  128. border-top-width: 1px;
  129. border-bottom-width: 1px;
  130. border-right-width: 1px;
  131. border-left-width: 0;
  132. }
  133. .segmented-control__item--button--first {
  134. border-left-width: 1px;
  135. border-top-left-radius: 5px;
  136. border-bottom-left-radius: 5px;
  137. }
  138. .segmented-control__item--button--last {
  139. border-top-right-radius: 5px;
  140. border-bottom-right-radius: 5px;
  141. }
  142. .segmented-control__item--text {
  143. border-bottom-style: solid;
  144. border-bottom-width: 2px;
  145. padding: 6px 0;
  146. }
  147. .segmented-control__text {
  148. font-size: 14px;
  149. line-height: 20px;
  150. text-align: center;
  151. }
  152. </style>