DefaultInput.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <template>
  2. <div class="column" :class="attrs.class" :style="attrs.style">
  3. <div class="col">
  4. <q-input
  5. ref="inputRef"
  6. v-model="model"
  7. v-bind="inputAttrs"
  8. hide-bottom-space
  9. label-color="secondary"
  10. color="secondary"
  11. :label
  12. :error="!!error"
  13. :error-message="errorMessage"
  14. :rules
  15. :outlined
  16. :bg-color
  17. :class="inputClass"
  18. :input-class="nativeInputClass"
  19. @update:model-value="error = null"
  20. >
  21. <template #append>
  22. <slot name="append">
  23. <q-icon v-if="icon" :name="icon" size="sm" color="secondary" />
  24. </slot>
  25. </template>
  26. </q-input>
  27. </div>
  28. </div>
  29. </template>
  30. <script setup>
  31. import {
  32. ref,
  33. onBeforeMount,
  34. useAttrs,
  35. computed,
  36. watch,
  37. useTemplateRef,
  38. } from "vue";
  39. defineOptions({
  40. inheritAttrs: false,
  41. });
  42. const { label, nativeInputClass, inputClass, rules, icon, bgColor, outlined } =
  43. defineProps({
  44. label: {
  45. type: String,
  46. default: "",
  47. },
  48. icon: {
  49. type: String,
  50. default: "",
  51. },
  52. rules: {
  53. type: Array,
  54. default: () => [],
  55. },
  56. nativeInputClass: {
  57. type: String,
  58. default: null,
  59. },
  60. inputClass: {
  61. type: String,
  62. default: null,
  63. },
  64. bgColor: {
  65. type: String,
  66. default: "white",
  67. },
  68. outlined: {
  69. type: Boolean,
  70. default: false,
  71. },
  72. });
  73. const attrs = useAttrs();
  74. const inputRef = useTemplateRef("inputRef");
  75. const model = defineModel({ type: [String, Object, Array, Boolean, null] });
  76. const error = defineModel("error", {
  77. type: [String, Object, Array, Boolean, null],
  78. });
  79. const required = ref(false);
  80. const inputAttrs = computed(() => {
  81. // eslint-disable-next-line
  82. const { class: _, style: __, ...rest } = attrs;
  83. return rest;
  84. });
  85. const errorMessage = computed(() => {
  86. if (error.value == null) {
  87. return void 0;
  88. }
  89. if (typeof error.value === "boolean") {
  90. return void 0;
  91. }
  92. return String(error.value);
  93. });
  94. watch(
  95. () => rules,
  96. (values) => {
  97. values.forEach((r) => {
  98. if (r?.$id === "required") return (required.value = true);
  99. });
  100. },
  101. );
  102. onBeforeMount(() => {
  103. rules.forEach((r) => {
  104. if (r?.$id === "required") return (required.value = true);
  105. });
  106. });
  107. defineExpose({
  108. inputRef,
  109. });
  110. </script>
  111. <style scoped lang="scss">
  112. :deep(.q-field--outlined.q-field--rounded .q-field__control) {
  113. border-radius: 8px;
  114. }
  115. </style>