search-form.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <!-- 搜索框入口 -->
  3. <wd-search
  4. :placeholder="searchPlaceholder"
  5. :hide-cancel="true"
  6. disabled
  7. @click="visible = true"
  8. />
  9. <!-- 搜索弹窗 -->
  10. <wd-popup
  11. v-model="visible"
  12. position="top"
  13. custom-style="border-radius: 0 0 24rpx 24rpx;"
  14. safe-area-inset-top
  15. @close="visible = false"
  16. >
  17. <view class="p-32rpx">
  18. <view class="mb-24rpx text-32rpx text-[#333] font-semibold">
  19. 搜索角色
  20. </view>
  21. <view class="mb-24rpx">
  22. <view class="mb-12rpx text-28rpx text-[#666]">
  23. 角色名称
  24. </view>
  25. <wd-input
  26. v-model="formData.name"
  27. placeholder="请输入角色名称"
  28. clearable
  29. />
  30. </view>
  31. <view class="mb-24rpx">
  32. <view class="mb-12rpx text-28rpx text-[#666]">
  33. 角色标识
  34. </view>
  35. <wd-input
  36. v-model="formData.code"
  37. placeholder="请输入角色标识"
  38. clearable
  39. />
  40. </view>
  41. <view class="mb-32rpx">
  42. <view class="mb-12rpx text-28rpx text-[#666]">
  43. 状态
  44. </view>
  45. <wd-radio-group v-model="formData.status" shape="button" size="medium">
  46. <wd-radio :value="-1">
  47. 全部
  48. </wd-radio>
  49. <wd-radio :value="0">
  50. 启用
  51. </wd-radio>
  52. <wd-radio :value="1">
  53. 禁用
  54. </wd-radio>
  55. </wd-radio-group>
  56. </view>
  57. <view class="w-full flex justify-center gap-24rpx">
  58. <wd-button class="flex-1" plain @click="handleReset">
  59. 重置
  60. </wd-button>
  61. <wd-button class="flex-1" type="primary" @click="handleSearch">
  62. 搜索
  63. </wd-button>
  64. </view>
  65. </view>
  66. </wd-popup>
  67. </template>
  68. <script lang="ts" setup>
  69. import { computed, reactive, ref, watch } from 'vue'
  70. /** 搜索表单数据 */
  71. export interface SearchFormData {
  72. name?: string
  73. code?: string
  74. status: number // -1 表示全部
  75. }
  76. const props = defineProps<{
  77. searchParams?: Partial<SearchFormData> // 初始搜索参数
  78. }>()
  79. const emit = defineEmits<{
  80. 'search': [data: SearchFormData]
  81. 'reset': []
  82. }>()
  83. const visible = ref(false)
  84. /** 搜索条件 placeholder 拼接 */
  85. const searchPlaceholder = computed(() => {
  86. const conditions: string[] = []
  87. if (props.searchParams?.name) {
  88. conditions.push(`名称:${props.searchParams.name}`)
  89. }
  90. if (props.searchParams?.code) {
  91. conditions.push(`标识:${props.searchParams.code}`)
  92. }
  93. if (props.searchParams?.status !== undefined && props.searchParams.status !== -1) {
  94. conditions.push(`状态:${props.searchParams.status === 0 ? '启用' : '禁用'}`)
  95. }
  96. return conditions.length > 0 ? conditions.join(' | ') : '搜索角色'
  97. })
  98. const formData = reactive<SearchFormData>({
  99. name: undefined,
  100. code: undefined,
  101. status: -1,
  102. })
  103. /** 监听弹窗打开,同步外部参数 */
  104. watch(visible, (val) => {
  105. if (val && props.searchParams) {
  106. formData.name = props.searchParams.name
  107. formData.code = props.searchParams.code
  108. formData.status = props.searchParams.status ?? -1
  109. }
  110. })
  111. /** 搜索 */
  112. function handleSearch() {
  113. visible.value = false
  114. emit('search', { ...formData })
  115. }
  116. /** 重置 */
  117. function handleReset() {
  118. formData.name = undefined
  119. formData.code = undefined
  120. formData.status = -1
  121. visible.value = false
  122. emit('reset')
  123. }
  124. </script>