u-radio.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <template>
  2. <view class="u-radio" :style="[radioStyle]">
  3. <view class="u-radio__icon-wrap" @tap="toggle">
  4. <u-icon :class="iconClass" name="checkbox-mark" :size="iconSize" :color="iconColor" class="u-radio__icon" :style="[iconStyle]" />
  5. </view>
  6. <view class="u-label-class u-radio__label" @tap="onClickLabel" :style="{
  7. fontSize: labelSize + 'rpx'
  8. }">
  9. <slot />
  10. </view>
  11. </view>
  12. </template>
  13. <script>
  14. /**
  15. * radio 单选框
  16. * @description 单选框用于有一个选择,用户只能选择其中一个的场景。搭配u-radio-group使用
  17. * @tutorial https://www.uviewui.com/components/radio.html
  18. * @property {String Number} icon-size 图标大小,单位rpx(默认24)
  19. * @property {String Number} label-size label字体大小,单位rpx(默认28)
  20. * @property {String Number} name radio组件的标示符
  21. * @property {String} shape 形状,见上方说明(默认circle)
  22. * @property {Boolean} disabled 是否禁用(默认false)
  23. * @property {Boolean} label-disabled 点击文本是否可以操作radio(默认true)
  24. * @property {String} active-color 选中时的颜色,如设置radioGroup的active-color将失效
  25. * @event {Function} change 某个radio状态发生变化时触发(选中状态)
  26. * @example <u-radio :label-disabled="false">门掩黄昏,无计留春住</u-radio>
  27. */
  28. export default {
  29. name: "u-radio",
  30. props: {
  31. // radio的名称
  32. name: {
  33. type: [String, Number],
  34. default: ''
  35. },
  36. // 形状,square为方形,circle为原型
  37. shape: {
  38. type: String,
  39. default: 'square'
  40. },
  41. // 是否禁用
  42. disabled: {
  43. type: Boolean,
  44. default: false
  45. },
  46. // 是否禁止点击提示语选中复选框
  47. labelDisabled: {
  48. type: Boolean,
  49. default: false
  50. },
  51. // 选中状态下的颜色,如设置此值,将会覆盖radioGroup的activeColor值
  52. activeColor: {
  53. type: String,
  54. default: ''
  55. },
  56. // 图标的大小,单位rpx
  57. iconSize: {
  58. type: [String, Number],
  59. default: 20
  60. },
  61. // label的字体大小,rpx单位
  62. labelSize: {
  63. type: [String, Number],
  64. default: 28
  65. },
  66. },
  67. inject: ['radioGroup'],
  68. data() {
  69. return {
  70. parentDisabled: false
  71. };
  72. },
  73. created() {
  74. this.parentDisabled = this.radioGroup.disabled;
  75. },
  76. computed: {
  77. // 设置radio的状态,要求radio的name等于radioGroup的value时才为选中状态
  78. iconStyle() {
  79. let style = {};
  80. if (this.radioActiveColor && this.name == this.radioGroup.value && !this.disabled && !this.parentDisabled) {
  81. style.borderColor = this.radioActiveColor;
  82. style.backgroundColor = this.radioActiveColor;
  83. }
  84. style.width = this.radioGroup.size + 'rpx';
  85. style.height = this.radioGroup.size + 'rpx';
  86. return style;
  87. },
  88. iconColor() {
  89. return this.name == this.radioGroup.value ? '#ffffff' : 'transparent';
  90. },
  91. iconClass() {
  92. let classs = [];
  93. classs.push('u-radio__icon--' + this.shape);
  94. if (this.name == this.radioGroup.value) classs.push('u-radio__icon--checked');
  95. if (this.disabled || this.parentDisabled) classs.push('u-radio__icon--disabled');
  96. if (this.name == this.radioGroup.value && (this.disabled || this.parentDisabled)) classs.push(
  97. 'u-radio__icon--disabled--checked');
  98. return classs;
  99. },
  100. // 激活的颜色,可能受radioGroup和本组件的activeColor影响
  101. // 本组件的activeColor值优先
  102. radioActiveColor() {
  103. return this.activeColor ? this.activeColor : this.radioGroup.activeColor;
  104. },
  105. radioStyle() {
  106. let style = {};
  107. if(this.radioGroup.width) {
  108. style.width = this.radioGroup.width;
  109. // #ifdef MP
  110. // 各家小程序因为它们特殊的编译结构,使用float布局
  111. style.float = 'left';
  112. // #endif
  113. // #ifndef MP
  114. // H5和APP使用flex布局
  115. style.flex = `0 0 ${this.radioGroup.width}`;
  116. // #endif
  117. }
  118. if(this.radioGroup.wrap) {
  119. style.width = '100%';
  120. // #ifndef MP
  121. // H5和APP使用flex布局,将宽度设置100%,即可自动换行
  122. style.flex = '0 0 100%';
  123. // #endif
  124. }
  125. return style;
  126. }
  127. },
  128. methods: {
  129. onClickLabel() {
  130. if (!this.disabled && !this.labelDisabled && !this.parentDisabled) {
  131. this.radioGroup.setValue(this.name);
  132. this.emitEvent();
  133. }
  134. },
  135. toggle() {
  136. if (!this.disabled && !this.parentDisabled) {
  137. this.radioGroup.setValue(this.name);
  138. this.emitEvent();
  139. }
  140. },
  141. emitEvent() {
  142. this.$emit('change', this.name)
  143. },
  144. }
  145. };
  146. </script>
  147. <style lang="scss" scoped>
  148. .u-radio {
  149. display: -webkit-flex;
  150. display: flex;
  151. -webkit-align-items: center;
  152. align-items: center;
  153. overflow: hidden;
  154. -webkit-user-select: none;
  155. user-select: none;
  156. line-height: 1.8;
  157. }
  158. .u-radio__icon-wrap,
  159. .u-radio__label {
  160. color: $u-content-color;
  161. }
  162. .u-radio__icon-wrap {
  163. -webkit-flex: none;
  164. flex: none;
  165. }
  166. .u-radio__icon {
  167. display: -webkit-flex;
  168. display: flex;
  169. -webkit-align-items: center;
  170. align-items: center;
  171. -webkit-justify-content: center;
  172. justify-content: center;
  173. box-sizing: border-box;
  174. width: 42rpx;
  175. height: 42rpx;
  176. color: transparent;
  177. text-align: center;
  178. transition-property: color, border-color, background-color;
  179. font-size: 20px;
  180. border: 1px solid #c8c9cc;
  181. transition-duration: 0.2s;
  182. }
  183. .u-radio__icon--circle {
  184. border-radius: 100%;
  185. }
  186. .u-radio__icon--square {
  187. border-radius: 3px;
  188. }
  189. .u-radio__icon--checked {
  190. color: #fff;
  191. background-color: #2979ff;
  192. border-color: #2979ff;
  193. }
  194. .u-radio__icon--disabled {
  195. background-color: #ebedf0;
  196. border-color: #c8c9cc;
  197. }
  198. .u-radio__icon--disabled--checked {
  199. color: #c8c9cc !important;
  200. }
  201. .u-radio__label {
  202. word-wrap: break-word;
  203. margin-left: 10rpx;
  204. margin-right: 24rpx;
  205. color: $u-content-color;
  206. font-size: 30rpx;
  207. }
  208. .u-radio__label--disabled {
  209. color: #c8c9cc;
  210. }
  211. .u-radio__label:empty {
  212. margin: 0;
  213. }
  214. </style>