修改动态 svg

This commit is contained in:
guanj
2025-10-13 16:14:03 +08:00
parent a3b6a5c0be
commit 2bbf84080c
238 changed files with 8886 additions and 4477 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -0,0 +1,36 @@
<template>
<!-- <div style='width: 12px;'></div>-->
<!-- <el-icon color='black' class='backIcon'>-->
<!-- <close @click='go(-1)' />-->
<!-- </el-icon>-->
<el-button @click='go(-1)' :class='{positionStyle:custom,ml10:true}' :icon='Back'>返回</el-button>
</template>
<script setup lang='ts'>
import { useRouter } from 'vue-router'
import { Back } from '@element-plus/icons-vue'
const { go } = useRouter()
defineProps(['custom'])
</script>
<style scoped>
.backIcon {
position: absolute;
top: 0;
right: 0;
font-size: 25px;
cursor: pointer;
}
.backIcon:hover {
border-radius: 25px;
background-color: lightgrey;
}
.positionStyle {
position: absolute;
right: 20px;
top: 20px;
}
</style>

View File

@@ -0,0 +1,4 @@
import Icon from './src/Icon.vue'
import IconSelect from './src/IconSelect.vue'
export { Icon, IconSelect }

View File

@@ -1,43 +1,44 @@
<script lang="ts">
import { createVNode, resolveComponent, defineComponent, computed, type CSSProperties } from 'vue'
import svg from '@/components/icon/svg/index.vue'
import { isExternal } from '@/utils/common'
export default defineComponent({
name: 'Icon',
props: {
name: {
type: String,
required: true
},
size: {
type: String,
default: '18px'
},
color: {
type: String,
default: '#000000'
}
},
setup(props) {
const iconStyle = computed((): CSSProperties => {
const { size, color } = props
let s = `${size.replace('px', '')}px`
return {
fontSize: s,
color: color
}
})
if (props.name.indexOf('el-icon-') === 0) {
return () =>
createVNode('el-icon', { class: 'icon el-icon', style: iconStyle.value }, [
createVNode(resolveComponent(props.name))
])
} else if (props.name.indexOf('local-') === 0 || isExternal(props.name)) {
return () => createVNode(svg, { name: props.name, size: props.size, color: props.color })
} else {
return () => createVNode('i', { class: [props.name, 'icon'], style: iconStyle.value })
}
}
})
</script>
<script lang="ts">
import { createVNode, resolveComponent, defineComponent, computed, type CSSProperties } from 'vue'
import svg from '@/components/icon/svg/index.vue'
import { isExternal } from '@/utils/common'
export default defineComponent({
name: 'Icon',
props: {
name: {
type: String,
required: true
},
size: {
type: String,
default: '18px'
},
color: {
type: String,
default: '#000000'
}
},
setup(props) {
const iconStyle = computed((): CSSProperties => {
const { size, color } = props
let s = `${size.replace('px', '')}px`
return {
fontSize: s,
color: color
}
})
if(props.name){
if (props.name.indexOf('el-icon-') === 0) {
return () =>
createVNode('el-icon', { class: 'icon el-icon', style: iconStyle.value }, [
createVNode(resolveComponent(props.name))
])
} else if (props.name.indexOf('local-') === 0 || isExternal(props.name)) {
return () => createVNode(svg, { name: props.name, size: props.size, color: props.color })
} else {
return () => createVNode('i', { class: [props.name, 'icon'], style: iconStyle.value })
}
}
}
})
</script>

View File

@@ -0,0 +1,87 @@
<script lang="ts" setup>
import { CSSProperties ,ref,toRef,computed,watch} from 'vue'
import { propTypes } from '@/utils/propTypes'
import Iconify from '@purge-icons/generated'
import { useDesign } from '@/hooks/web/useDesign'
defineOptions({ name: 'Icon' })
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('icon')
const props = defineProps({
// icon name
icon: propTypes.string,
// icon color
color: propTypes.string,
// icon size
size: propTypes.number.def(16),
// icon svg class
svgClass: propTypes.string.def('')
})
const elRef = ref<ElRef>(null)
const isLocal = computed(() => props.icon.startsWith('svg-icon:'))
const symbolId = computed(() => {
return unref(isLocal) ? `#icon-${props.icon.split('svg-icon:')[1]}` : props.icon
})
const getIconifyStyle = computed(() => {
const { color, size } = props
return {
fontSize: `${size}px`,
height: '1em',
color
}
})
const getSvgClass = computed(() => {
const { svgClass } = props
return `iconify ${svgClass}`
})
const updateIcon = async (icon: string) => {
if (unref(isLocal)) return
const el = unref(elRef)
if (!el) return
await nextTick()
if (!icon) return
const svg = Iconify.renderSVG(icon, {})
if (svg) {
el.textContent = ''
el.appendChild(svg)
} else {
const span = document.createElement('span')
span.className = 'iconify'
span.dataset.icon = icon
el.textContent = ''
el.appendChild(span)
}
}
watch(
() => props.icon,
(icon: string) => {
updateIcon(icon)
}
)
</script>
<template>
<ElIcon :class="prefixCls" :color="color" :size="size">
<svg v-if="isLocal" :class="getSvgClass" aria-hidden="true">
<use :xlink:href="symbolId" />
</svg>
<span v-else ref="elRef" :class="$attrs.class" :style="getIconifyStyle">
<span :class="getSvgClass" :data-icon="symbolId"></span>
</span>
</ElIcon>
</template>

View File

@@ -0,0 +1,229 @@
<script lang="ts" setup>
import { CSSProperties ,ref,toRef,computed,watch} from 'vue'
import { cloneDeep } from 'lodash-es'
import { IconJson } from '@/components/Icon/src/data'
defineOptions({ name: 'IconSelect' })
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined
const props = defineProps({
modelValue: {
require: false,
type: String
}
})
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
const visible = ref(false)
const inputValue = toRef(props, 'modelValue')
const iconList = ref(IconJson)
const icon = ref('add-location')
const currentActiveType = ref('ep:')
// 深拷贝图标数据,前端做搜索
const copyIconList = cloneDeep(iconList.value)
const pageSize = ref(96)
const currentPage = ref(1)
// 搜索条件
const filterValue = ref('')
const tabsList = [
{
label: 'Element Plus',
name: 'ep:'
},
{
label: 'Font Awesome 4',
name: 'fa:'
},
{
label: 'Font Awesome 5 Solid',
name: 'fa-solid:'
}
]
const pageList = computed(() => {
if (currentPage.value === 1) {
return copyIconList[currentActiveType.value]
?.filter((v) => v.includes(filterValue.value))
.slice(currentPage.value - 1, pageSize.value)
} else {
return copyIconList[currentActiveType.value]
?.filter((v) => v.includes(filterValue.value))
.slice(
pageSize.value * (currentPage.value - 1),
pageSize.value * (currentPage.value - 1) + pageSize.value
)
}
})
const iconCount = computed(() => {
return copyIconList[currentActiveType.value] == undefined
? 0
: copyIconList[currentActiveType.value].length
})
const iconItemStyle = computed((): ParameterCSSProperties => {
return (item) => {
if (inputValue.value === currentActiveType.value + item) {
return {
borderColor: 'var(--el-color-primary)',
color: 'var(--el-color-primary)'
}
}
}
})
function handleClick({ props }) {
currentPage.value = 1
currentActiveType.value = props.name
emit('update:modelValue', currentActiveType.value + iconList.value[currentActiveType.value][0])
icon.value = iconList.value[currentActiveType.value][0]
}
function onChangeIcon(item) {
icon.value = item
emit('update:modelValue', currentActiveType.value + item)
visible.value = false
}
function onCurrentChange(page) {
currentPage.value = page
}
watch(
() => {
return props.modelValue
},
() => {
if (props.modelValue && props.modelValue.indexOf(':') >= 0) {
currentActiveType.value = props.modelValue.substring(0, props.modelValue.indexOf(':') + 1)
icon.value = props.modelValue.substring(props.modelValue.indexOf(':') + 1)
}
}
)
watch(
() => {
return filterValue.value
},
() => {
currentPage.value = 1
}
)
</script>
<template>
<div class="selector">
<ElInput v-model="inputValue" @click="visible = !visible">
<template #append>
<ElPopover
:popper-options="{
placement: 'auto'
}"
:visible="visible"
:width="350"
popper-class="pure-popper"
trigger="click"
>
<template #reference>
<div
class="h-32px w-40px flex cursor-pointer items-center justify-center"
@click="visible = !visible"
>
<Icon :icon="currentActiveType + icon" />
</div>
</template>
<ElInput v-model="filterValue" class="p-2" clearable placeholder="搜索图标" />
<ElDivider border-style="dashed" />
<ElTabs v-model="currentActiveType" @tab-click="handleClick">
<ElTabPane
v-for="(pane, index) in tabsList"
:key="index"
:label="pane.label"
:name="pane.name"
>
<ElDivider border-style="dashed" class="tab-divider" />
<ElScrollbar height="220px">
<ul class="ml-2 flex flex-wrap px-2">
<li
v-for="(item, key) in pageList"
:key="key"
:style="iconItemStyle(item)"
:title="item"
class="icon-item mr-2 mt-1 w-1/10 flex cursor-pointer items-center justify-center border border-solid p-2"
@click="onChangeIcon(item)"
>
<Icon :icon="currentActiveType + item" />
</li>
</ul>
</ElScrollbar>
</ElTabPane>
</ElTabs>
<ElDivider border-style="dashed" />
<ElPagination
:current-page="currentPage"
:page-size="pageSize"
:total="iconCount"
background
class="h-10 flex items-center justify-center"
layout="prev, pager, next"
small
@current-change="onCurrentChange"
/>
</ElPopover>
</template>
</ElInput>
</div>
</template>
<style lang="scss" scoped>
.el-divider--horizontal {
margin: 1px auto !important;
}
.tab-divider.el-divider--horizontal {
margin: 0 !important;
}
.icon-item {
&:hover {
color: var(--el-color-primary);
border-color: var(--el-color-primary);
transform: scaleX(1.05);
transition: all 0.4s;
}
}
:deep(.el-tabs__nav-next) {
font-size: 15px;
line-height: 32px;
box-shadow: -5px 0 5px -6px #ccc;
}
:deep(.el-tabs__nav-prev) {
font-size: 15px;
line-height: 32px;
box-shadow: 5px 0 5px -6px #ccc;
}
:deep(.el-input-group__append) {
padding: 0;
}
:deep(.el-tabs__item) {
height: 30px;
font-size: 12px;
font-weight: normal;
line-height: 30px;
}
:deep(.el-tabs__header),
:deep(.el-tabs__nav-wrap) {
position: static;
margin: 0;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +1,71 @@
import { readFileSync, readdirSync } from 'fs'
let idPerfix = ''
const iconNames: string[] = []
const svgTitle = /<svg([^>+].*?)>/
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
const hasViewBox = /(viewBox="[^>+].*?")/g
const clearReturn = /(\r)|(\n)/g
// 清理 svg 的 fill
const clearFill = /(fill="[^>+].*?")/g
function findSvgFile(dir: string): string[] {
const svgRes = []
const dirents = readdirSync(dir, {
withFileTypes: true,
})
for (const dirent of dirents) {
iconNames.push(`${idPerfix}-${dirent.name.replace('.svg', '')}`)
if (dirent.isDirectory()) {
svgRes.push(...findSvgFile(dir + dirent.name + '/'))
} else {
const svg = readFileSync(dir + dirent.name)
.toString()
.replace(clearReturn, '')
.replace(clearFill, 'fill=""')
.replace(svgTitle, ($1, $2) => {
let width = 0
let height = 0
let content = $2.replace(clearHeightWidth, (s1: string, s2: string, s3: number) => {
if (s2 === 'width') {
width = s3
} else if (s2 === 'height') {
height = s3
}
return ''
})
if (!hasViewBox.test($2)) {
content += `viewBox="0 0 ${width} ${height}"`
}
return `<symbol id="${idPerfix}-${dirent.name.replace('.svg', '')}" ${content}>`
})
.replace('</svg>', '</symbol>')
svgRes.push(svg)
}
}
return svgRes
}
export const svgBuilder = (path: string, perfix = 'local') => {
if (path === '') return
idPerfix = perfix
const res = findSvgFile(path)
return {
name: 'svg-transform',
transformIndexHtml(html: string) {
/* eslint-disable */
return html.replace(
'<body>',
`
<body>
<svg id="local-icon" data-icon-name="${iconNames.join(
','
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
${res.join('')}
</svg>
`
)
/* eslint-enable */
},
}
}
import { readFileSync, readdirSync } from 'fs'
let idPerfix = ''
const iconNames: string[] = []
const svgTitle = /<svg([^>+].*?)>/
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
const hasViewBox = /(viewBox="[^>+].*?")/g
const clearReturn = /(\r)|(\n)/g
// 清理 svg 的 fill
const clearFill = /(fill="[^>+].*?")/g
function findSvgFile(dir: string): string[] {
const svgRes = []
const dirents = readdirSync(dir, {
withFileTypes: true,
})
for (const dirent of dirents) {
iconNames.push(`${idPerfix}-${dirent.name.replace('.svg', '')}`)
if (dirent.isDirectory()) {
svgRes.push(...findSvgFile(dir + dirent.name + '/'))
} else {
const svg = readFileSync(dir + dirent.name)
.toString()
.replace(clearReturn, '')
.replace(clearFill, 'fill=""')
.replace(svgTitle, ($1, $2) => {
let width = 0
let height = 0
let content = $2.replace(clearHeightWidth, (s1: string, s2: string, s3: number) => {
if (s2 === 'width') {
width = s3
} else if (s2 === 'height') {
height = s3
}
return ''
})
if (!hasViewBox.test($2)) {
content += `viewBox="0 0 ${width} ${height}"`
}
return `<symbol id="${idPerfix}-${dirent.name.replace('.svg', '')}" ${content}>`
})
.replace('</svg>', '</symbol>')
svgRes.push(svg)
}
}
return svgRes
}
export const svgBuilder = (path: string, perfix = 'local') => {
if (path === '') return
idPerfix = perfix
const res = findSvgFile(path)
return {
name: 'svg-transform',
transformIndexHtml(html: string) {
/* eslint-disable */
return html.replace(
'<body>',
`
<body>
<svg id="local-icon" data-icon-name="${iconNames.join(
','
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
${res.join('')}
</svg>
`
)
/* eslint-enable */
},
}
}

View File

@@ -1,49 +1,49 @@
<template>
<div v-if="isUrl" :style="urlIconStyle" class="url-svg svg-icon icon" />
<svg v-else class="svg-icon icon" :style="iconStyle">
<use :href="iconName" />
</svg>
</template>
<script setup lang="ts">
import { computed, type CSSProperties } from 'vue'
import { isExternal } from '@/utils/common'
interface Props {
name: string
size: string
color: string
}
const props = withDefaults(defineProps<Props>(), {
name: '',
size: '18px',
color: '#000000',
})
const s = `${props.size.replace('px', '')}px`
const iconName = computed(() => `#${props.name}`)
const iconStyle = computed((): CSSProperties => {
return {
color: props.color,
fontSize: s,
}
})
const isUrl = computed(() => isExternal(props.name))
const urlIconStyle = computed(() => {
return {
width: s,
height: s,
mask: `url(${props.name}) no-repeat 50% 50%`,
'-webkit-mask': `url(${props.name}) no-repeat 50% 50%`,
}
})
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
fill: currentColor;
overflow: hidden;
}
</style>
<template>
<div v-if="isUrl" :style="urlIconStyle" class="url-svg svg-icon icon" />
<svg v-else class="svg-icon icon" :style="iconStyle">
<use :href="iconName" />
</svg>
</template>
<script setup lang="ts">
import { computed, type CSSProperties } from 'vue'
import { isExternal } from '@/utils/common'
interface Props {
name: string
size: string
color: string
}
const props = withDefaults(defineProps<Props>(), {
name: '',
size: '18px',
color: '#000000',
})
const s = `${props.size.replace('px', '')}px`
const iconName = computed(() => `#${props.name}`)
const iconStyle = computed((): CSSProperties => {
return {
color: props.color,
fontSize: s,
}
})
const isUrl = computed(() => isExternal(props.name))
const urlIconStyle = computed(() => {
return {
width: s,
height: s,
mask: `url(${props.name}) no-repeat 50% 50%`,
'-webkit-mask': `url(${props.name}) no-repeat 50% 50%`,
}
})
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
fill: currentColor;
overflow: hidden;
}
</style>

View File

@@ -1,47 +1,27 @@
<!-- 设备管理使用折叠面板渲染多个tree -->
<template>
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
<Icon
v-show="menuCollapse"
@click="onMenuCollapse"
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''"
size="18"
class="fold ml10 mt20 menu-collapse"
style="cursor: pointer"
/>
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse"
style="cursor: pointer" />
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
<div style="display: flex; align-items: center" class="mb10">
<!-- <el-form-item> -->
<el-input
maxlength="32"
show-word-limit
v-model.trim="filterText"
autocomplete="off"
placeholder="请输入内容"
clearable
>
<el-input maxlength="32" show-word-limit v-model.trim="filterText" autocomplete="off"
placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<!-- </el-form-item> -->
<Icon
@click="onMenuCollapse"
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''"
size="18"
class="fold ml10 menu-collapse"
style="cursor: pointer"
v-if="props.canExpand"
/>
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
style="cursor: pointer" v-if="props.canExpand" />
</div>
<el-collapse
:accordion="true"
v-model.trim="activeName"
style="flex: 1; height: 100%"
@change="changeDevice"
>
<el-collapse :accordion="true" v-model.trim="activeName" style="flex: 1; height: 100%"
@change="changeDevice">
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
<el-option label="功能调试" value="2"></el-option>
@@ -50,24 +30,12 @@
</el-select>
<el-tree
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
ref="treeRef1"
:props="defaultProps"
highlight-current
:filter-node-method="filterNode"
node-key="id"
default-expand-all
v-bind="$attrs"
:data="zlDevList"
style="overflow: auto"
>
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
node-key="id" default-expand-all v-bind="$attrs" :data="zlDevList" style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -76,24 +44,13 @@
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
<el-tree
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
ref="treeRef2"
:props="defaultProps"
highlight-current
default-expand-all
:filter-node-method="filterNode"
node-key="id"
:data="bxsDeviceData"
v-bind="$attrs"
style="overflow: auto"
>
ref="treeRef2" :props="defaultProps" highlight-current default-expand-all
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -102,24 +59,13 @@
<el-collapse-item title="云前置设备" name="2" v-if="frontDeviceData.length != 0">
<el-tree
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
ref="treeRef3"
:props="defaultProps"
highlight-current
default-expand-all
:filter-node-method="filterNode"
node-key="id"
:data="frontDeviceData"
v-bind="$attrs"
style="overflow: auto"
>
ref="treeRef3" :props="defaultProps" highlight-current default-expand-all
:filter-node-method="filterNode" node-key="id" :data="frontDeviceData" v-bind="$attrs"
style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -174,18 +120,21 @@ watch(
if (val && val.length != 0) {
val.map((item: any) => {
if (item.name == '治理设备') {
zlDeviceData.value = []
item.children.map((vv: any) => {
zlDeviceData.value.push(vv)
})
} else if (item.name == '便携式设备') {
bxsDeviceData.value = []
item.children.map((vv: any) => {
bxsDeviceData.value.push(vv)
})
}else if (item.name == '云前置设备') {
} else if (item.name == '云前置设备') {
frontDeviceData.value = []
item.children.map((vv: any) => {
frontDeviceData.value.push(vv)
})
}
})
}
@@ -199,13 +148,15 @@ watch(
watch(filterText, val => {
if (activeName.value == '0') {
treeRef1.value!.filter(val)
} else if(activeName.value == '1'){
} else if (activeName.value == '1') {
treeRef2.value!.filter(val)
}else {
} else {
treeRef3.value!.filter(val)
}
})
watch(process, val => {
if (val == '') {
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
} else {
@@ -281,6 +232,7 @@ const changeDevice = (val: any) => {
let arr1: any = []
//zlDeviceData
zlDevList.value.forEach((item: any) => {
item.children.forEach((item2: any) => {
item2.children.forEach((item3: any) => {
@@ -288,6 +240,7 @@ const changeDevice = (val: any) => {
})
})
})
let arr2: any = []
bxsDeviceData.value.forEach((item: any) => {
// item.children.forEach((item2: any) => {
@@ -296,7 +249,7 @@ const changeDevice = (val: any) => {
})
let arr3: any = []
frontDeviceData.value.forEach((item: any) => {
item.children.forEach((item2: any) => {
item.children.forEach((item2: any) => {
item2.children.forEach((item3: any) => {
arr3.push(item3)
})
@@ -306,21 +259,21 @@ const changeDevice = (val: any) => {
arr2.map((item: any) => {
item.checked = false
})
treeRef1.value && treeRef1.value.setCurrentKey(arr1[0].id)
treeRef1.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
emit('changeDeviceType', activeName.value, arr1[0])
}
if (val == '1') {
arr1.map((item: any) => {
item.checked = false
})
treeRef2.value && treeRef2.value.setCurrentKey(arr2[0].id)
treeRef2.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
emit('changeDeviceType', activeName.value, arr2[0])
}
if (val == '2') {
arr3.map((item: any) => {
item.checked = false
})
treeRef3.value && treeRef3.value.setCurrentKey(arr3[0].id)
treeRef3.value && treeRef3.value.setCurrentKey(arr3[0]?.id)
emit('changeDeviceType', activeName.value, arr3[0])
}
}

View File

@@ -1,16 +1,9 @@
<!-- 设备监控使用折叠面板渲染多个tree -->
<template>
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
<Icon
v-show="menuCollapse"
@click="onMenuCollapse"
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''"
size="18"
class="fold ml10 mt20 menu-collapse"
style="cursor: pointer"
v-if="route.path != '/admin/govern/reportCore/statistics/index'"
/>
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse" style="cursor: pointer"
v-if="route.path != '/admin/govern/reportCore/statistics/index'" />
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
@@ -18,22 +11,13 @@
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<Icon
@click="onMenuCollapse"
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''"
size="18"
class="fold ml10 menu-collapse"
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
style="cursor: pointer"
v-if="props.canExpand && route.path != '/admin/govern/reportCore/statistics/index'"
/>
v-if="props.canExpand && route.path != '/admin/govern/reportCore/statistics/index'" />
</div>
<el-collapse
:accordion="true"
v-model.trim="activeName"
style="flex: 1; height: 100%"
@change="changeDevice"
>
<el-collapse :accordion="true" v-model.trim="activeName" style="flex: 1; height: 100%"
@change="changeDevice">
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
<el-option label="功能调试" value="2"></el-option>
@@ -43,24 +27,12 @@
<el-tree
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
ref="treeRef1"
:props="defaultProps"
highlight-current
:filter-node-method="filterNode"
node-key="id"
default-expand-all
v-bind="$attrs"
:data="zlDevList"
style="overflow: auto"
>
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
node-key="id" default-expand-all v-bind="$attrs" :data="zlDevList" style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -69,24 +41,13 @@
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
<el-tree
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
ref="treeRef2"
:props="defaultProps"
highlight-current
default-expand-all
:filter-node-method="filterNode"
node-key="id"
:data="bxsDeviceData"
v-bind="$attrs"
style="overflow: auto"
>
ref="treeRef2" :props="defaultProps" highlight-current default-expand-all
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -95,24 +56,13 @@
<el-collapse-item title="云前置设备" name="2" v-if="yqfDeviceData.length != 0">
<el-tree
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
ref="treeRef3"
:props="defaultProps"
highlight-current
default-expand-all
:filter-node-method="filterNode"
node-key="id"
:data="yqfDeviceData"
v-bind="$attrs"
style="overflow: auto"
>
ref="treeRef3" :props="defaultProps" highlight-current default-expand-all
:filter-node-method="filterNode" node-key="id" :data="yqfDeviceData" v-bind="$attrs"
style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
@@ -169,21 +119,24 @@ watch(
if (val && val.length != 0) {
val.map((item: any) => {
if (item.name == '治理设备') {
zlDeviceData.value = []
item.children.map((vv: any) => {
zlDeviceData.value.push(vv)
})
// console.log('🚀 ~ item.children.map ~ zlDeviceData.value:', zlDeviceData.value)
} else if (item.name == '便携式设备') {
bxsDeviceData.value = []
item.children.map((vv: any) => {
bxsDeviceData.value.push(vv)
})
}else if (item.name == '云前置设备') {
} else if (item.name == '云前置设备') {
yqfDeviceData.value = []
item.children.map((vv: any) => {
yqfDeviceData.value.push(vv)
})
}
})
}
},
{
@@ -195,9 +148,9 @@ watch(
watch(filterText, val => {
if (activeName.value == '0') {
treeRef1.value!.filter(val)
} else if(activeName.value == '1') {
} else if (activeName.value == '1') {
treeRef2.value!.filter(val)
}else {
} else {
treeRef3.value!.filter(val)
}
})
@@ -213,7 +166,7 @@ watch(process, val => {
})
const changeDevice = (val: any) => {
console.log('changeDevice', val)
console.log('changeDevice', val)
let arr1: any = []
//zlDeviceData
zlDevList.value.forEach((item: any) => {
@@ -233,7 +186,7 @@ const changeDevice = (val: any) => {
})
let arr3: any = []
yqfDeviceData.value.forEach((item: any) => {
item.children.forEach((item2: any) => {
item.children.forEach((item2: any) => {
item2.children.forEach((item3: any) => {
item3.children.forEach((item4: any) => {
arr3.push(item4)
@@ -256,7 +209,7 @@ const changeDevice = (val: any) => {
treeRef2?.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
emit('changePointType', activeName.value, arr2[0])
}
if(val == '2'){
if (val == '2') {
arr3.map((item: any) => {
item.checked = false
})
@@ -381,6 +334,4 @@ onMounted(() => {
display: flex;
align-items: center;
}
</style>