refactor: 升级Vue SFC深度选择器语法为::v-deep

本次提交将项目中所有使用`::deep`的CSS深度选择器统一替换为Vue 3官方推荐的`::v-deep`语法,修复了旧版语法在新版本Vue生态中的兼容性问题,同时修正了部分组件的响应式表单定义方式,将`reactive`配合`Object.assign`的写法调整为更符合Vue 3组合式API规范的`ref`响应式状态写法,整体优化了代码的可维护性和兼容性。
This commit is contained in:
zhangtao
2026-05-11 15:46:18 +08:00
parent 4112942a14
commit 80d4f18e8b
64 changed files with 510 additions and 501 deletions
@@ -1039,7 +1039,7 @@ function handleViewJobState(row: JobLogTable) {
</script>
<style scoped>
.job-page ::deep(.data-table) {
.job-page ::v-deep(.data-table) {
height: 100%;
}
@@ -1151,7 +1151,7 @@ function handleViewJobState(row: JobLogTable) {
min-height: 0;
}
.execution-log-drawer ::deep(.el-card.data-table) {
.execution-log-drawer ::v-deep(.el-card.data-table) {
flex: 1;
min-height: 0;
}
@@ -583,7 +583,7 @@ const defaultCodeBlock = `def handler(*args, **kwargs):
}
`;
const formData = reactive<NodeForm>({
const formData = ref<NodeForm>({
id: undefined,
name: "",
code: undefined,
@@ -603,7 +603,7 @@ const kwargsList = ref<{ key: string; value: string }[]>([]);
const executeDialogVisible = ref(false);
const currentExecuteNode = ref<NodeTable | null>(null);
const executeFormData = reactive<{
const executeFormData = ref<{
node_display_name: string;
trigger: TriggerType;
trigger_args?: string;
@@ -618,7 +618,7 @@ const executeFormData = reactive<{
});
const executeDialogFormItems = computed<FormItem[]>(() => {
const trig = executeFormData.trigger;
const trig = executeFormData.value.trigger;
const showRange = !!trig && trig !== "now" && trig !== "date";
let triggerArgsLabel = "执行参数";
if (trig === "cron") triggerArgsLabel = "Cron表达式";
@@ -802,7 +802,7 @@ async function handleOpenDialog(type: "create" | "update", id?: number) {
: [];
} else {
dialogVisible.title = "新增节点";
formData.id = undefined;
formData.value.id = undefined;
argsList.value = [];
kwargsList.value = [];
}
@@ -822,10 +822,10 @@ async function handleSubmit() {
dataFormRef.value?.validate(async (valid: any) => {
if (valid) {
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
const submitData = {
...formData,
...formData.value,
args: argsList.value.filter((v) => v.trim()).join(",") || undefined,
kwargs:
kwargsList.value.filter((v) => v.key.trim()).length > 0
@@ -859,22 +859,22 @@ async function handleSubmit() {
const handlechangeCron = (cronStr: string) => {
if (typeof cronStr == "string") {
executeFormData.trigger_args = cronStr;
executeFormData.value.trigger_args = cronStr;
}
};
const handleIntervalConfirm = (value: string) => {
executeFormData.trigger_args = value;
executeFormData.value.trigger_args = value;
openInterval.value = false;
};
function handleOpenExecuteDialog(row: NodeTable) {
currentExecuteNode.value = row;
executeFormData.node_display_name = row.name ?? "";
executeFormData.trigger = "now";
executeFormData.trigger_args = undefined;
executeFormData.start_date = undefined;
executeFormData.end_date = undefined;
executeFormData.value.node_display_name = row.name ?? "";
executeFormData.value.trigger = "now";
executeFormData.value.trigger_args = undefined;
executeFormData.value.start_date = undefined;
executeFormData.value.end_date = undefined;
executeFormRenderKey.value += 1;
executeDialogVisible.value = true;
}
@@ -886,7 +886,7 @@ function handleCloseExecuteDialog() {
}
async function handleExecuteNode() {
if (executeFormData.trigger !== "now") {
if (executeFormData.value.trigger !== "now") {
const execForm = executeFormRef.value;
const elForm = execForm?.ref;
if (!elForm) return;
@@ -897,13 +897,13 @@ async function handleExecuteNode() {
try {
submitLoading.value = true;
const params: any = {
trigger: executeFormData.trigger,
trigger: executeFormData.value.trigger,
};
if (executeFormData.trigger !== "now") {
params.trigger_args = executeFormData.trigger_args;
params.start_date = executeFormData.start_date;
params.end_date = executeFormData.end_date;
if (executeFormData.value.trigger !== "now") {
params.trigger_args = executeFormData.value.trigger_args;
params.start_date = executeFormData.value.start_date;
params.end_date = executeFormData.value.end_date;
}
await NodeAPI.executeNode(currentExecuteNode.value?.id as number, params);
@@ -986,17 +986,17 @@ onMounted(async () => {
margin-top: 16px;
}
.node-splitter-art-form ::deep(.el-row > .el-col:last-child),
.execute-debug-art-form ::deep(.el-row > .el-col:last-child) {
.node-splitter-art-form ::v-deep(.el-row > .el-col:last-child),
.execute-debug-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.node-splitter-art-form ::deep(.el-form-item__content),
.execute-debug-art-form ::deep(.el-form-item__content) {
.node-splitter-art-form ::v-deep(.el-form-item__content),
.execute-debug-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
.node-splitter-art-form ::deep(section) {
.node-splitter-art-form ::v-deep(section) {
padding-right: 10px;
padding-left: 10px;
}
@@ -193,15 +193,15 @@ function handleDelete() {
flex: 1;
}
.panel-art-form ::deep(.el-row > .el-col:last-child) {
.panel-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.panel-art-form ::deep(.el-form-item__content) {
.panel-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
.panel-art-form ::deep(section) {
.panel-art-form ::v-deep(section) {
padding: 0;
}
</style>
@@ -159,13 +159,13 @@ watch(
}
}
formData.value = {
Object.assign(formData, {
type: newNode.type || "",
label: newNode.data?.label || "",
args: newNode.data?.args || "",
kwargsStr,
description: newNode.data?.description || "",
};
});
}
},
{ deep: true, immediate: true }
@@ -250,15 +250,15 @@ onMounted(() => {
flex: 1;
}
.panel-art-form ::deep(.el-row > .el-col:last-child) {
.panel-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.panel-art-form ::deep(.el-form-item__content) {
.panel-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
.panel-art-form ::deep(section) {
.panel-art-form ::v-deep(section) {
padding: 0;
}
</style>
@@ -183,7 +183,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed, onMounted, markRaw, type Component } from "vue";
import { ref, watch, computed, onMounted, markRaw, type Component } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Panel, VueFlow, useVueFlow } from "@vue-flow/core";
import { Background } from "@vue-flow/background";
@@ -230,7 +230,7 @@ const emit = defineEmits(["update:visible", "refresh"]);
const formRef = ref<InstanceType<typeof FaForm> | null>(null);
const workflowId = ref<number>();
const formData = reactive<Partial<WorkflowForm>>({
const formData = ref<Partial<WorkflowForm>>({
code: "",
name: "",
description: "",
@@ -904,7 +904,7 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
<style scoped lang="scss">
.workflow-drawer {
::deep(.el-drawer__body) {
::v-deep(.el-drawer__body) {
display: flex;
flex-direction: column;
}
@@ -916,11 +916,11 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
height: 100%;
}
::deep(.el-splitter) {
::v-deep(.el-splitter) {
flex: 1;
}
::deep(.el-splitter-panel) {
::v-deep(.el-splitter-panel) {
overflow: hidden;
}
@@ -961,12 +961,12 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
overflow: hidden;
}
::deep(.vue-flow__controls) {
::v-deep(.vue-flow__controls) {
display: flex;
flex-direction: column;
}
::deep(.vue-flow__controls-button) {
::v-deep(.vue-flow__controls-button) {
display: flex;
align-items: center;
justify-content: center;
@@ -978,7 +978,7 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
border: none;
}
::deep(.el-dropdown) {
::v-deep(.el-dropdown) {
display: flex;
}
@@ -996,15 +996,15 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
justify-content: flex-end;
}
.workflow-base-art-form ::deep(.el-row > .el-col:last-child) {
.workflow-base-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.workflow-base-art-form ::deep(.el-form-item__content) {
.workflow-base-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
.workflow-base-art-form ::deep(section) {
.workflow-base-art-form ::v-deep(section) {
padding: 0;
}
</style>
@@ -84,7 +84,7 @@
<FaForm
:key="nodeTypeFormRenderKey"
ref="formRef"
v-model="form"
v-model="formData"
:items="nodeTypeDialogFormItems"
:rules="rules"
label-width="100px"
@@ -125,7 +125,7 @@ import { useTable } from "@/hooks/core/useTable";
import type { ColumnOption } from "@/types/component";
import { ElMessage, ElMessageBox, ElTag } from "element-plus";
import type { FormRules } from "element-plus";
import { computed, h, reactive, ref } from "vue";
import { computed, h, ref } from "vue";
const BATCH_DELETE_MSG = "确认删除选中的编排节点类型吗?";
@@ -438,7 +438,7 @@ const defaultForm = (): WorkflowNodeTypeForm => ({
is_active: true,
});
const form = reactive<WorkflowNodeTypeForm>(defaultForm());
const formData = ref<WorkflowNodeTypeForm>(defaultForm());
const rules: FormRules = {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
@@ -448,7 +448,7 @@ const rules: FormRules = {
};
function resetForm() {
Object.assign(form, defaultForm());
Object.assign(formData.value, defaultForm());
editingId.value = null;
formRef.value?.ref?.resetFields();
formRef.value?.ref?.clearValidate();
@@ -467,14 +467,14 @@ async function openDialog(id?: number) {
const res = await WorkflowNodeTypeAPI.getWorkflowNodeTypeDetail(id);
const d = res.data?.data as WorkflowNodeTypeTable | undefined;
if (d) {
form.name = d.name || "";
form.code = d.code || "";
form.category = (d.category as WorkflowNodeTypeForm["category"]) || "action";
form.func = d.func || "";
form.args = d.args || "";
form.kwargs = d.kwargs || "{}";
form.sort_order = d.sort_order ?? 0;
form.is_active = d.is_active ?? true;
formData.value.name = d.name || "";
formData.value.code = d.code || "";
formData.value.category = (d.category as WorkflowNodeTypeForm["category"]) || "action";
formData.value.func = d.func || "";
formData.value.args = d.args || "";
formData.value.kwargs = d.kwargs || "{}";
formData.value.sort_order = d.sort_order ?? 0;
formData.value.is_active = d.is_active ?? true;
}
} catch {
ElMessage.error("加载详情失败");
@@ -488,9 +488,9 @@ async function openDialog(id?: number) {
async function submitForm() {
if (!formRef.value) return;
await formRef.value.validate();
if (form.kwargs?.trim()) {
if (formData.value.kwargs?.trim()) {
try {
JSON.parse(form.kwargs);
JSON.parse(formData.value.kwargs);
} catch {
ElMessage.error("关键字参数须为合法 JSON");
return;
@@ -499,12 +499,12 @@ async function submitForm() {
submitting.value = true;
try {
if (editingId.value) {
await WorkflowNodeTypeAPI.updateWorkflowNodeType(editingId.value, form);
await WorkflowNodeTypeAPI.updateWorkflowNodeType(editingId.value, formData.value);
ElMessage.success("更新成功");
dialogVisible.value = false;
await refreshUpdate();
} else {
await WorkflowNodeTypeAPI.createWorkflowNodeType(form);
await WorkflowNodeTypeAPI.createWorkflowNodeType(formData.value);
ElMessage.success("创建成功");
dialogVisible.value = false;
await refreshCreate();
@@ -518,11 +518,11 @@ async function submitForm() {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
</style>