index.jsx 5.1 KB

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