一句话概括需求,multiple的select,需要在鼠标悬浮到选中的选项时弹出悬浮框
el-select不支持内容的插槽,选中的内容就只显示该选项的currentLabel字段。我就想到给el-select添加一个插槽,能够定制显示的内容。这样让我重新思考了扩展el-select的方式。这次我选择使用mixins的方式来扩展.
开始贴代码了:)
<template>
<div
class="el-select"
:class="[selectSize ? 'el-select--' + selectSize : '']"
@click.stop="toggleMenu"
v-clickoutside="handleClose">
<div
class="el-select__tags"
v-if="multiple"
ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%' }">
<span v-if="collapseTags && selected.length">
<el-tag
:closable="!selectDisabled"
:size="collapseTagSize"
:hit="selected[0].hitState"
type="info"
@close="deleteTag($event, selected[0])"
disable-transitions>
<span class="el-select__tags-text">{{ selected[0].currentLabel }}</span>
</el-tag>
<el-tag
v-if="selected.length > 1"
:closable="false"
:size="collapseTagSize"
type="info"
disable-transitions>
<span class="el-select__tags-text">+ {{ selected.length - 1 }}</span>
</el-tag>
</span>
<transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
<el-tag
v-for="item in selected"
:key="getValueKey(item)"
:closable="!selectDisabled"
:size="collapseTagSize"
:hit="item.hitState"
type="info"
@close="deleteTag($event, item)"
disable-transitions>
<span class="el-select__tags-text"><slot name="content" v-if="$scopedSlots.content" v-bind:item="item"></slot><template v-else>{{ item.currentLabel }}</template></span>
</el-tag>
</transition-group>
<input
type="text"
class="el-select__input"
:class="[selectSize ? `is-${ selectSize }` : '']"
:disabled="selectDisabled"
:autocomplete="autoComplete || autocomplete"
@focus="handleFocus"
@blur="softFocus = false"
@click.stop
@keyup="managePlaceholder"
@keydown="resetInputState"
@keydown.down.prevent="navigateOptions('next')"
@keydown.up.prevent="navigateOptions('prev')"
@keydown.enter.prevent="selectOption"
@keydown.esc.stop.prevent="visible = false"
@keydown.delete="deletePrevTag"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
v-model="query"
@input="debouncedQueryChange"
v-if="filterable"
:style="{ 'flex-grow': '1', width: inputLength / (inputWidth - 32) + '%', 'max-width': inputWidth - 42 + 'px' }"
ref="input">
</div>
<el-input
ref="reference"
v-model="selectedLabel"
type="text"
:placeholder="currentPlaceholder"
:name="name"
:id="id"
:autocomplete="autoComplete || autocomplete"
:size="selectSize"
:disabled="selectDisabled"
:readonly="readonly"
:validate-event="false"
:class="{ 'is-focus': visible }"
@focus="handleFocus"
@blur="handleBlur"
@keyup.native="debouncedOnInputChange"
@keydown.native.down.stop.prevent="navigateOptions('next')"
@keydown.native.up.stop.prevent="navigateOptions('prev')"
@keydown.native.enter.prevent="selectOption"
@keydown.native.esc.stop.prevent="visible = false"
@keydown.native.tab="visible = false"
@paste.native="debouncedOnInputChange"
@mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false">
<template slot="prefix" v-if="$slots.prefix">
<slot name="prefix"></slot>
</template>
<template slot="suffix">
<i v-show="!showClose" :class="['el-select__caret', 'el-input__icon', 'el-icon-' + iconClass]"></i>
<i v-if="showClose" class="el-select__caret el-input__icon el-icon-circle-close" @click="handleClearClick"></i>
</template>
</el-input>
<transition
name="el-zoom-in-top"
@before-enter="handleMenuEnter"
@after-leave="doDestroy">
<el-select-menu
ref="popper"
:append-to-body="popperAppendToBody"
v-show="visible && emptyText !== false">
<el-scrollbar
tag="ul"
wrap-class="el-select-dropdown__wrap"
view-class="el-select-dropdown__list"
ref="scrollbar"
:class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"
v-show="options.length > 0 && !loading">
<el-option
:value="query"
created
v-if="showNewOption">
</el-option>
<slot></slot>
</el-scrollbar>
<template v-if="emptyText && (!allowCreate || loading || (allowCreate && options.length === 0 ))">
<slot name="empty" v-if="$slots.empty"></slot>
<p class="el-select-dropdown__empty" v-else>
{{ emptyText }}
</p>
</template>
</el-select-menu>
</transition>
</div>
</template>
<script>
import { Select } from 'element-ui';
export default {
name: 'ExtendedSelect',
mixins: [Select]
}
</script>
以上内容大部分都是来自element源码,只做了一点点的修改
<slot name="content" v-if="$scopedSlots.content" v-bind:item="item"></slot><template v-else>{{ item.currentLabel }}</template>
使用方法
...
<extended-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-popover
slot="content"
slot-scope="scope"
placement="top-start"
title="标题"
width="200"
trigger="hover"
content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
<span slot="reference">{{ scope.item.currentLabel }}</span>
</el-popover>
</extended-select>
...
以上就是全部了
如果帮到你,给点个赞呗:)