mirror of
https://github.com/Powerful-517/yys-editor.git
synced 2026-03-05 15:05:27 +00:00
refactor: 重构属性编辑面板,支持Tab分离和节点类型切换
- 将属性面板分为游戏属性和图像属性两个Tab - 游戏属性Tab包含节点基本信息、类型切换和特定属性 - 图像属性Tab包含所有样式设置(填充、描边、阴影等) - 资产选择器节点支持在式神和御魂之间切换 - 切换节点类型时自动清空已选资产 - 优化AssetSelectorPanel,移除重复的资产库选择器
This commit is contained in:
114
src/components/common/GenericImageSelector.vue
Normal file
114
src/components/common/GenericImageSelector.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="show"
|
||||
:title="config.title"
|
||||
>
|
||||
<span v-if="config.currentItem">
|
||||
当前选择:{{ config.currentItem[config.itemRender.labelField] }}
|
||||
</span>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<div v-if="config.searchable !== false" style="display: flex; align-items: center;">
|
||||
<el-input
|
||||
v-model="searchText"
|
||||
placeholder="请输入内容"
|
||||
style="width: 200px; margin-right: 10px;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Tab分组 -->
|
||||
<el-tabs
|
||||
v-model="activeTab"
|
||||
type="card"
|
||||
class="demo-tabs"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="group in config.groups"
|
||||
:key="group.name"
|
||||
:label="group.label"
|
||||
:name="group.name"
|
||||
>
|
||||
<div style="max-height: 600px; overflow-y: auto;">
|
||||
<el-space wrap size="large">
|
||||
<div
|
||||
v-for="item in filteredItems(group)"
|
||||
:key="item[config.itemRender.labelField]"
|
||||
style="display: flex; flex-direction: column; justify-content: center"
|
||||
>
|
||||
<el-button
|
||||
:style="`width: ${imageSize}px; height: ${imageSize}px;`"
|
||||
@click="handleSelect(item)"
|
||||
>
|
||||
<img
|
||||
:src="item[config.itemRender.imageField]"
|
||||
:style="`width: ${imageSize - 1}px; height: ${imageSize - 1}px;`"
|
||||
>
|
||||
</el-button>
|
||||
<span style="text-align: center; display: block;">
|
||||
{{ item[config.itemRender.labelField] }}
|
||||
</span>
|
||||
</div>
|
||||
</el-space>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import type { SelectorConfig, GroupConfig } from '@/types/selector'
|
||||
|
||||
const props = defineProps<{
|
||||
config: SelectorConfig
|
||||
modelValue: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
'select': [item: any]
|
||||
}>()
|
||||
|
||||
const show = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
const searchText = ref('')
|
||||
const activeTab = ref('ALL')
|
||||
const imageSize = computed(() => props.config.itemRender.imageSize || 100)
|
||||
|
||||
// 过滤逻辑
|
||||
const filteredItems = (group: GroupConfig) => {
|
||||
let items = props.config.dataSource
|
||||
|
||||
// 分组过滤
|
||||
if (group.name !== 'ALL') {
|
||||
if (group.filter) {
|
||||
items = items.filter(group.filter)
|
||||
} else {
|
||||
items = items.filter(item =>
|
||||
item[props.config.groupField]?.toLowerCase() === group.name.toLowerCase()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索过滤
|
||||
if (searchText.value.trim()) {
|
||||
const searchFields = props.config.searchFields || [props.config.itemRender.labelField]
|
||||
items = items.filter(item =>
|
||||
searchFields.some(field =>
|
||||
item[field]?.toLowerCase().includes(searchText.value.toLowerCase())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
const handleSelect = (item: any) => {
|
||||
emit('select', item)
|
||||
searchText.value = ''
|
||||
activeTab.value = 'ALL'
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user