mirror of
https://github.com/Powerful-517/yys-editor.git
synced 2025-08-23 08:04:50 +00:00
增加全局dialog处理逻辑
This commit is contained in:
32
src/components/DialogManager.vue
Normal file
32
src/components/DialogManager.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useDialogs } from '../ts/useDialogs'
|
||||||
|
import ShikigamiSelect from './flow/nodes/yys/ShikigamiSelect.vue'
|
||||||
|
import YuhunSelect from './flow/nodes/yys/YuhunSelect.vue'
|
||||||
|
import PropertySelect from './flow/nodes/yys/PropertySelect.vue'
|
||||||
|
|
||||||
|
const { dialogs, closeDialog } = useDialogs();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ShikigamiSelect
|
||||||
|
v-if="dialogs.shikigami.show"
|
||||||
|
:showSelectShikigami="dialogs.shikigami.show"
|
||||||
|
:currentShikigami="dialogs.shikigami.data"
|
||||||
|
@closeSelectShikigami="closeDialog('shikigami')"
|
||||||
|
@updateShikigami="data => { dialogs.shikigami.callback?.(data, dialogs.shikigami.node); closeDialog('shikigami') }"
|
||||||
|
/>
|
||||||
|
<YuhunSelect
|
||||||
|
v-if="dialogs.yuhun.show"
|
||||||
|
:showSelectYuhun="dialogs.yuhun.show"
|
||||||
|
:currentYuhun="dialogs.yuhun.data"
|
||||||
|
@closeSelectYuhun="closeDialog('yuhun')"
|
||||||
|
@updateYuhun="data => { dialogs.yuhun.callback?.(data, dialogs.yuhun.node); closeDialog('yuhun') }"
|
||||||
|
/>
|
||||||
|
<PropertySelect
|
||||||
|
v-if="dialogs.property.show"
|
||||||
|
:showPropertySelect="dialogs.property.show"
|
||||||
|
:currentProperty="dialogs.property.data"
|
||||||
|
@closePropertySelect="closeDialog('property')"
|
||||||
|
@updateProperty="data => { dialogs.property.callback?.(data, dialogs.property.node); closeDialog('property') }"
|
||||||
|
/>
|
||||||
|
</template>
|
@@ -2,10 +2,8 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="show"
|
v-model="show"
|
||||||
title="请选择式神"
|
title="请选择式神"
|
||||||
@close="cancel"
|
|
||||||
:before-close="cancel"
|
|
||||||
>
|
>
|
||||||
<span>当前选择式神:{{ current.name }}</span>
|
<span>当前选择式神:{{ props.currentShikigami.name }}</span>
|
||||||
<div style="display: flex; align-items: center;">
|
<div style="display: flex; align-items: center;">
|
||||||
<el-input
|
<el-input
|
||||||
placeholder="请输入内容"
|
placeholder="请输入内容"
|
||||||
@@ -45,7 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import type { TabsPaneContext } from 'element-plus'
|
import type { TabsPaneContext } from 'element-plus'
|
||||||
import shikigamiData from "../../../../data/Shikigami.json"
|
import shikigamiData from "../../../../data/Shikigami.json"
|
||||||
|
|
||||||
@@ -58,7 +56,7 @@ interface Shikigami {
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentShikigami: {
|
currentShikigami: {
|
||||||
type: Object as () => Shikigami,
|
type: Object as () => Shikigami,
|
||||||
default: () => ({ name: '' })
|
default: () => ({ name: '未选择式神', avatar: '', rarity: '' })
|
||||||
},
|
},
|
||||||
showSelectShikigami: {
|
showSelectShikigami: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -68,10 +66,19 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['closeSelectShikigami', 'updateShikigami'])
|
const emit = defineEmits(['closeSelectShikigami', 'updateShikigami'])
|
||||||
|
|
||||||
const searchText = ref('') // 新增搜索文本
|
const show = computed({
|
||||||
|
get() {
|
||||||
|
return props.showSelectShikigami
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
if (!value) {
|
||||||
|
emit('closeSelectShikigami')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const searchText = ref('')
|
||||||
const activeName = ref('ALL')
|
const activeName = ref('ALL')
|
||||||
let current = ref({name:''})
|
|
||||||
const show = ref(false)
|
|
||||||
|
|
||||||
const rarityLevels = [
|
const rarityLevels = [
|
||||||
{ label: "全部", name: "ALL" },
|
{ label: "全部", name: "ALL" },
|
||||||
@@ -84,34 +91,16 @@ const rarityLevels = [
|
|||||||
{ label: "呱太", name: "G" },
|
{ label: "呱太", name: "G" },
|
||||||
]
|
]
|
||||||
|
|
||||||
watch(() => props.showSelectShikigami, (newVal) => {
|
|
||||||
show.value = newVal
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(() => props.currentShikigami, (newVal) => {
|
|
||||||
console.log("ShikigamiSelect.vue" + current.value.name)
|
|
||||||
current.value = newVal
|
|
||||||
console.log("ShikigamiSelect.vue" + current.value.name)
|
|
||||||
}, {deep: true})
|
|
||||||
|
|
||||||
|
|
||||||
const handleClick = (tab: TabsPaneContext) => {
|
const handleClick = (tab: TabsPaneContext) => {
|
||||||
console.log('Tab clicked:', tab)
|
console.log('Tab clicked:', tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancel = () => {
|
|
||||||
emit('closeSelectShikigami')
|
|
||||||
show.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirm = (shikigami: Shikigami) => {
|
const confirm = (shikigami: Shikigami) => {
|
||||||
emit('updateShikigami', shikigami)
|
emit('updateShikigami', shikigami)
|
||||||
searchText.value=''
|
searchText.value = ''
|
||||||
activeName.value='ALL'
|
activeName.value = 'ALL'
|
||||||
// cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 修改后的过滤函数
|
// 修改后的过滤函数
|
||||||
const filterShikigamiByRarityAndSearch = (rarity: string, search: string) => {
|
const filterShikigamiByRarityAndSearch = (rarity: string, search: string) => {
|
||||||
let filteredList = shikigamiData;
|
let filteredList = shikigamiData;
|
||||||
|
@@ -2,10 +2,8 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="show"
|
v-model="show"
|
||||||
title="请选择御魂"
|
title="请选择御魂"
|
||||||
@close="cancel"
|
|
||||||
:before-close="cancel"
|
|
||||||
>
|
>
|
||||||
<span>当前选择御魂:{{ current.name }}</span>
|
<span>当前选择御魂:{{ props.currentYuhun.name }}</span>
|
||||||
<div style="display: flex; align-items: center;">
|
<div style="display: flex; align-items: center;">
|
||||||
<el-input
|
<el-input
|
||||||
placeholder="请输入内容"
|
placeholder="请输入内容"
|
||||||
@@ -45,7 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import type { TabsPaneContext } from 'element-plus'
|
import type { TabsPaneContext } from 'element-plus'
|
||||||
import yuhunData from "../../../../data/Yuhun.json"
|
import yuhunData from "../../../../data/Yuhun.json"
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ interface Yuhun {
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentYuhun: {
|
currentYuhun: {
|
||||||
type: Object as () => Yuhun,
|
type: Object as () => Yuhun,
|
||||||
default: () => ({ name: '' })
|
default: () => ({ name: '未选择御魂', type: '', avatar: '' })
|
||||||
},
|
},
|
||||||
showSelectYuhun: {
|
showSelectYuhun: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -69,10 +67,19 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['closeSelectYuhun', 'updateYuhun'])
|
const emit = defineEmits(['closeSelectYuhun', 'updateYuhun'])
|
||||||
|
|
||||||
|
const show = computed({
|
||||||
|
get() {
|
||||||
|
return props.showSelectYuhun
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
if (!value) {
|
||||||
|
emit('closeSelectYuhun')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const searchText = ref('') // 搜索文本
|
const searchText = ref('') // 搜索文本
|
||||||
const activeName = ref('ALL')
|
const activeName = ref('ALL')
|
||||||
let current = ref({name:''})
|
|
||||||
const show = ref(false)
|
|
||||||
|
|
||||||
const yuhunTypes = [
|
const yuhunTypes = [
|
||||||
{ label: "全部", name: "ALL" },
|
{ label: "全部", name: "ALL" },
|
||||||
@@ -85,30 +92,14 @@ const yuhunTypes = [
|
|||||||
{ label: "特殊类", name: "Special" }
|
{ label: "特殊类", name: "Special" }
|
||||||
]
|
]
|
||||||
|
|
||||||
watch(() => props.showSelectYuhun, (newVal) => {
|
|
||||||
show.value = newVal
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(() => props.currentYuhun, (newVal) => {
|
|
||||||
console.log("YuhunSelect.vue" + current.value.name)
|
|
||||||
current.value = newVal
|
|
||||||
console.log("YuhunSelect.vue" + current.value.name)
|
|
||||||
}, {deep: true})
|
|
||||||
|
|
||||||
const handleClick = (tab: TabsPaneContext) => {
|
const handleClick = (tab: TabsPaneContext) => {
|
||||||
console.log('Tab clicked:', tab)
|
console.log('Tab clicked:', tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancel = () => {
|
|
||||||
emit('closeSelectYuhun')
|
|
||||||
show.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirm = (yuhun: Yuhun) => {
|
const confirm = (yuhun: Yuhun) => {
|
||||||
emit('updateYuhun', yuhun)
|
emit('updateYuhun', yuhun)
|
||||||
searchText.value=''
|
searchText.value = ''
|
||||||
activeName.value='ALL'
|
activeName.value = 'ALL'
|
||||||
// cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过滤函数
|
// 过滤函数
|
||||||
|
@@ -1,123 +0,0 @@
|
|||||||
// src/store/dialogStore.js
|
|
||||||
import { defineStore } from 'pinia';
|
|
||||||
|
|
||||||
export const useDialogStore = defineStore('dialog', {
|
|
||||||
state: () => ({
|
|
||||||
// 对话框可见性
|
|
||||||
shikigamiVisible: false,
|
|
||||||
yuhunVisible: false,
|
|
||||||
propertyVisible: false,
|
|
||||||
|
|
||||||
// 当前选中的节点信息
|
|
||||||
selectedNode: null,
|
|
||||||
|
|
||||||
// 当前选中的数据(式神、御魂、属性)
|
|
||||||
currentShikigami: { name: '未选择式神', avatar: '', rarity: '' },
|
|
||||||
currentYuhun: { name: '未选择御魂', avatar: '', type: '' },
|
|
||||||
currentProperty: { type: '未选择属性', priority: 'optional', description: '' },
|
|
||||||
}),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
// 打开式神选择对话框
|
|
||||||
openShikigamiDialog(node) {
|
|
||||||
this.selectedNode = node;
|
|
||||||
this.shikigamiVisible = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 关闭式神选择对话框
|
|
||||||
closeShikigamiDialog() {
|
|
||||||
this.shikigamiVisible = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 更新式神信息
|
|
||||||
updateShikigami(shikigami) {
|
|
||||||
if (this.selectedNode) {
|
|
||||||
try {
|
|
||||||
// 获取节点引用,尝试多种方式获取 Vue 组件实例
|
|
||||||
const nodeElement = document.querySelector(`[data-id="${this.selectedNode.id}"]`);
|
|
||||||
if (nodeElement) {
|
|
||||||
let nodeInstance = null;
|
|
||||||
|
|
||||||
// 方法1:通过 __vueParentComponent (Vue 3)
|
|
||||||
if (nodeElement.__vueParentComponent && nodeElement.__vueParentComponent.ctx) {
|
|
||||||
nodeInstance = nodeElement.__vueParentComponent.ctx;
|
|
||||||
}
|
|
||||||
// 方法2:通过 __vue_app__ (Vue 3)
|
|
||||||
else if (nodeElement.__vue_app__) {
|
|
||||||
nodeInstance = nodeElement.__vue_app__;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果找到实例并且有更新方法,调用它
|
|
||||||
if (nodeInstance && nodeInstance.updateNodeShikigami) {
|
|
||||||
nodeInstance.updateNodeShikigami(shikigami);
|
|
||||||
console.log('式神信息已更新:', shikigami.name);
|
|
||||||
} else {
|
|
||||||
console.warn('无法调用节点更新方法');
|
|
||||||
// 备用方案:通过全局事件总线传递更新
|
|
||||||
window.dispatchEvent(new CustomEvent('update-shikigami', {
|
|
||||||
detail: { nodeId: this.selectedNode.id, shikigami },
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('更新式神信息时出错:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭对话框
|
|
||||||
this.shikigamiVisible = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 打开御魂选择对话框
|
|
||||||
openYuhunDialog(node) {
|
|
||||||
this.selectedNode = node;
|
|
||||||
this.yuhunVisible = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 关闭御魂选择对话框
|
|
||||||
closeYuhunDialog() {
|
|
||||||
this.yuhunVisible = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 更新御魂信息
|
|
||||||
updateYuhun(yuhun) {
|
|
||||||
this.currentYuhun = yuhun;
|
|
||||||
this.closeYuhunDialog();
|
|
||||||
this.updateNodeData('yuhun', yuhun);
|
|
||||||
},
|
|
||||||
|
|
||||||
// 打开属性选择对话框
|
|
||||||
openPropertyDialog(node) {
|
|
||||||
this.selectedNode = node;
|
|
||||||
this.propertyVisible = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 关闭属性选择对话框
|
|
||||||
closePropertyDialog() {
|
|
||||||
this.propertyVisible = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 更新属性信息
|
|
||||||
updateProperty(property) {
|
|
||||||
this.currentProperty = property;
|
|
||||||
this.closePropertyDialog();
|
|
||||||
this.updateNodeData('property', property);
|
|
||||||
},
|
|
||||||
|
|
||||||
// 统一更新节点数据(通过事件总线或直接调用方法)
|
|
||||||
updateNodeData(type, data) {
|
|
||||||
if (this.selectedNode) {
|
|
||||||
// 方法1:通过事件总线触发更新(推荐)
|
|
||||||
window.dispatchEvent(new CustomEvent(`update-${type}`, {
|
|
||||||
detail: { nodeId: this.selectedNode.id, data }
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 方法2:直接调用节点实例的方法(如果节点组件支持)
|
|
||||||
// const nodeElement = document.querySelector(`[data-id="${this.selectedNode.id}"]`);
|
|
||||||
// if (nodeElement && nodeElement.__vueParentComponent?.ctx?.[`updateNode${type.charAt(0).toUpperCase() + type.slice(1)}`]) {
|
|
||||||
// nodeElement.__vueParentComponent.ctx[`updateNode${type.charAt(0).toUpperCase() + type.slice(1)}`](data);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
29
src/ts/useDialogs.ts
Normal file
29
src/ts/useDialogs.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const dialogs = reactive({
|
||||||
|
shikigami: { show: false, data: null, node: null, callback: null },
|
||||||
|
yuhun: { show: false, data: null, node: null, callback: null },
|
||||||
|
property: { show: false, data: null, node: null, callback: null }
|
||||||
|
})
|
||||||
|
|
||||||
|
function openDialog(type: string, data = null, node = null, callback = null) {
|
||||||
|
dialogs[type].show = true
|
||||||
|
dialogs[type].data = data
|
||||||
|
dialogs[type].node = node
|
||||||
|
dialogs[type].callback = callback
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDialog(type: string) {
|
||||||
|
dialogs[type].show = false
|
||||||
|
dialogs[type].data = null
|
||||||
|
dialogs[type].node = null
|
||||||
|
dialogs[type].callback = null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDialogs() {
|
||||||
|
return {
|
||||||
|
dialogs,
|
||||||
|
openDialog,
|
||||||
|
closeDialog
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user