tui-radio.vue 4.1 KB

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