vue3ts+element-plus实现点击el-select下拉选择内容填充和编辑内容

发布于:2024-08-18 ⋅ 阅读:(124) ⋅ 点赞:(0)

需求在填写报表时,既可以选择下拉选项,还可以编辑选的内容, 找了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>


目前已满足需求使用,当笔记记录下过程;
写在最后,有想法可以一起交流交流,欢迎各位大佬洽谈交流
前端学习社区交流群


网站公告

今日签到

点亮在社区的每一天
去签到