index.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { h, defineComponent, computed, ref, watch } from 'vue'
  2. import { ElForm, ElFormItem } from 'element-plus'
  3. import CipButton from '../cip-button'
  4. import CipFormItem from '../cip-form-item'
  5. import { debounce, isNumber, getUsingConfig } from '@cip/utils/util'
  6. import { useFormProvide } from '../hooks/use-form'
  7. import { useObserveDomResize } from '../hooks/use-dom-resize'
  8. import { cipSearchFormProps } from './props'
  9. import './index.less'
  10. import { useCipConfig } from '@cip/components/hooks/use-cip-config'
  11. // cip-search-form 强制开启grid模式
  12. export default defineComponent({
  13. name: 'CipSearchForm',
  14. props: cipSearchFormProps,
  15. emits: ['update:model', 'search'],
  16. setup (props, { emit, attrs }) {
  17. useFormProvide(props)
  18. const cipConfig = useCipConfig()
  19. const cipSearchForm = ref()
  20. const contentWidth = ref(1000)
  21. useObserveDomResize(() => cipSearchForm.value.$el, (e) => {
  22. contentWidth.value = e.contentRect.width
  23. })
  24. // 值更新
  25. const updateModel = (val) => { emit('update:model', val) }
  26. // 触发搜索
  27. const emitSearch = debounce((type) => { emit('search', type) }, 200, false)
  28. const resetSearch = () => {
  29. // 重置的时候载入默认model
  30. updateModel({ ...props.defaultModel })
  31. emitSearch('reset')
  32. }
  33. const isExpand = ref(false)
  34. const toggleExpand = () => {
  35. isExpand.value = !isExpand.value
  36. }
  37. // 1366使用3列,1920使用5列,默认4列
  38. const gridCount = computed(() => {
  39. const grid = getUsingConfig(props.grid, cipConfig.searchGrid)
  40. if (isNumber(grid) && grid > 0) return grid // 过滤grid为数字且grid>0 则使用固定的列
  41. return Math.max(2, Math.floor(contentWidth.value / 335)) // contentWidth.value < 1300 ? 3 : (contentWidth.value > 1900 ? 5 : 4)
  42. })
  43. // 展示数量列表
  44. const fieldShowList = computed(() => {
  45. if (!props.collapse) {
  46. return props.fieldList
  47. } else {
  48. return isExpand.value ? props.fieldList : props.fieldList.filter((item, index) => index < gridCount.value - 1)
  49. }
  50. })
  51. const isImmediateSearch = (config) => {
  52. return config.immediateSearch === true || config.autoSelect === true
  53. }
  54. const showResetButton = computed(() => {
  55. return getUsingConfig(props.searchReset, cipConfig.searchReset)
  56. })
  57. const showExpandButton = computed(() => {
  58. return props.collapse && props.fieldList.length >= gridCount.value
  59. })
  60. const arrowIcon = computed(() => {
  61. return isExpand.value ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
  62. })
  63. const formItem = ({ key, config } = {}) => {
  64. return h(CipFormItem, {
  65. key,
  66. model: props.model,
  67. fieldKey: key,
  68. config: config,
  69. grid: true,
  70. onKeyup: (e) => {
  71. const { keyCode } = e
  72. if (keyCode === 13) {
  73. emitSearch()
  74. }
  75. },
  76. onSearch: () => {
  77. emitSearch()
  78. },
  79. 'onUpdate:model': (val) => {
  80. updateModel(val)
  81. // 值变更时立即搜索
  82. if (isImmediateSearch(config)) emitSearch()
  83. }
  84. })
  85. }
  86. const formItemList = () => fieldShowList.value.map(formItem)
  87. const formDefaultSlots = () => {
  88. const slots = formItemList() || []
  89. if (!props.hideSearch) {
  90. // 是否仅一个搜索条件
  91. const isOne = fieldShowList.value.length === 1
  92. const buttonList = <ElFormItem class={['cip-search-button', { 'cip-search-button--right': !isOne }]}
  93. style={{
  94. alignItems: props.labelPosition === 'top' ? 'flex-end' : 'flex-start',
  95. gridColumn: !isOne ? `${gridCount.value} / span 1` : undefined
  96. }}
  97. >
  98. <CipButton buttonType={'search'} onClick={() => emitSearch()}>
  99. {{ default: ({ text }) => props.searchButtonText ?? text }}
  100. </CipButton>
  101. {showResetButton.value && <CipButton buttonType={'reset'} onClick={() => resetSearch()}/>}
  102. {showExpandButton.value && <CipButton buttonType={'expend'} style={{ paddingLeft: '8px', paddingRight: '8px' }} onClick={() => toggleExpand()}><i class={arrowIcon.value}/></CipButton>}
  103. </ElFormItem>
  104. slots.push(buttonList)
  105. }
  106. return slots
  107. }
  108. if (props.hideSearch) { // 一次性配置不进行响应
  109. isExpand.value = true
  110. }
  111. return () => h(ElForm, {
  112. ...attrs,
  113. ref: cipSearchForm,
  114. class: 'cip-search-form',
  115. labelPosition: props.labelPosition,
  116. size: 'small',
  117. style: { gridTemplateColumns: `repeat(${gridCount.value}, 1fr)` },
  118. onSubmit: (e) => {
  119. e.preventDefault()
  120. emitSearch()
  121. } // 防止只有一个搜索项时按会车直接提交form的默认行为
  122. }, { default: formDefaultSlots })
  123. }
  124. })