问题:

我需要实现如下图所示的效果
效果

决定发这篇文章前,我先在网上搜索,看有没有类似的文章。我发现多数文章实现回显图标的方式是自己写了个 div,用 css 定位到 el-select 上。这显然不够优雅!

解决:

直接上最后代码,方便想直接复制粘贴的人用。

<el-select style="width: 100%;" v-model="dialogData.icon" placeholder="请选择菜单图标">
  <template #prefix>
    <el-icon color="#606266"><icon-svg :name="dialogData.icon" /></el-icon>
  </template>
  <el-option v-for="item in iconNames" :label="item" :value="item">
    <div class="option-container">
      <el-icon><icon-svg :name="item" /></el-icon>
      <span>&nbsp;&nbsp;{{ item }}</span>
    </div>
  </el-option>
</el-select>
data() {
  return {
  	//...省略其他变量
    iconNames: []
  }
},
mounted() {
  //从文件夹中获取所有的svg图标路径,形成文件名数组,供选择菜单图标时显示
  //注意替换文件路径!!!
  //import.meta.globEager 已经弃用,请使用 import.meta.glob('*', { eager: true }) 来代替。
  //import.meta.glob是什么?请访问下方链接了解。
  //https://cn.vitejs.dev/guide/features.html#glob-import
  const files = import.meta.glob('@/assets/svg/menu/*.svg', { eager: true });
  for(const path in files) {
    this.iconNames.push(path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.')));
  }
}
.option-container {
  display: flex;
  align-items: center;
}

<icon-svg /> 是我自定义的一个用来显示图标的通用组件,我采用了 symbol(不知道什么是symbol的点这里) 的方式引入 svg 图标。

import.meta.glob是什么?(点这里查看)

icon-svg 组件代码如下:

<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="'#' + name" />
  </svg>
</template>

<script>
export default {
  name: 'IconSvg',
  props: {
    name: {
      type: String,
      required: true
    }
  }
}
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

解释:

其实最核心的是怎么把图标回显到 el-select 上,关键的代码如下。

<template #prefix>
  <el-icon color="#606266"><icon-svg :name="dialogData.icon" /></el-icon>
</template>

我通过查阅文档得知,el-select 有一个 prefix 插槽。
文档
用这个就可以设置选择框前面的内容,然后将 el-select 选中的值传给 icon-svg 组件的 name 属性,就可以回显图标啦。

但是,ElementPlus 默认给这个插槽加了淡灰色的 color 样式,而我希望回显的图标不要改变颜色,所以我在 el-icon 上加了 color,以覆盖默认的样式。

Logo

前往低代码交流专区

更多推荐