u-switch-jp.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <view class="u-switch" :class="[value == true ? 'u-switch--on' : '', disabled ? 'u-switch--disabled' : '']" @tap="onClick"
  3. :style="[switchStyle]">
  4. <span class=" u-switch--text" v-if="obj.sz"
  5. :style="[textStyle]"
  6. >{{obj.sz[value== true?1:0]}}</span>
  7. <view class="u-switch__node node-class"
  8. :style="[nodeStyle]"
  9. >
  10. <u-loading :show="loading" class="u-switch__loading" :size="size * 0.6" :color="loadingColor" />
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. /**
  16. * switch 开关选择器
  17. * @description 选择开关一般用于只有两个选择,且只能选其一的场景。
  18. * @tutorial https://www.uviewui.com/components/switch.html
  19. * @property {Boolean} loading 是否处于加载中(默认false)
  20. * @property {Boolean} disabled 是否禁用(默认false)
  21. * @property {String Number} size 开关尺寸,单位rpx(默认50)
  22. * @property {String} active-color 打开时的背景色(默认#2979ff)
  23. * @property {Boolean} inactive-color 关闭时的背景色(默认#ffffff)
  24. * @property {Boolean | Number | String} active-value 打开选择器时通过change事件发出的值(默认true)
  25. * @property {Boolean | Number | String} inactive-value 关闭选择器时通过change事件发出的值(默认false)
  26. * @event {Function} change 在switch打开或关闭时触发
  27. * @example <u-switch v-model="checked" active-color="red" inactive-color="#eee"></u-switch>
  28. */
  29. export default {
  30. name: "u-switch",
  31. props: {
  32. // 是否为加载中状态
  33. obj: {
  34. type: Object,
  35. default () {
  36. // 如下
  37. // return [{
  38. // text: '确定',
  39. // color: '',
  40. // fontSize: ''
  41. // }]
  42. return {};
  43. }
  44. },
  45. loading: {
  46. type: Boolean,
  47. default: false
  48. },
  49. // 是否为禁用装填
  50. disabled: {
  51. type: Boolean,
  52. default: false
  53. },
  54. // 开关尺寸,单位rpx
  55. size: {
  56. type: [Number, String],
  57. default: 50
  58. },
  59. // 打开时的背景颜色
  60. activeColor: {
  61. type: String,
  62. default: '#2979ff'
  63. },
  64. // 关闭时的背景颜色
  65. inactiveColor: {
  66. type: String,
  67. default: '#ffffff'
  68. },
  69. // 通过v-model双向绑定的值
  70. value: {
  71. type: Boolean,
  72. default: false
  73. },
  74. // 是否使手机发生短促震动,目前只在iOS的微信小程序有效(2020-05-06)
  75. vibrateShort: {
  76. type: Boolean,
  77. default: false
  78. },
  79. // 打开选择器时的值
  80. activeValue: {
  81. type: [Number, String, Boolean],
  82. default: true
  83. },
  84. // 关闭选择器时的值
  85. inactiveValue: {
  86. type: [Number, String, Boolean],
  87. default: false
  88. },
  89. },
  90. data() {
  91. return {
  92. }
  93. },
  94. computed: {
  95. textStyle(){
  96. let style = {
  97. };
  98. if(this.obj.fontSize){
  99. style.fontSize=this.obj.fontSize
  100. }
  101. return style;
  102. },
  103. nodeStyle(){
  104. var k= this.size+'rpx'
  105. let style = {
  106. width:k,
  107. height: k
  108. };
  109. if(this.obj.transform&&this.value==true){
  110. style.transform=this.obj.transform
  111. }
  112. return style;
  113. },
  114. switchStyle() {
  115. let style = {};
  116. if(this.obj.width){
  117. style.width=this.obj.width
  118. }
  119. style.fontSize = this.size + 'rpx';
  120. style.backgroundColor = this.value ? this.activeColor : this.inactiveColor;
  121. return style;
  122. },
  123. loadingColor() {
  124. return this.value ? this.activeColor : null;
  125. }
  126. },
  127. methods: {
  128. onClick() {
  129. if (!this.disabled && !this.loading) {
  130. // 使手机产生短促震动,微信小程序有效,APP(HX 2.6.8)和H5无效
  131. if(this.vibrateShort) uni.vibrateShort();
  132. this.$emit('input', !this.value);
  133. // 放到下一个生命周期,因为双向绑定的value修改父组件状态需要时间,且是异步的
  134. this.$nextTick(() => {
  135. this.$emit('change', this.value ? this.activeValue : this.inactiveValue);
  136. })
  137. }
  138. }
  139. }
  140. };
  141. </script>
  142. <style lang="scss" scoped>
  143. @import "../../libs/css/style.components.scss";
  144. .u-switch {
  145. position: relative;
  146. /* #ifndef APP-NVUE */
  147. display: inline-block;
  148. /* #endif */
  149. box-sizing: initial;
  150. width: 2em;
  151. height: 1em;
  152. background-color: #fff;
  153. border: 1px solid rgba(0, 0, 0, 0.1);
  154. border-radius: 1em;
  155. transition: background-color 0.3s;
  156. font-size: 50rpx;
  157. }
  158. .u-switch__node {
  159. @include vue-flex;
  160. align-items: center;
  161. justify-content: center;
  162. position: absolute;
  163. top: 0;
  164. left: 0;
  165. border-radius: 100%;
  166. z-index: 1;
  167. background-color: #fff;
  168. background-color: #fff;
  169. 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);
  170. 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);
  171. transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);
  172. transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05), -webkit-transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);
  173. transition: transform cubic-bezier(0.3, 1.05, 0.4, 1.05);
  174. transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05)
  175. }
  176. .u-switch__loading {
  177. @include vue-flex;
  178. align-items: center;
  179. justify-content: center;
  180. }
  181. .u-switch--on {
  182. background-color: #1989fa;
  183. }
  184. .u-switch--on .u-switch__node {
  185. transform: translateX(100%);
  186. }
  187. .u-switch--disabled {
  188. opacity: 0.4;
  189. }
  190. .u-switch--text{
  191. @include vue-flex;
  192. align-items: center;
  193. justify-content: center;
  194. position: absolute;
  195. top: 0;
  196. left: 25rpx;
  197. z-index: 1;
  198. transform: translateX(20%);
  199. color: #fff;
  200. }
  201. .u-switch--on{
  202. .u-switch--text {
  203. transform: translateX(0%);
  204. }
  205. }
  206. </style>