单独设置一个文件当做公共组件调用
<template> <main> <el-select ref="select" v-model="values" multiple style="width:100%" :placeholder="placeholder" @change="handleChange" @remove-tag="removeTag" > <el-option v-for="item in options" :key="item.id" :disabled="disabled && item.id === Number(judgingCondition)" :label="item.name" :value="item.id" /> </el-select> </main> </template> <script> export default { name: 'select-tags', props: { // 选项 options: { type: Array, default: () => [] }, // 选中的值 value: { type: Array, default: () => [] }, // 提示 placeholder: { type: String, default: '请选择' }, // 是否禁用 disabled: { type: Boolean, default: false }, // 判断条件 judgingCondition: { type: String | Number, default: '' } }, data() { return { observer: null, hideDom: null }; }, computed: { /** * @description 获取当前选中的值 */ values: { get() { return this.value; }, set(val) { this.$emit('input', val); } } }, mounted() { this.mutationObserver(); }, beforeDestroy() { this.observer.disconnect(); }, methods: { /** * @description 监听tag变化 */ mutationObserver() { const tagLIstDom = this.$refs.select.$el.querySelector('.el-select__tags'); const tagSpanDom = this.$refs.select.$el.querySelector('.el-select__tags > span'); // 创建隐藏的计数节点 this.hideDom = document.createElement('span'); this.hideDom.classList.add('count-node'); tagSpanDom.append(this.hideDom); const config = { childList: true }; const callback = mutationsList => { mutationsList.forEach(item => { if (item.type === 'childList') { const tagList = item.target.childNodes; let tagWidth = 0; let tagNum = 0; let availableTagWidth = 0; for (let i = 0; i < tagList.length; i++) { const e = tagList[i]; if (tagWidth > tagLIstDom.offsetWidth) { e.style.display = 'none'; } else { e.style.display = 'inline-block'; } tagWidth += e.offsetWidth + 5; if (tagWidth > tagLIstDom.offsetWidth) { e.style.display = 'none'; } else { e.style.display = 'inline-block'; } if (e.style.display !== 'none') { tagNum++; this.hideDom.style.display = 'none'; const margin = tagNum === 1 ? 0 : 7; availableTagWidth += e.offsetWidth + margin; } else { this.hideDom.style.display = 'inline-block'; this.hideDom.style.left = `${availableTagWidth}px`; this.hideDom.innerHTML = `+${tagList.length - tagNum}`; } } } }); }; this.observer = new MutationObserver(callback); this.observer.observe(tagSpanDom, config); }, /** * @description 选择框改变 */ handleChange() { this.$emit('change', this.value); }, /** * * @param val 当前角色绑定的分校不允许删除 */ removeTag(val) { this.$emit('remove-tag', val); } } }; </script> <style lang='less' scoped> @import url('./index.less'); </style>
/deep/.count-node { position: absolute; top: 2px; display: none; height: 24px; padding: 0 8px; line-height: 22px; margin-left: 6px; background-color: #f4f4f5; border: 1px solid #e9e9eb; border-radius: 4px; color: #909399; font-size: 12px; box-sizing: border-box; }
组件调用
<select-tags v-model="formData.browseList" :options="schoolList" :judging-condition="schoolId" :disabled="true" :placeholder="'请选择内容'" class="select-tags" @remove-tag="removeTag" /> /** * * @param val 当前角色绑定的分校不允许删除 */ removeTag(val) { if (Number(this.schoolId) === val) { const defaultIndex = this.schoolList.findIndex(item => item.id === val); // 获取默认值在数组中的下标 this.formData.browseList.splice(defaultIndex, 0, val); // 将要删除的值插入到默认值对应的下标位置 return false; } return true; }
都是借鉴别的博客总结出来的https://blog.csdn.net/weixin_57748960/article/details/127925890?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-127925890-blog-107493500.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-127925890-blog-107493500.pc_relevant_default&utm_relevant_index=3
但是他做的不能同时多个select使用在一个页面的话 我的改进了一下可以多个同时使用
右侧赞助一下 代码改变世界一块二块也是爱
分类:
vue
, experience
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通