自定義的圖標選擇組件是若依的項目的
1. 若依的圖標選擇組件
- js文件,引入所有的svg圖片
let icons = []
// 注意這里的路徑,一定要是自己svg圖片的路徑
const modules = import.meta.glob('./../../assets/icons/svg/*.svg');
for (const path in modules) {const p = path.split('assets/icons/svg/')[1].split('.svg')[0];icons.push(p);
}export default icons
- vue組件
- 自定義的
SvgIcon
組件,每個人定義的方式都不用,這里重要的就是name
屬性:圖片的名字 - defineProps:
activeIcon
: 用于返顯用戶已經選擇或者原本就存在的圖標 - meit:訂閱selected事件,發送用戶當前選擇的圖標
- defineExpose:
reset
方法,向外拋出方法,在父組件中可以清除搜索框中的內容
- 自定義的
<template><div class="icon-body"><el-inputv-model="iconName"class="icon-search"clearableplaceholder="請輸入圖標名稱"@clear="filterIcons"@input="filterIcons"><template #suffix><SvgIcon name="search"/></template></el-input><div class="icon-list"><div class="list-container"><div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)"><div :class="['icon-item', { active: activeIcon === item }]"><!--自定義的SvgIcon組件,每個人定義的方式都不用,這里重要的就是name屬性:圖片的名字--><SvgIcon :name="item" class-name="icon" style="height: 25px;width: 16px;"/><span>{{ item }}</span></div></div></div></div></div>
</template><script setup>
import icons from './requireIcons'
import SvgIcon from '@/components/svgicon/SvgIcon.vue'
// activeIcon: 用于返現用戶已經選擇的圖標
const props = defineProps({activeIcon: {type: String}
});const iconName = ref('');
const iconList = ref(icons);
// 訂閱selected時間,發送用戶當前選擇的圖標
const emit = defineEmits(['selected']);// 通過js文件中的方法,將icon/svg文件夾中的圖標的名字取出來
function filterIcons() {iconList.value = iconsif (iconName.value) {iconList.value = icons.filter(item => item.indexOf(iconName.value) !== -1)}
}function selectedIcon(name) {emit('selected', name)document.body.click()
}function reset() {iconName.value = ''iconList.value = icons
}
// 向外拋出方法:在父組件中可以清除搜索框中的內容
defineExpose({reset
})
</script><style lang='scss' scoped>.icon-body {width: 100%;padding: 10px;.icon-search {position: relative;margin-bottom: 5px;width: 50%;}.icon-list {height: 200px;overflow: auto;.list-container {display: flex;flex-wrap: wrap;.icon-item-wrapper {width: calc(100% / 3);height: 25px;line-height: 25px;cursor: pointer;display: flex;.icon-item {display: flex;max-width: 100%;height: 100%;padding: 0 5px;&:hover {background: #ececec;border-radius: 5px;}.icon {flex-shrink: 0;}span {display: inline-block;vertical-align: -0.15em;fill: currentColor;padding-left: 2px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}}.icon-item.active {background: #ececec;border-radius: 5px;}}}}}
</style>
2. 在項目中引入組件
引入組件
<IconSelect @selected="iconSelected" ref="iconSelect" :activeIcon="formData.icon"/>
@selected="iconSelected"
:接收子組件發送的事件,圖標被選中:activeIcon="formData.icon"
:給子組件傳遞圖標,比如在修改數據時,數據中原本就存在圖標ref="iconSelect"
:使用子組件的實例,調用子組件拋出的方法
<el-popoverplacement="bottom-start":width="200"trigger="click"
><!-- popover彈出框的插槽,這個插槽的決定了彈出框在頁面顯示的效果,這里顯示的是input輸入框 --><template #reference><el-input v-model="formData.icon" placeholder="請選擇圖標" clearable @clear="clearIconInput"><!-- input的插槽,input框前面顯示的圖標 --><template #prefix><svg-icon v-if="formData.icon" :name="formData.icon" /><svg-icon v-else name="search" /></template></el-input></template><!-- popover彈出框的插槽,這個插槽決定彈出框彈出后顯示的內容,這里顯示的是IconSelect組件 --><template #default><!-- 彈出框的內容是自定義組件 --><IconSelect style="background-color: #fff;width:500px;border:1px black solid" @selected="iconSelected" ref="iconSelect" :activeIcon="formData.icon"/></template>
</el-popover>
<script setup>
const formData = reactive({icon: undefined,
})
// 子組件的ref,用戶調用子組件中defineExpose暴露的方法
const iconSelectRef = useTemplateRef("iconSelect")
// 子組件IconSelect通過emit發送的訂閱消息
const iconSelected = (name) => {formData.icon = name
}
// 調用子組件iconSelect的reset方法
const clearIconInput = () => {formData.icon = undefinediconSelectRef.value.reset()
}
</script>