test.vue 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <template>
  2. <UItext
  3. :disabled="props.disabled"
  4. class="select"
  5. :class="{ ready, focus: showOptions }"
  6. ref="vmRef"
  7. v-model="inputValue"
  8. :width="props.width"
  9. :height="props.height"
  10. readonly
  11. :placeholder="props.placeholder"
  12. @blur="blurHandler"
  13. @click="changShow(!showOptions)"
  14. >
  15. <template #icon>
  16. <icon type="pull-down" small />
  17. </template>
  18. </UItext>
  19. <UIFloating :mount="mountEl" :refer="vmRef && vmRef.root">
  20. <ul class="select-replace" :class="{ ready }" :style="originHeight && { 'max-height': maxHeight + 'px' }" ref="contentRef">
  21. <li v-for="option in props.options" :key="option.value" :class="{ active: props.modelValue === option.value }" @click="optionClickHandler(option)">
  22. {{ option.label }}
  23. </li>
  24. </ul>
  25. </UIFloating>
  26. </template>
  27. <script setup lang="ts">
  28. import UItext from './text.vue'
  29. import UIFloating from '../floating/index.vue'
  30. import { ref, onUnmounted, computed } from 'vue'
  31. import { selectPropsDesc } from './state'
  32. import icon from '../icon'
  33. import { changeWHFactory } from '../../utils'
  34. const props = defineProps(selectPropsDesc)
  35. const emit = defineEmits(['update:modelValue'])
  36. const vmRef = ref(null)
  37. const mountEl = document.body
  38. let timeout: number
  39. const inputValue = computed(() => {
  40. const selectOption = props.options.find(({ value }) => value === props.modelValue)
  41. return selectOption ? selectOption.label : ''
  42. })
  43. const [contentRef, changShow, maxHeight, originHeight, showOptions, ready] = changeWHFactory()
  44. const optionClickHandler = option => {
  45. emit('update:modelValue', option.value)
  46. vmRef.value.input.focus()
  47. changShow(false)
  48. }
  49. const blurHandler = () => {
  50. timeout = setTimeout(() => changShow(false), 500)
  51. }
  52. const attach = document.documentElement
  53. const htmlClickHandler = ev => {
  54. if (vmRef.value.root.contains(ev.target)) {
  55. clearTimeout(timeout)
  56. } else {
  57. changShow(false)
  58. }
  59. }
  60. attach.addEventListener('click', htmlClickHandler)
  61. onUnmounted(() => {
  62. attach.removeEventListener('click', htmlClickHandler)
  63. })
  64. </script>