index.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template>
  2. <view>
  3. <label :class="['nut-checkbox', 'nut-checkbox-size-' + currentSize]">
  4. <input
  5. type="checkbox"
  6. :name="name"
  7. :class="{ 'nut-checkbox-ani': isAnimated }"
  8. :disabled="isDisabled"
  9. :checked.prop="isChecked"
  10. :value="submittedValue"
  11. @change="changeEvt"
  12. />
  13. <span class="nut-checkbox-label" v-if="label">
  14. {{ label }}
  15. </span>
  16. <span class="nut-checkbox-label" v-else>
  17. <slot></slot>
  18. </span>
  19. </label>
  20. </view>
  21. </template>
  22. <script lang="ts">
  23. import {
  24. reactive,
  25. ref,
  26. toRefs,
  27. watch,
  28. watchEffect,
  29. computed,
  30. getCurrentInstance,
  31. inject
  32. } from 'vue';
  33. import { createComponent } from '@/utils/create';
  34. const { componentName, create } = createComponent('checkbox');
  35. export default create({
  36. props: {
  37. name: {
  38. type: String
  39. },
  40. size: {
  41. type: [String, Number, Boolean],
  42. default: 'base'
  43. },
  44. label: {
  45. type: String,
  46. default: ''
  47. },
  48. modelValue: {
  49. required: true
  50. },
  51. trueValue: {
  52. default: true
  53. },
  54. falseValue: {
  55. default: false
  56. },
  57. submittedValue: {
  58. type: String,
  59. default: 'on' // HTML default
  60. },
  61. checked: {
  62. type: Boolean,
  63. default: false
  64. },
  65. disabled: {
  66. type: Boolean,
  67. default: false
  68. },
  69. animation: {
  70. type: Boolean,
  71. default: true
  72. }
  73. },
  74. components: {},
  75. setup(props, { emit }) {
  76. const parentGroup = inject('checkboxgroup', {
  77. parentNode: false,
  78. changeVal: val => {
  79. console.log();
  80. }
  81. });
  82. const parentProps = getCurrentInstance()?.parent?.props;
  83. const isChecked = computed(() => {
  84. if (parentGroup && parentGroup.parentNode) {
  85. const choosedVal = parentProps?.modelValue;
  86. const chooseFlag =
  87. (choosedVal as any).indexOf(props.label) == -1 ? false : true;
  88. return chooseFlag;
  89. } else {
  90. const isCheckedVal =
  91. props.modelValue == props.trueValue || props.checked;
  92. return isCheckedVal;
  93. }
  94. });
  95. // const isCheckedVal = props.modelValue == props.trueValue || props.checked;
  96. // const isChecked = ref(isCheckedVal);
  97. const isObject = obj => {
  98. return obj !== null && typeof obj === 'object';
  99. };
  100. // const looseEqual = (a, b) => {
  101. // return (
  102. // a == b ||
  103. // (isObject(a) && isObject(b)
  104. // ? JSON.stringify(a) === JSON.stringify(b)
  105. // : false)
  106. // );
  107. // };
  108. const isDisabled = computed(() => {
  109. if (parentGroup && parentGroup.parentNode) {
  110. return parentProps?.disabled;
  111. } else {
  112. return props.disabled;
  113. }
  114. });
  115. const currentSize = computed(() => {
  116. if (parentGroup && parentGroup.parentNode) {
  117. return parentProps?.size;
  118. } else {
  119. return props.size;
  120. }
  121. });
  122. const isAnimated = computed(() => {
  123. if (parentGroup && parentGroup.parentNode) {
  124. return parentProps?.animated;
  125. } else {
  126. return props.animation;
  127. }
  128. });
  129. const { label, name, submittedValue } = reactive(props);
  130. const setParentValue = checked => {
  131. // const { label } = props;
  132. // const { max, modelValue } = parentProps?.modelValue;
  133. const modelValue = parentProps?.modelValue;
  134. const value = (modelValue as any).slice();
  135. if (checked) {
  136. if (value.indexOf(label) === -1) {
  137. value.push(label);
  138. parentGroup?.changeVal(value);
  139. }
  140. } else {
  141. const index = value.indexOf(label);
  142. if (index !== -1) {
  143. value.splice(index, 1);
  144. parentGroup?.changeVal(value);
  145. }
  146. }
  147. };
  148. const changeEvt = (event: any) => {
  149. event?.stopPropagation();
  150. const isCheck: boolean = event.target.checked;
  151. if (isDisabled.value) {
  152. return false;
  153. }
  154. if (parentGroup.parentNode) {
  155. setParentValue(isCheck);
  156. return false;
  157. }
  158. emit('update:modelValue', isCheck);
  159. emit(
  160. 'input',
  161. isCheck ? props.trueValue : props.falseValue,
  162. props.label,
  163. event
  164. );
  165. if (isChecked.value !== isCheck) {
  166. emit(
  167. 'change',
  168. isCheck ? props.trueValue : props.falseValue,
  169. props.label,
  170. event
  171. );
  172. }
  173. };
  174. return {
  175. currentSize,
  176. label,
  177. name,
  178. isDisabled,
  179. submittedValue,
  180. isAnimated,
  181. isChecked,
  182. changeEvt
  183. };
  184. }
  185. });
  186. </script>
  187. <style lang="scss">
  188. @import 'index.scss';
  189. </style>