uni-segmented-control.vue 5.0 KB

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