element plus基于输入框的二次封装,批量输入

521 阅读1分钟

在业务的实际使用中会存在批量搜索的需求,本文讲述如何实现基于element puls完成输入框的二次封装,使其可以批量粘贴近多个值,并使用逗号进行分隔方便进行批量搜索。

效果图

df5ad721-5cc6-4a87-939a-138507481e08.gif

实现代码

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>