tui-switch.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <template>
  2. <view class="tui-switch__input" :style="{zoom:nvue?1:scaleRatio,transform:`scale(${nvue?scaleRatio:1})`}">
  3. <switch v-if="type==='switch'" :class="{'tui-pevents':isLabel}" @change="change" :name="name" :checked="val" :disabled="disabled" :color="color">
  4. </switch>
  5. <view class="tui-checkbox__self" :class="{'tui-checkbox__disabled':disabled}"
  6. :style="{backgroundColor:val?color:'#fff',border:val?`1px solid ${color}`:`1px solid ${borderColor}`}"
  7. v-else>
  8. <view class="tui-check__mark" :style="{borderBottomColor:checkMarkColor,borderRightColor:checkMarkColor}"
  9. v-if="val"></view>
  10. <switch class="tui-switch__hidden" :class="{'tui-pevents':isLabel}" style="position: absolute;opacity: 0;"
  11. @change="change" :name="name" type="checkbox" :checked="val" :disabled="disabled"></switch>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: "tui-switch",
  18. emits: ['change'],
  19. // #ifndef VUE3
  20. // #ifdef MP-WEIXIN
  21. behaviors: ['wx://form-field-group'],
  22. // #endif
  23. // #ifdef MP-BAIDU || MP-QQ
  24. behaviors: ['uni://form-field'],
  25. // #endif
  26. // #endif
  27. props: {
  28. //开关选择器名称
  29. name: {
  30. type: String,
  31. default: ''
  32. },
  33. checked: {
  34. type: Boolean,
  35. default: false
  36. },
  37. disabled: {
  38. type: Boolean,
  39. default: false
  40. },
  41. //样式,有效值:switch, checkbox
  42. type: {
  43. type: String,
  44. default: 'switch'
  45. },
  46. //switch选中颜色
  47. color: {
  48. type: String,
  49. default: '#5677fc'
  50. },
  51. //边框颜色,type=checkbox时生效
  52. borderColor: {
  53. type: String,
  54. default: '#ccc'
  55. },
  56. //对号颜色,type=checkbox时生效
  57. checkMarkColor: {
  58. type: String,
  59. default: '#fff'
  60. },
  61. scaleRatio: {
  62. type: [Number, String],
  63. default: 1
  64. }
  65. },
  66. data() {
  67. let nvue = false;
  68. // #ifdef APP-NVUE
  69. nvue = true;
  70. // #endif
  71. return {
  72. val: false,
  73. nvue: nvue,
  74. isLabel: false
  75. };
  76. },
  77. watch: {
  78. checked(val) {
  79. this.val = val;
  80. }
  81. },
  82. created() {
  83. this.val = this.checked;
  84. this.label = this.getParent();
  85. if (this.label) {
  86. this.isLabel = true
  87. this.label.childrens.push(this)
  88. }
  89. },
  90. methods: {
  91. change(e, label) {
  92. if (this.label && !label) return;
  93. this.val = e.detail.value;
  94. this.$emit('change', e)
  95. },
  96. labelClick() {
  97. if (this.disabled) return;
  98. let e = {
  99. detail: {
  100. value: !this.val
  101. }
  102. }
  103. this.change(e, true)
  104. },
  105. getParent(name = 'tui-label') {
  106. let parent = this.$parent;
  107. let parentName = parent.$options.name;
  108. while (parentName !== name) {
  109. parent = parent.$parent;
  110. if (!parent) return false;
  111. parentName = parent.$options.name;
  112. }
  113. return parent;
  114. }
  115. }
  116. }
  117. </script>
  118. <style scoped>
  119. /* #ifndef APP-NVUE */
  120. .tui-switch__input {
  121. display: inline-block;
  122. }
  123. /* #endif */
  124. .tui-checkbox__self {
  125. font-size: 0;
  126. width: 40rpx;
  127. height: 40rpx;
  128. /* #ifdef APP-NVUE */
  129. border-radius: 40rpx;
  130. /* #endif */
  131. /* #ifndef APP-NVUE */
  132. border-radius: 50%;
  133. display: inline-flex;
  134. box-sizing: border-box;
  135. vertical-align: top;
  136. /* #endif */
  137. flex-direction: row;
  138. align-items: center;
  139. justify-content: center;
  140. overflow: hidden;
  141. position: relative;
  142. }
  143. /* #ifdef H5 || APP-VUE */
  144. ::v-deep .uni-switch-input {
  145. margin-right: 0 !important;
  146. }
  147. /* #endif */
  148. /* #ifdef APP-NVUE */
  149. .uni-switch-input {
  150. margin-right: 0 !important;
  151. }
  152. /* #endif */
  153. /* #ifdef MP-WEIXIN */
  154. .wx-switch-input {
  155. margin-right: 0 !important;
  156. }
  157. /* #endif */
  158. .tui-check__mark {
  159. width: 20rpx;
  160. height: 40rpx;
  161. border-bottom-style: solid;
  162. border-bottom-width: 3px;
  163. border-bottom-color: #FFFFFF;
  164. border-right-style: solid;
  165. border-right-width: 3px;
  166. border-right-color: #FFFFFF;
  167. transform: rotate(45deg) scale(0.5);
  168. transform-origin: 54% 48%;
  169. /* #ifndef APP-NVUE */
  170. box-sizing: border-box;
  171. /* #endif */
  172. }
  173. .tui-switch__hidden {
  174. position: absolute;
  175. top: 0;
  176. left: 0;
  177. opacity: 0;
  178. z-index: 2;
  179. /* #ifndef APP-NVUE */
  180. width: 100%;
  181. height: 100%;
  182. border: 0 none;
  183. -webkit-appearance: none;
  184. -moz-appearance: none;
  185. appearance: none;
  186. /* #endif */
  187. /* #ifdef APP-NVUE */
  188. width: 100wx;
  189. height: 100wx;
  190. border-width: 0;
  191. /* #endif */
  192. }
  193. /* #ifdef H5 */
  194. .tui-pevents {
  195. pointer-events: none;
  196. }
  197. /* #endif */
  198. .tui-checkbox__disabled {
  199. opacity: 0.6;
  200. }
  201. </style>