Electron for OpenHarmony 实战:Select 选择器组件实现 PC适配
本文介绍了在Electron for OpenHarmony项目中使用Element Plus的Select选择器组件的方法。选择器适用于固定选项的场景,能提升用户体验和操作效率。文章详细讲解了基础选择器、可清空选择器、多选模式、可搜索选择器、禁用状态和分组选项等常见功能的实现方式,包括v-model绑定、数据准备、属性配置等核心内容。通过代码示例展示了如何创建不同功能的选择器组件,帮助开发者快速
表单里除了输入框,用得最多的就是选择器了。当选项是固定的几个值时,让用户从下拉列表里选比让他手动输入要靠谱得多,既能避免输入错误,也能提升操作效率。这篇文章来聊聊在 Electron for OpenHarmony 项目中如何实现 Select 选择器组件。
选择器的应用场景
在实际项目中,选择器的使用场景非常多:性别选择、省市区级联、状态筛选、分类选择等等。相比原生的 select 标签,Element Plus 的 el-select 组件功能强大很多,支持搜索过滤、多选、远程加载、自定义模板等高级特性,而且样式统一美观,不会出现不同浏览器显示效果不一致的问题。
数据准备
选择器需要一组选项数据,通常是一个对象数组,每个对象包含 value 和 label 两个字段:
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const value1 = ref('')
const value2 = ref([])
const options = [
{ value: '1', label: '选项一' },
{ value: '2', label: '选项二' },
{ value: '3', label: '选项三' },
{ value: '4', label: '选项四' },
{ value: '5', label: '选项五' },
]
</script>
value 是选项的实际值,会绑定到 v-model 上;label 是显示给用户看的文本。这两个字段名是 Element Plus 的默认配置,如果你的数据结构不一样,可以通过 value-key 和 label 属性来指定。
value1 用于单选场景,初始值是空字符串;value2 用于多选场景,初始值是空数组。这个初始值的类型很重要,如果多选场景给了字符串初始值,组件会报错。
基础选择器
最简单的用法就是 v-model 绑定一个值,然后用 v-for 渲染选项:
<el-card class="demo-card">
<template #header>基础用法</template>
<el-select v-model="value1" placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-card>
el-select 是选择器容器,el-option 是每个选项。v-for 遍历 options 数组,:key 绑定唯一标识,:label 绑定显示文本,:value 绑定实际值。
placeholder 在没有选中任何选项时显示,提示用户这个选择器是干什么的。style="width: 100%" 让选择器撑满父容器宽度,默认情况下 el-select 有一个固定宽度,在响应式布局中不太好用。
用户点击选择器会弹出下拉面板,选中某个选项后面板收起,选中的 label 显示在选择器中,对应的 value 赋值给 v-model 绑定的变量。
可清空选择器
有时候用户选错了想重新选,或者这个字段本身就是可选的,需要能清空已选的值:
<el-card class="demo-card">
<template #header>可清空</template>
<el-select v-model="value1" clearable placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-card>
加上 clearable 属性后,当选择器有值时,鼠标悬停会在右侧显示一个小叉号,点击就能清空选中的值。这个交互和 Input 组件的 clearable 是一致的,用户学习成本低。
清空后 v-model 绑定的变量会变成空字符串(单选)或空数组(多选),placeholder 会重新显示出来。
多选模式
单选只能选一个,但有些场景需要选多个,比如给文章打标签、选择多个收件人:
<el-card class="demo-card">
<template #header>多选</template>
<el-select v-model="value2" multiple placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-card>
multiple 属性开启多选模式。多选时,选中的选项会以标签(Tag)的形式显示在选择器中,每个标签右侧有删除按钮可以单独移除。v-model 绑定的变量是一个数组,包含所有选中项的 value。
多选模式下点击已选中的选项会取消选中,点击未选中的选项会添加到已选列表。下拉面板不会自动收起,方便用户连续选择多个。
如果选项很多,选中的标签可能会把选择器撑得很高。可以用 collapse-tags 属性折叠标签:
<el-select v-model="value2" multiple collapse-tags placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
折叠后只显示第一个标签,后面的用 “+N” 的形式表示还有多少个。鼠标悬停在 “+N” 上会显示完整列表。
可搜索选择器
选项太多的时候,让用户一个个找太费劲了。加上搜索功能,用户输入关键字就能快速定位:
<el-card class="demo-card">
<template #header>可搜索</template>
<el-select v-model="value1" filterable placeholder="请选择" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-card>
filterable 属性开启搜索功能。开启后选择器变成可输入状态,用户输入的内容会和选项的 label 进行匹配,只显示匹配的选项。匹配规则默认是包含匹配,不区分大小写。
如果默认的匹配规则不满足需求,可以通过 filter-method 属性自定义过滤函数:
<script setup lang="ts">
const filterMethod = (query: string) => {
// 自定义过滤逻辑,比如拼音匹配
if (query) {
// 返回过滤后的选项
}
}
</script>
<template>
<el-select v-model="value1" filterable :filter-method="filterMethod" placeholder="请选择">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
禁用状态
某些情况下需要禁止用户操作选择器,比如没有权限或者正在加载数据:
<el-card class="demo-card">
<template #header>禁用状态</template>
<el-select v-model="value1" disabled placeholder="禁用状态" style="width: 100%">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-card>
disabled 属性禁用整个选择器,视觉上会变灰,点击没有任何反应。这个属性通常会动态绑定:
<el-select v-model="value1" :disabled="loading" placeholder="请选择">
除了禁用整个选择器,还可以禁用单个选项:
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
禁用的选项会变灰,可以看到但不能选中。这在某些选项暂时不可用的场景很有用,比如库存为 0 的商品规格。
分组选项
选项很多的时候,可以按类别分组显示,让用户更容易找到想要的:
<script setup lang="ts">
const groupOptions = [
{
label: '热门城市',
options: [
{ value: 'beijing', label: '北京' },
{ value: 'shanghai', label: '上海' },
{ value: 'guangzhou', label: '广州' },
]
},
{
label: '其他城市',
options: [
{ value: 'chengdu', label: '成都' },
{ value: 'hangzhou', label: '杭州' },
{ value: 'wuhan', label: '武汉' },
]
}
]
</script>
<template>
<el-select v-model="value1" placeholder="请选择城市" style="width: 100%">
<el-option-group v-for="group in groupOptions" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label" :value="item.value" />
</el-option-group>
</el-select>
</template>
el-option-group 组件用来包裹一组选项,:label 设置分组标题。分组标题不可选中,只是起到分类提示的作用。
远程搜索
当选项数据量很大,不适合一次性加载到前端时,可以用远程搜索,用户输入关键字后从服务端获取匹配的选项:
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('')
const options = ref([])
const loading = ref(false)
const remoteSearch = async (query: string) => {
if (!query) {
options.value = []
return
}
loading.value = true
// 模拟接口请求
setTimeout(() => {
options.value = [
{ value: '1', label: `搜索结果 1 - ${query}` },
{ value: '2', label: `搜索结果 2 - ${query}` },
{ value: '3', label: `搜索结果 3 - ${query}` },
]
loading.value = false
}, 500)
}
</script>
<template>
<el-select
v-model="value"
filterable
remote
:remote-method="remoteSearch"
:loading="loading"
placeholder="请输入关键字搜索"
style="width: 100%"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
remote 属性开启远程搜索模式,remote-method 指定搜索函数,用户输入时会调用这个函数并传入输入的内容。:loading 绑定加载状态,在请求过程中显示 loading 图标。
远程搜索通常会配合防抖使用,避免用户快速输入时频繁请求接口:
<script setup lang="ts">
import { ref } from 'vue'
import { useDebounceFn } from '@vueuse/core'
const remoteSearch = useDebounceFn(async (query: string) => {
// 搜索逻辑
}, 300)
</script>
与鸿蒙原生能力结合
在 Electron for OpenHarmony 项目中,选择器的选项数据可能来自原生层。比如获取系统支持的语言列表:
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useOhos } from '@/composables/useOhos'
const language = ref('')
const languages = ref([])
const { getSystemInfo } = useOhos()
onMounted(async () => {
const info = await getSystemInfo()
// 假设系统信息中包含支持的语言列表
languages.value = [
{ value: 'zh-CN', label: '简体中文' },
{ value: 'en-US', label: 'English' },
]
})
</script>
<template>
<el-select v-model="language" placeholder="选择语言" style="width: 100%">
<el-option v-for="item in languages" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
选择器的值变化后,也可以调用原生能力来响应:
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useOhos } from '@/composables/useOhos'
const theme = ref('light')
const { setWindowTitle } = useOhos()
watch(theme, (newTheme) => {
setWindowTitle(`当前主题: ${newTheme}`)
})
</script>
<template>
<el-select v-model="theme" placeholder="选择主题" style="width: 100%">
<el-option value="light" label="浅色主题" />
<el-option value="dark" label="深色主题" />
<el-option value="auto" label="跟随系统" />
</el-select>
</template>
watch 监听 theme 变量的变化,变化时调用 setWindowTitle 更新窗口标题。这只是一个简单示例,实际项目中可能会调用更复杂的原生能力,比如切换系统主题、修改系统设置等。
自定义选项模板
默认的选项只显示文本,有时候需要更丰富的展示,比如带图标或者多行信息:
<script setup lang="ts">
const cities = [
{ value: 'beijing', label: '北京', desc: '首都,政治文化中心' },
{ value: 'shanghai', label: '上海', desc: '经济金融中心' },
{ value: 'shenzhen', label: '深圳', desc: '科技创新之城' },
]
</script>
<template>
<el-select v-model="value1" placeholder="请选择城市" style="width: 100%">
<el-option v-for="item in cities" :key="item.value" :label="item.label" :value="item.value">
<div style="display: flex; justify-content: space-between; align-items: center;">
<span>{{ item.label }}</span>
<span style="color: #909399; font-size: 12px;">{{ item.desc }}</span>
</div>
</el-option>
</el-select>
</template>
el-option 的默认插槽可以自定义选项的显示内容。注意 :label 属性还是要设置的,因为选中后选择器中显示的是 label 的值,不是插槽内容。
样式定制
Element Plus 的选择器样式可以通过 CSS 变量定制:
.demo-page {
--el-select-border-color-hover: #409eff;
--el-select-disabled-border: #e4e7ed;
--el-select-font-size: 14px;
--el-select-input-color: #606266;
--el-select-input-focus-border-color: #409eff;
}
下拉面板的样式需要用全局样式来覆盖,因为面板是挂载在 body 下的,不在组件的 scoped 范围内:
/* 全局样式文件 */
.el-select-dropdown {
--el-bg-color-overlay: #fff;
--el-border-color-light: #e4e7ed;
}
.el-select-dropdown__item.hover {
background-color: #f5f7fa;
}
小结
Select 选择器是表单中非常重要的组件,这篇文章介绍了它的各种用法:基础单选、可清空、多选、可搜索、禁用状态、分组选项、远程搜索,以及与鸿蒙原生能力的结合。选择器的核心是把用户的选择限定在预设的范围内,既能保证数据的准确性,又能提升操作效率。根据实际场景选择合适的配置,才能发挥选择器的最大价值。
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
更多推荐

所有评论(0)