修改动态 svg
This commit is contained in:
@@ -1,88 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10" class="ba-array-key">{{ state.keyTitle }}</el-col>
|
||||
<el-col :span="10" class="ba-array-value">{{ state.valueTitle }}</el-col>
|
||||
</el-row>
|
||||
<el-row class="ba-array-item" v-for="(item, idx) in state.value" :gutter="10" :key="idx">
|
||||
<el-col :span="10">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="item.key"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="item.value"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button @click="onDelArrayItem(idx)" size="small" icon="el-icon-Delete" circle />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10" :offset="10">
|
||||
<el-button v-blur class="ba-add-array-item" @click="onAddArrayItem" icon="el-icon-Plus">{{ t('Add')
|
||||
}}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
type baInputArray = { key: string; value: string }
|
||||
interface Props {
|
||||
modelValue: baInputArray[]
|
||||
keyTitle?: string
|
||||
valueTitle?: string
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: () => [],
|
||||
keyTitle: '',
|
||||
valueTitle: '',
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
value: props.modelValue,
|
||||
keyTitle: props.keyTitle ? props.keyTitle : t('utils.ArrayKey'),
|
||||
valueTitle: props.valueTitle ? props.valueTitle : t('utils.ArrayValue'),
|
||||
})
|
||||
|
||||
const onAddArrayItem = () => {
|
||||
state.value.push({
|
||||
key: '',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
|
||||
const onDelArrayItem = (idx: number) => {
|
||||
state.value.splice(idx, 1)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
state.value = newVal
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ba-array-key,
|
||||
.ba-array-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.ba-array-item {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ba-add-array-item {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10" class="ba-array-key">{{ state.keyTitle }}</el-col>
|
||||
<el-col :span="10" class="ba-array-value">{{ state.valueTitle }}</el-col>
|
||||
</el-row>
|
||||
<el-row class="ba-array-item" v-for="(item, idx) in state.value" :gutter="10" :key="idx">
|
||||
<el-col :span="10">
|
||||
<el-input v-model="item.key"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-input v-model="item.value"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button @click="onDelArrayItem(idx)" size="small" icon="el-icon-Delete" circle />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10" :offset="10">
|
||||
<el-button v-blur class="ba-add-array-item" @click="onAddArrayItem" icon="el-icon-Plus">{{ t('Add') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
type baInputArray = { key: string; value: string }
|
||||
interface Props {
|
||||
modelValue: baInputArray[]
|
||||
keyTitle?: string
|
||||
valueTitle?: string
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: () => [],
|
||||
keyTitle: '',
|
||||
valueTitle: '',
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
value: props.modelValue,
|
||||
keyTitle: props.keyTitle ? props.keyTitle : t('utils.ArrayKey'),
|
||||
valueTitle: props.valueTitle ? props.valueTitle : t('utils.ArrayValue'),
|
||||
})
|
||||
|
||||
const onAddArrayItem = () => {
|
||||
state.value.push({
|
||||
key: '',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
|
||||
const onDelArrayItem = (idx: number) => {
|
||||
state.value.splice(idx, 1)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
state.value = newVal
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ba-array-key,
|
||||
.ba-array-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.ba-array-item {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.ba-add-array-item {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,282 +1,316 @@
|
||||
<template>
|
||||
<el-popover :placement='placement' trigger='focus' :hide-after='0' :width='state.selectorWidth'
|
||||
:visible='state.popoverVisible'>
|
||||
<div @mouseover.stop='state.iconSelectorMouseover = true' @mouseout.stop='state.iconSelectorMouseover = false'
|
||||
class='icon-selector'>
|
||||
<transition name='el-zoom-in-center'>
|
||||
<div class='icon-selector-box'>
|
||||
<div class='selector-header'>
|
||||
<div class='selector-title'>{{ title ? title : '请选择图标' }}</div>
|
||||
<div class='selector-tab'>
|
||||
<span :title="'Element Puls ' + 'utils.Icon'" @click="onChangeTab('ele')"
|
||||
:class="state.iconType == 'ele' ? 'active' : ''">ele</span>
|
||||
<span :title="'Font Awesome ' + 'utils.Icon'" @click="onChangeTab('awe')"
|
||||
:class="state.iconType == 'awe' ? 'active' : ''">awe</span>
|
||||
<!-- <span :title="'utils.Ali iconcont Icon'" @click="onChangeTab('ali')"-->
|
||||
<!-- :class="state.iconType == 'ali' ? 'active' : ''"-->
|
||||
<!-- >ali</span>-->
|
||||
<!-- <span-->
|
||||
<!-- :title="'utils.Local icon title'"-->
|
||||
<!-- @click="onChangeTab('local')"-->
|
||||
<!-- :class="state.iconType == 'local' ? 'active' : ''"-->
|
||||
<!-- >local</span-->
|
||||
<!-- >-->
|
||||
</div>
|
||||
</div>
|
||||
<div class='selector-body'>
|
||||
<el-scrollbar ref='selectorScrollbarRef'>
|
||||
<div v-if='renderFontIconNames.length > 0'>
|
||||
<div class='icon-selector-item' :title='item' @click='onIcon(item)'
|
||||
v-for='(item, key) in renderFontIconNames' :key='key'>
|
||||
<Icon :name='item' />
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-input maxlength="32" show-word-limit v-model.trim='state.inputValue' :size='size' :disabled='disabled'
|
||||
placeholder='搜索图标' ref='selectorInput' @focus='onInputFocus' @blur='onInputBlur'
|
||||
:class="'size-' + size">
|
||||
<template #prepend>
|
||||
<div class='icon-prepend'>
|
||||
<Icon :key="'icon' + state.iconKey"
|
||||
:name='state.prependIcon ? state.prependIcon : state.defaultModelValue' />
|
||||
<div v-if='showIconName' class='name'>
|
||||
{{ state.prependIcon ? state.prependIcon : state.defaultModelValue }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #append>
|
||||
<Icon @click='onInputRefresh' name='el-icon-RefreshRight' />
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
import { reactive, ref, onMounted, nextTick, watch, computed } from 'vue'
|
||||
import { getElementPlusIconfontNames, getAwesomeIconfontNames } from '@/utils/iconfont'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import type { Placement } from 'element-plus'
|
||||
|
||||
type IconType = 'ele' | 'awe' | 'ali' | 'local'
|
||||
|
||||
interface Props {
|
||||
size?: 'default' | 'small' | 'large'
|
||||
disabled?: boolean
|
||||
title?: string
|
||||
type?: IconType
|
||||
placement?: Placement
|
||||
modelValue?: string
|
||||
showIconName?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'default',
|
||||
disabled: false,
|
||||
title: '',
|
||||
type: 'ele',
|
||||
placement: 'bottom',
|
||||
modelValue: '',
|
||||
showIconName: false
|
||||
})
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void
|
||||
(e: 'change', value: string): void
|
||||
}>()
|
||||
|
||||
const selectorInput = ref()
|
||||
const selectorScrollbarRef = ref()
|
||||
const state: {
|
||||
iconType: IconType
|
||||
selectorWidth: number
|
||||
popoverVisible: boolean
|
||||
inputFocus: boolean
|
||||
iconSelectorMouseover: boolean
|
||||
fontIconNames: string[]
|
||||
inputValue: string
|
||||
prependIcon: string
|
||||
defaultModelValue: string
|
||||
iconKey: number
|
||||
} = reactive({
|
||||
iconType: props.type,
|
||||
selectorWidth: 0,
|
||||
popoverVisible: false,
|
||||
inputFocus: false,
|
||||
iconSelectorMouseover: false,
|
||||
fontIconNames: [],
|
||||
inputValue: '',
|
||||
prependIcon: props.modelValue,
|
||||
defaultModelValue: props.modelValue || 'fa fa-circle-o',
|
||||
iconKey: 0 // 给icon标签准备个key,以随时使用 h 函数重新生成元素
|
||||
})
|
||||
|
||||
const onInputFocus = () => {
|
||||
state.inputFocus = state.popoverVisible = true
|
||||
}
|
||||
const onInputBlur = () => {
|
||||
state.inputFocus = false
|
||||
state.popoverVisible = state.iconSelectorMouseover
|
||||
}
|
||||
const onInputRefresh = () => {
|
||||
state.iconKey++
|
||||
state.prependIcon = state.defaultModelValue
|
||||
state.inputValue = ''
|
||||
emits('update:modelValue', state.defaultModelValue)
|
||||
emits('change', state.defaultModelValue)
|
||||
}
|
||||
const onChangeTab = (name: IconType) => {
|
||||
state.iconType = name
|
||||
state.fontIconNames = []
|
||||
if (name == 'ele') {
|
||||
getElementPlusIconfontNames().then((res) => {
|
||||
state.fontIconNames = res
|
||||
})
|
||||
} else if (name == 'awe') {
|
||||
getAwesomeIconfontNames().then((res) => {
|
||||
state.fontIconNames = res.map((name) => `fa ${name}`)
|
||||
})
|
||||
}
|
||||
// else if (name == 'ali') {
|
||||
// getIconfontNames().then((res) => {
|
||||
// state.fontIconNames = res.map((name) => `iconfont ${name}`)
|
||||
// })
|
||||
// } else if (name == 'local') {
|
||||
// getLocalIconfontNames().then((res) => {
|
||||
// state.fontIconNames = res
|
||||
// })
|
||||
// }
|
||||
}
|
||||
const onIcon = (icon: string) => {
|
||||
state.iconSelectorMouseover = state.popoverVisible = false
|
||||
state.iconKey++
|
||||
state.prependIcon = icon
|
||||
state.inputValue = ''
|
||||
emits('update:modelValue', icon)
|
||||
emits('change', icon)
|
||||
nextTick(() => {
|
||||
selectorInput.value.blur()
|
||||
})
|
||||
}
|
||||
|
||||
const renderFontIconNames = computed(() => {
|
||||
if (!state.inputValue) return state.fontIconNames
|
||||
|
||||
let inputValue = state.inputValue.trim().toLowerCase()
|
||||
return state.fontIconNames.filter((icon: string) => {
|
||||
if (icon.toLowerCase().indexOf(inputValue) !== -1) {
|
||||
return icon
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 获取 input 的宽度
|
||||
const getInputWidth = () => {
|
||||
nextTick(() => {
|
||||
state.selectorWidth = selectorInput.value.$el.offsetWidth < 260 ? 260 : selectorInput.value.$el.offsetWidth
|
||||
})
|
||||
}
|
||||
|
||||
const popoverVisible = () => {
|
||||
state.popoverVisible = state.inputFocus || state.iconSelectorMouseover ? true : false
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => {
|
||||
state.iconKey++
|
||||
if (props.modelValue != state.prependIcon) state.defaultModelValue = props.modelValue
|
||||
if (props.modelValue == '') state.defaultModelValue = 'fa fa-circle-o'
|
||||
state.prependIcon = props.modelValue
|
||||
}
|
||||
)
|
||||
onMounted(() => {
|
||||
getInputWidth()
|
||||
useEventListener(document, 'click', popoverVisible)
|
||||
getElementPlusIconfontNames().then((res) => {
|
||||
state.fontIconNames = res
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.size-small {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.size-large {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.size-default {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.icon-prepend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.name {
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.selector-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.selector-tab {
|
||||
margin-left: auto;
|
||||
|
||||
span {
|
||||
padding: 0 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.selector-body {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.icon-selector-item {
|
||||
display: inline-block;
|
||||
padding: 10px 10px 6px 10px;
|
||||
margin: 3px;
|
||||
border: 1px solid var(--ba-border-color);
|
||||
border-radius: var(--el-border-radius-base);
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
|
||||
.icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input-group__prepend) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-popover
|
||||
:placement="placement"
|
||||
trigger="focus"
|
||||
:hide-after="0"
|
||||
:width="state.selectorWidth"
|
||||
:visible="state.popoverVisible"
|
||||
>
|
||||
<div
|
||||
@mouseover.stop="state.iconSelectorMouseover = true"
|
||||
@mouseout.stop="state.iconSelectorMouseover = false"
|
||||
class="icon-selector"
|
||||
>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div class="icon-selector-box">
|
||||
<div class="selector-header">
|
||||
<div class="selector-title">{{ title ? title : '请选择图标' }}</div>
|
||||
<div class="selector-tab">
|
||||
<span
|
||||
:title="'Element Puls ' + 'utils.Icon'"
|
||||
@click="onChangeTab('ele')"
|
||||
:class="state.iconType == 'ele' ? 'active' : ''"
|
||||
>
|
||||
ele
|
||||
</span>
|
||||
<span
|
||||
:title="'Font Awesome ' + 'utils.Icon'"
|
||||
@click="onChangeTab('awe')"
|
||||
:class="state.iconType == 'awe' ? 'active' : ''"
|
||||
>
|
||||
awe
|
||||
</span>
|
||||
<!-- <span :title="'utils.Ali iconcont Icon'" @click="onChangeTab('ali')"-->
|
||||
<!-- :class="state.iconType == 'ali' ? 'active' : ''"-->
|
||||
<!-- >ali</span>-->
|
||||
<span
|
||||
:title="'utils.Local icon title'"
|
||||
@click="onChangeTab('local')"
|
||||
:class="state.iconType == 'local' ? 'active' : ''"
|
||||
>
|
||||
local
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="selector-body">
|
||||
<el-scrollbar ref="selectorScrollbarRef">
|
||||
<div v-if="renderFontIconNames.length > 0">
|
||||
<div
|
||||
class="icon-selector-item"
|
||||
:title="item"
|
||||
@click="onIcon(item)"
|
||||
v-for="(item, key) in renderFontIconNames"
|
||||
:key="key"
|
||||
>
|
||||
<Icon :name="item" />
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="state.inputValue"
|
||||
:size="size"
|
||||
:disabled="disabled"
|
||||
placeholder="搜索图标"
|
||||
ref="selectorInput"
|
||||
@focus="onInputFocus"
|
||||
@blur="onInputBlur"
|
||||
:class="'size-' + size"
|
||||
>
|
||||
<template #prepend>
|
||||
<div class="icon-prepend">
|
||||
<Icon
|
||||
:key="'icon' + state.iconKey"
|
||||
:name="state.prependIcon ? state.prependIcon : state.defaultModelValue"
|
||||
/>
|
||||
<div v-if="showIconName" class="name">
|
||||
{{ state.prependIcon ? state.prependIcon : state.defaultModelValue }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #append>
|
||||
<Icon @click="onInputRefresh" name="el-icon-RefreshRight" />
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, nextTick, watch, computed } from 'vue'
|
||||
import { getElementPlusIconfontNames, getAwesomeIconfontNames, getLocalIconfontNames } from '@/utils/iconfont'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import type { Placement } from 'element-plus'
|
||||
|
||||
type IconType = 'ele' | 'awe' | 'ali' | 'local'
|
||||
|
||||
interface Props {
|
||||
size?: 'default' | 'small' | 'large'
|
||||
disabled?: boolean
|
||||
title?: string
|
||||
type?: IconType
|
||||
placement?: Placement
|
||||
modelValue?: string
|
||||
showIconName?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'default',
|
||||
disabled: false,
|
||||
title: '',
|
||||
type: 'ele',
|
||||
placement: 'bottom',
|
||||
modelValue: '',
|
||||
showIconName: false
|
||||
})
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void
|
||||
(e: 'change', value: string): void
|
||||
}>()
|
||||
|
||||
const selectorInput = ref()
|
||||
const selectorScrollbarRef = ref()
|
||||
const state: {
|
||||
iconType: IconType
|
||||
selectorWidth: number
|
||||
popoverVisible: boolean
|
||||
inputFocus: boolean
|
||||
iconSelectorMouseover: boolean
|
||||
fontIconNames: string[]
|
||||
inputValue: string
|
||||
prependIcon: string
|
||||
defaultModelValue: string
|
||||
iconKey: number
|
||||
} = reactive({
|
||||
iconType: props.type,
|
||||
selectorWidth: 0,
|
||||
popoverVisible: false,
|
||||
inputFocus: false,
|
||||
iconSelectorMouseover: false,
|
||||
fontIconNames: [],
|
||||
inputValue: '',
|
||||
prependIcon: props.modelValue,
|
||||
defaultModelValue: props.modelValue || 'fa fa-circle-o',
|
||||
iconKey: 0 // 给icon标签准备个key,以随时使用 h 函数重新生成元素
|
||||
})
|
||||
|
||||
const onInputFocus = () => {
|
||||
state.inputFocus = state.popoverVisible = true
|
||||
}
|
||||
const onInputBlur = () => {
|
||||
state.inputFocus = false
|
||||
state.popoverVisible = state.iconSelectorMouseover
|
||||
}
|
||||
const onInputRefresh = () => {
|
||||
state.iconKey++
|
||||
state.prependIcon = state.defaultModelValue
|
||||
state.inputValue = ''
|
||||
emits('update:modelValue', state.defaultModelValue)
|
||||
emits('change', state.defaultModelValue)
|
||||
}
|
||||
const onChangeTab = (name: IconType) => {
|
||||
state.iconType = name
|
||||
state.fontIconNames = []
|
||||
if (name == 'ele') {
|
||||
getElementPlusIconfontNames().then(res => {
|
||||
state.fontIconNames = res
|
||||
})
|
||||
} else if (name == 'awe') {
|
||||
getAwesomeIconfontNames().then(res => {
|
||||
state.fontIconNames = res.map(name => `fa ${name}`)
|
||||
})
|
||||
}
|
||||
// else if (name == 'ali') {
|
||||
// getIconfontNames().then((res) => {
|
||||
// state.fontIconNames = res.map((name) => `iconfont ${name}`)
|
||||
// })
|
||||
// }
|
||||
else if (name == 'local') {
|
||||
getLocalIconfontNames().then(res => {
|
||||
state.fontIconNames = res
|
||||
})
|
||||
}
|
||||
}
|
||||
const onIcon = (icon: string) => {
|
||||
state.iconSelectorMouseover = state.popoverVisible = false
|
||||
state.iconKey++
|
||||
state.prependIcon = icon
|
||||
state.inputValue = ''
|
||||
emits('update:modelValue', icon)
|
||||
emits('change', icon)
|
||||
nextTick(() => {
|
||||
selectorInput.value.blur()
|
||||
})
|
||||
}
|
||||
|
||||
const renderFontIconNames = computed(() => {
|
||||
if (!state.inputValue) return state.fontIconNames
|
||||
|
||||
let inputValue = state.inputValue.trim().toLowerCase()
|
||||
return state.fontIconNames.filter((icon: string) => {
|
||||
if (icon.toLowerCase().indexOf(inputValue) !== -1) {
|
||||
return icon
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 获取 input 的宽度
|
||||
const getInputWidth = () => {
|
||||
nextTick(() => {
|
||||
state.selectorWidth = selectorInput.value.$el.offsetWidth < 260 ? 260 : selectorInput.value.$el.offsetWidth
|
||||
})
|
||||
}
|
||||
|
||||
const popoverVisible = () => {
|
||||
state.popoverVisible = state.inputFocus || state.iconSelectorMouseover ? true : false
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => {
|
||||
state.iconKey++
|
||||
if (props.modelValue != state.prependIcon) state.defaultModelValue = props.modelValue
|
||||
if (props.modelValue == '') state.defaultModelValue = 'fa fa-circle-o'
|
||||
state.prependIcon = props.modelValue
|
||||
}
|
||||
)
|
||||
onMounted(() => {
|
||||
getInputWidth()
|
||||
useEventListener(document, 'click', popoverVisible)
|
||||
getElementPlusIconfontNames().then(res => {
|
||||
state.fontIconNames = res
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.size-small {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.size-large {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.size-default {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.icon-prepend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.name {
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.selector-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.selector-tab {
|
||||
margin-left: auto;
|
||||
|
||||
span {
|
||||
padding: 0 5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.selector-body {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.icon-selector-item {
|
||||
display: inline-block;
|
||||
padding: 10px 10px 6px 10px;
|
||||
margin: 3px;
|
||||
border: 1px solid var(--ba-border-color);
|
||||
border-radius: var(--el-border-radius-base);
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
|
||||
.icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input-group__prepend) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user