需求在填写报表时,既可以选择下拉选项,还可以编辑选的内容, 找了elementUi没有现成的就自己组装一个
效果:
贴代码:
在components下新建文件夹TextareaSelect,再新建index.vue和interface.ts (这里是vue3+ts)
<!-- TextareaSelect/index.vue -->
<template>
<div class="flex" id="textarea">
<el-select
ref="selectRef"
:placeholder="placeholder"
@change="updateTextField"
style="width: 20px"
>
<el-option
v-for="(item, index) in options"
:key="index"
:label="item[props.label]"
:value="item[props.value]"
/>
</el-select>
<el-input
v-model="inputValue"
type="textarea"
:rows="2"
style="margin-left: 20px"
/>
</div>
</template>
<script setup lang="ts" name="TextareaSelect">
import { computed, inject, ref, watch } from "vue";
import { TextareaSelect } from "./interface";
import { formItemContextKey } from "element-plus";
const formItemContext = inject(formItemContextKey, undefined); // 表单Item实例
const emit = defineEmits(["update:modelValue", "updateValue"]); // 定义emit
// 定义组件属性
const props = withDefaults(defineProps<TextareaSelect>(), {
options: () => [],
value: "value",
label: "label",
modelValue: "",
});
const inputValue = ref(props.modelValue);
// 更新文本域的内容
function updateTextField(value: string) {
const foundOption = props.options.find((opt) => opt[props.value] === value);
if (foundOption) {
inputValue.value = foundOption[props.label];
}
}
// 监听 inputValue 的变化
watch(inputValue, (value) => {
emit("update:modelValue", value);
emit("updateValue", value);
});
// 监听 props.modelValue 的变化
watch(
() => props.modelValue,
(value) => {
inputValue.value = value;
}
);
const placeholder = computed(() => {
return "请选择" + (formItemContext?.label || "");
});
</script>
<style scoped>
/* 使用全局+#id覆盖原el-select样式 */
:global(#textarea .el-select__wrapper) {
background-color: transparent !important;
box-shadow: 0 0 0 0 !important;
}
.flex {
display: flex;
align-items: flex-start;
}
</style>
// TextareaSelect/interface.ts
export interface TextareaSelect {
/** 选项数组 */
options: any[];
/** 选项显示标签 */
label?: string;
/** 选项值 */
value?: string;
/** 默认值 */
modelValue?: any;
}
引入页面使用
<template>
<pre>下拉选择内容添加进文本域,也可以编辑(回显,双向绑定)</pre>
<TextareaSelect
v-model="formData.textContent"
:options="options"
@update-value="formData.textContent"
/>
结果:{{ formData }}
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import TextareaSelect from "/src/components/TextareaSelect/index.vue";
const formData = reactive({
textContent: "回显数据",
});
const options = [
{
value: "val1",
label: "label1",
},
{
value: "val2",
label: "label2",
},
{
value: "val3",
label: "label3",
},
];
</script>
目前已满足需求使用,当笔记记录下过程;
写在最后,有想法可以一起交流交流,欢迎各位大佬洽谈交流
【前端学习社区交流群】