mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-29 23:44:41 +00:00
refactor: 升级Vue SFC深度选择器语法为::v-deep
本次提交将项目中所有使用`::deep`的CSS深度选择器统一替换为Vue 3官方推荐的`::v-deep`语法,修复了旧版语法在新版本Vue生态中的兼容性问题,同时修正了部分组件的响应式表单定义方式,将`reactive`配合`Object.assign`的写法调整为更符合Vue 3组合式API规范的`ref`响应式状态写法,整体优化了代码的可维护性和兼容性。
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user