evan-switch.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <!-- <view @click="toggle" class="evan-switch" :class="{'evan-switch--disabled':disabled}" :style="{width:2*size+'px',height:switchHeight,borderRadius:size+'px',backgroundColor:currentValue===activeValue?activeColor:inactiveColor}">
  3. <view class="evan-switch__circle" :style="{width:size+'px',height:size+'px',transform:currentValue===activeValue?`translateX(${size}px)`:`translateX(0)`}"></view>
  4. </view> -->
  5. <view @click="toggle" class="evan-switch" :class="{'evan-switch--disabled':disabled}" :style="{backgroundColor:currentValue===activeValue?activeColor:inactiveColor}">
  6. <view class="evan-switch__circle" :style="{transform:currentValue===activeValue?`translateX(${29}px)`:`translateX(0)`}"></view>
  7. </view>
  8. </template>
  9. <script>
  10. export default {
  11. name: 'EvanSwitch',
  12. props: {
  13. value: {
  14. type: [String, Number, Boolean],
  15. default: false
  16. },
  17. activeColor: {
  18. type: String,
  19. default: '#108ee9'
  20. },
  21. inactiveColor: {
  22. type: String,
  23. default: '#fff'
  24. },
  25. size: {
  26. type: Number,
  27. default: 30
  28. },
  29. disabled: {
  30. type: Boolean,
  31. default: false
  32. },
  33. activeValue: {
  34. type: [String, Number, Boolean],
  35. default: true
  36. },
  37. inactiveValue: {
  38. type: [String, Number, Boolean],
  39. default: false
  40. },
  41. beforeChange: {
  42. type: Function,
  43. default: null
  44. },
  45. extraData: null,
  46. contextLevel: {
  47. type: Number,
  48. default: 1
  49. }
  50. },
  51. computed: {
  52. switchHeight() {
  53. // #ifdef APP-NVUE
  54. return this.size + 2 + 'px'
  55. // #endif
  56. // #ifndef APP-NVUE
  57. return this.size + 'px'
  58. // #endif
  59. }
  60. },
  61. watch: {
  62. value: {
  63. immediate: true,
  64. handler(value) {
  65. this.currentValue = value
  66. }
  67. }
  68. },
  69. data() {
  70. return {
  71. currentValue: false
  72. }
  73. },
  74. methods: {
  75. toggle() {
  76. if (!this.disabled) {
  77. if (this.beforeChange && typeof this.beforeChange === 'function') {
  78. let context = this
  79. for (let i = 0; i < this.contextLevel; i++) {
  80. context = context.$options.parent
  81. }
  82. const result = this.beforeChange(this.currentValue === this.activeValue ? this.inactiveValue : this.activeValue,
  83. this.extraData, context)
  84. if (typeof result === 'object') {
  85. result.then(() => {
  86. this.toggleValue()
  87. }).catch(() => {})
  88. } else if (typeof result === 'boolean' && result) {
  89. this.toggleValue()
  90. }
  91. } else {
  92. this.toggleValue()
  93. }
  94. }
  95. },
  96. toggleValue() {
  97. this.currentValue = this.currentValue === this.activeValue ? this.inactiveValue : this.activeValue
  98. this.$emit('input', this.currentValue)
  99. this.$emit('change', this.currentValue)
  100. }
  101. }
  102. }
  103. </script>
  104. <style lang="scss" scoped>
  105. .evan-switch {
  106. position: relative;
  107. border-width: 1px;
  108. border-color: rgba(0, 0, 0, 0.1);
  109. border-style: solid;
  110. transition: background-color 0.3s;
  111. width: 100upx;
  112. height: 36upx;
  113. background: #2BC7B9;
  114. border-radius: 18upx;
  115. /* #ifndef APP-NVUE */
  116. box-sizing: content-box;
  117. /* #endif */
  118. }
  119. .evan-switch--disabled {
  120. opacity: 0.3;
  121. }
  122. .evan-switch__circle {
  123. position: absolute;
  124. left: -4upx;
  125. top: -8upx;
  126. width: 50upx;
  127. height: 50upx;
  128. background: #FFFFFF;
  129. box-shadow: 0px 2px 10px 0px rgba(166, 217, 212, 0.49);
  130. border-radius: 50%;
  131. /* #ifndef APP-NVUE */
  132. box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
  133. /* #endif */
  134. /* #ifdef APP-NVUE */
  135. box-shadow: 1px 0 0px 0 rgba(0, 0, 0, 0.05);
  136. /* #endif */
  137. transition: transform 0.3s;
  138. }
  139. </style>