vue3+ts实现一个下拉选择框组件,支持搜索和多级联动

<template>
  <div class="multi-select-dropdown">
    <input type="text" v-model="searchText" @input="filterOptions" placeholder="搜索..." />
    <select v-model="selected" @change="handleChange">
      <option v-for="option in filteredOptions" :key="option.value" :value="option.value">
        {{ option.label }}
      </option>
    </select>
    <div v-if="showSubOptions" class="sub-options">
      <!-- 子级下拉框 -->
      <select v-model="selectedSubOption">
        <option v-for="subOption in subOptions" :key="subOption.value" :value="subOption.value">
          {{ subOption.label }}
        </option>
      </select>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

// 定义 props
const props = defineProps<{
  options: Array<{ value: string; label: string; children?: Array<{ value: string; label: string }> }>;
}>();

// 定义 emits
const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void;
  (e: 'change', value: string): void;
}>();

// 数据
const searchText = ref('');
const selected = ref('');
const showSubOptions = ref(false);
const selectedSubOption = ref('');

// 计算属性
const filteredOptions = computed(() => {
  return props.options.filter(option => option.label.includes(searchText.value));
});

// 方法
const handleChange = () => {
  const selectedOption = props.options.find(option => option.value === selected.value);
  if (selectedOption && selectedOption.children) {
    showSubOptions.value = true;
  } else {
    showSubOptions.value = false;
  }
  emit('change', selected.value);
};

const filterOptions = () => {
  // 根据搜索文本过滤选项
};

// 监听 selected 的变化,更新父组件
watch(selected, (newValue) => {
  emit('update:modelValue', newValue);
});
</script>

<style scoped>
.multi-select-dropdown {
  /* 样式 */
}
.sub-options {
  /* 子级下拉框样式 */
}
</style>

在这个组件中,我们使用了 defineProps 来定义组件的属性,defineEmits 来定义组件可以触发的事件。组件内部使用了 refcomputed 来管理数据和计算属性,以及 watch 来监听数据变化并更新父组件。

父组件可以通过 v-model 或事件监听来与这个子组件进行交互。例如:

<template>
  <div>
    <multi-select-dropdown :options="options" v-model="selectedValue" @change="handleChange" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import MultiSelectDropdown from './MultiSelectDropdown.vue';

const options = [
  { value: '1', label: '选项1', children: [{ value: '1-1', label: '子选项1-1' }] },
  { value: '2', label: '选项2', children: [{ value: '2-1', label: '子选项2-1' }] },
  // 更多选项...
];

const selectedValue = ref('');

const handleChange = (value: string) => {
  console.log('Selected value changed to:', value);
};
</script>
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会尽力为您解答。首先,我们需要使用Vue3和TypeScript来创建一个选择列表页,然后添加上传功能。 1. 创建Vue组件 我们可以使用`defineComponent`函数来创建组件,并在组件中定义所需的数据和方法。这里我们创建一个名为`ListPage`的组件,它包含一个下拉选择一个上传按钮。 ```typescript import { defineComponent } from 'vue'; export default defineComponent({ name: 'ListPage', data() { return { options: [ { label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }, ], selectedOption: '', }; }, methods: { handleUpload() { // TODO: 实现上传功能 }, }, template: ` <div> <select v-model="selectedOption"> <option v-for="option in options" :value="option.value">{{ option.label }}</option> </select> <button @click="handleUpload">上传</button> </div> `, }); ``` 2. 添加上传功能 为了实现上传功能,我们可以使用`FormData`对象来构建一个包含文件的表单数据,并使用`axios`库将其发送到服务器。 首先,我们需要安装`axios`库: ```bash npm install axios ``` 然后,我们可以在`handleUpload`方法中添加上传逻辑: ```typescript import { defineComponent } from 'vue'; import axios from 'axios'; export default defineComponent({ name: 'ListPage', data() { return { options: [ { label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }, ], selectedOption: '', file: null, }; }, methods: { handleFileChange(event: Event) { const target = event.target as HTMLInputElement; this.file = target.files?.[0]; }, async handleUpload() { const formData = new FormData(); formData.append('file', this.file); formData.append('selectedOption', this.selectedOption); const response = await axios.post('/api/upload', formData); console.log(response.data); }, }, template: ` <div> <select v-model="selectedOption"> <option v-for="option in options" :value="option.value">{{ option.label }}</option> </select> <input type="file" @change="handleFileChange"> <button @click="handleUpload" :disabled="!selectedOption || !file">上传</button> </div> `, }); ``` 在`handleUpload`方法中,我们首先创建一个`FormData`对象,并将文件和选择的选项添加到表单数据中。然后,我们使用`axios.post`方法将表单数据发送到服务器。在这个例子中,我们假设服务器的上传接口是`/api/upload`,并打印服务器响应的数据。最后,我们将上传按钮的`disabled`属性绑定到选择的选项和文件是否存在的条件,以防止用户上传无效的数据。 以上就是用Vue3和TypeScript创建可选择列表页并实现上传功能的步骤。希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温暖前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值