在业务的实际使用中会存在批量搜索的需求,本文讲述如何实现基于element puls完成输入框的二次封装,使其可以批量粘贴近多个值,并使用逗号进行分隔方便进行批量搜索。
效果图
实现代码
BatchInput组文件
<template>
<el-input v-model="inputValue" :placeholder="props.placeholder" @input="updateVal">
<template #suffix>
<el-icon class="batch-icon" @click="handleBatchInput">
<Plus />
</el-icon>
</template>
</el-input>
<BatchInputDialog v-model:visible="batchInputVisible" @getDatas="getBatchDatas" :data="inputValue"></BatchInputDialog>
</template>
<script lang="ts" setup>
import { reactive, toRefs, watch } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import BatchInputDialog from '@comp/Dialog/BatchInputDialog.vue';
const props = defineProps({
modelValue: {
type: String,
required: true,
},
placeholder: {
type: String,
default: '支持批量搜索',
required: false,
},
});
const emit = defineEmits(['update:modelValue', 'input']);
const updateVal = value => {
emit('update:modelValue', value);
emit('input', value);
};
const state = reactive({
inputValue: '',
batchInputVisible: false,
});
const { inputValue, batchInputVisible } = toRefs(state);
watch(
() => props.modelValue,
value => {
state.inputValue = value;
},
{ immediate: true }
);
const handleBatchInput = () => {
state.batchInputVisible = true;
};
const getBatchDatas = value => {
if (value) {
updateVal(value);
}
};
</script>
<style scoped lang="scss">
.batch-icon {
cursor: pointer;
}
</style>
BatchInputDialog文件
<template>
<el-dialog v-model="props.visible" top="10px" :title="props.title" width="450px" :before-close="handleClose">
<el-form ref="queryParamsRef" :model="queryParams" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="" prop="value">
<el-input v-model="queryParams.value" :autosize="{ minRows: 16 }" type="textarea" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive, toRefs, watch } from 'vue';
const props = defineProps({
visible: {
type: Boolean,
default: false,
required: true,
},
title: {
type: String,
default: '请输入',
required: false,
},
data: {
type: String,
default: '',
required: false,
},
});
const state = reactive({
queryParams: <any>{
value: '',
},
});
// 把逗号分隔转换成空格换行
const formatBreak = value => {
var parts = value.split(',');
return parts.join('\n');
};
watch(
() => props.data,
value => {
state.queryParams.value = formatBreak(value);
},
{ immediate: true }
);
const { queryParams } = toRefs(state);
const emits = defineEmits<{
(e: 'update:visible', value): void;
(e: 'getDatas', value): void;
}>();
const handleClose = () => {
emits('update:visible', false);
};
// 把空格转换成逗号分隔
const formatString = input => {
var parts = input.split(/[ \n]+/);
return parts.join(',');
};
const handleConfirm = () => {
const result = formatString(state.queryParams.value);
emits('getDatas', result);
handleClose();
};
</script>
<style scoped lang="scss">
.selectioned {
color: var(--el-color-primary);
}
.image-info-wrap {
justify-content: center;
}
</style>
使用
<template>
<el-form ref="queryParamsRef" :model="queryParams" label-width="80px">
<el-row>
<el-col :span="6">
<el-form-item label="编码" prop="code">
<BatchInput v-model="queryParams.code"></BatchInput>
</el-form-item>
</el-col>
</el-row
</template>
<script lang="ts" setup>
import BatchInput from '@comp/BatchInput.vue';
import { reactive, ref, onMounted, watch, toRefs } from 'vue';
import type { FormInstance } from 'element-plus';
const state = reactive({
queryParams: <any>{
code: '',
},
queryParamsRef: <FormInstance>{},
});
const {
queryParams,
queryParamsRef
} = toRefs(state);
</script>