radio-group.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <component
  3. :is="_elTag"
  4. class="el-radio-group"
  5. role="radiogroup"
  6. @keydown="handleKeydown"
  7. >
  8. <slot></slot>
  9. </component>
  10. </template>
  11. <script>
  12. import Emitter from 'element-ui/src/mixins/emitter';
  13. const keyCode = Object.freeze({
  14. LEFT: 37,
  15. UP: 38,
  16. RIGHT: 39,
  17. DOWN: 40
  18. });
  19. export default {
  20. name: 'ElRadioGroup',
  21. componentName: 'ElRadioGroup',
  22. inject: {
  23. elFormItem: {
  24. default: ''
  25. }
  26. },
  27. mixins: [Emitter],
  28. props: {
  29. value: {},
  30. size: String,
  31. fill: String,
  32. textColor: String,
  33. disabled: Boolean
  34. },
  35. computed: {
  36. _elFormItemSize() {
  37. return (this.elFormItem || {}).elFormItemSize;
  38. },
  39. _elTag() {
  40. let tag = (this.$vnode.data || {}).tag;
  41. if (!tag || tag === 'component') tag = 'div';
  42. return tag;
  43. },
  44. radioGroupSize() {
  45. return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
  46. }
  47. },
  48. created() {
  49. this.$on('handleChange', value => {
  50. this.$emit('change', value);
  51. });
  52. },
  53. mounted() {
  54. // 当radioGroup没有默认选项时,第一个可以选中Tab导航
  55. const radios = this.$el.querySelectorAll('[type=radio]');
  56. const firstLabel = this.$el.querySelectorAll('[role=radio]')[0];
  57. if (![].some.call(radios, radio => radio.checked) && firstLabel) {
  58. firstLabel.tabIndex = 0;
  59. }
  60. },
  61. methods: {
  62. handleKeydown(e) { // 左右上下按键 可以在radio组内切换不同选项
  63. const target = e.target;
  64. const className = target.nodeName === 'INPUT' ? '[type=radio]' : '[role=radio]';
  65. const radios = this.$el.querySelectorAll(className);
  66. const length = radios.length;
  67. const index = [].indexOf.call(radios, target);
  68. const roleRadios = this.$el.querySelectorAll('[role=radio]');
  69. switch (e.keyCode) {
  70. case keyCode.LEFT:
  71. case keyCode.UP:
  72. e.stopPropagation();
  73. e.preventDefault();
  74. if (index === 0) {
  75. roleRadios[length - 1].click();
  76. roleRadios[length - 1].focus();
  77. } else {
  78. roleRadios[index - 1].click();
  79. roleRadios[index - 1].focus();
  80. }
  81. break;
  82. case keyCode.RIGHT:
  83. case keyCode.DOWN:
  84. if (index === (length - 1)) {
  85. e.stopPropagation();
  86. e.preventDefault();
  87. roleRadios[0].click();
  88. roleRadios[0].focus();
  89. } else {
  90. roleRadios[index + 1].click();
  91. roleRadios[index + 1].focus();
  92. }
  93. break;
  94. default:
  95. break;
  96. }
  97. }
  98. },
  99. watch: {
  100. value(value) {
  101. this.dispatch('ElFormItem', 'el.form.change', [this.value]);
  102. }
  103. }
  104. };
  105. </script>