文档片段全面改进,不使用render

This commit is contained in:
2025-04-20 17:50:07 +08:00
parent e43f9230eb
commit 68c93f5d83
48 changed files with 1330 additions and 732 deletions

View File

@@ -0,0 +1,162 @@
<template>
<div class="chen-demand-list">
<div class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
<div class="arco-table-container">
<table class="arco-table-element" cellpadding="0" cellspacing="0">
<thead>
<tr class="arco-table-tr">
<th class="arco-table-th" :width="20">
<span class="arco-table-cell arco-table-cell-align-center">
<a-tooltip content="添加步骤">
<a-button type="primary" size="mini" shape="round" @click="addItem">
新增步骤+
</a-button>
</a-tooltip>
</span>
</th>
<th class="arco-table-th" :width="400">
<span class="arco-table-cell arco-table-cell-align-center">
<span class="arco-table-th-title">操作</span>
</span>
</th>
<th class="arco-table-th" :width="310">
<span class="arco-table-cell arco-table-cell-align-center">
<span class="arco-table-th-title">预期</span>
</span>
</th>
</tr>
</thead>
<tbody>
<!-- 根据subStep渲染 -->
<template
v-if="modelValue && modelValue.length > 0"
v-for="(stepItem, index) in modelValue"
:key="index"
>
<tr class="arco-table-tr">
<td class="arco-table-td">
<span class="arco-table-cell justify-center gap-1.5">
<!-- 删除单项按钮 -->
<a-button
type="primary"
status="danger"
size="mini"
shape="round"
@click="deleteItem(index)"
:disabled="modelValue.length <= 1"
>
<template #icon><icon-close /></template>
</a-button>
<a-tooltip content="复制该项添加">
<a-button
type="primary"
status="warning"
size="mini"
shape="round"
@click="copyItem(index)"
>
<template #icon>
<icon-copy />
</template>
</a-button>
</a-tooltip>
<a-button-group shape="round" size="mini">
<a-button type="primary" @click="moveUp(index)">
<icon-arrow-rise />
</a-button>
<a-button type="primary" @click="moveDown(index)">
<icon-arrow-fall />
</a-button>
</a-button-group>
</span>
</td>
<td class="arco-table-td">
<span class="arco-table-cell">
<a-textarea auto-size v-model="stepItem.operation"></a-textarea>
</span>
</td>
<td class="arco-table-td">
<span class="arco-table-cell">
<a-textarea auto-size v-model="stepItem.expect"></a-textarea>
</span>
</td>
</tr>
</template>
<template v-else>
<tr>
<td colspan="3">
<div class="flex justify-center items-center p-2 border-1">
<a-alert>暂无测试子项条目请添加</a-alert>
</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { type Ref, nextTick } from "vue"
// 辅助函数当modelValue不是列表时候
function handleIsNotArray() {
if (Array.isArray(modelValue.value)) return
modelValue.value = []
}
// 定义value数据
interface ISubStep {
operation: string
expect: string
}
// 绑定外部数据预期是列表有operation、expect两个字段
const modelValue = defineModel() as unknown as Ref<ISubStep[]>
// 单纯新增 - modalValue新增一行
const addItem = async () => {
handleIsNotArray()
await nextTick() // 因为要等待modelValue值变化DOM渲染完毕
modelValue.value.push({ operation: "", expect: "" })
}
// 删除指定行
const deleteItem = (index: number) => {
modelValue.value = modelValue.value.filter((_, idx) => idx !== index)
}
// 复制单项
const copyItem = (index: number) => {
const newItem = modelValue.value[index]
modelValue.value = [...modelValue.value, newItem]
}
// 辅助函数交换列表两个元素
function swapItems(idx1: number, idx2: number) {
const arr = modelValue.value
;[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
}
// 向下移动
const moveDown = (index: number) => {
if (index === modelValue.value.length - 1) return
swapItems(index, index + 1)
}
// 向上移动
const moveUp = (index: number) => {
if (index === 0) return
swapItems(index, index - 1)
}
</script>
<style lang="less" scoped>
:deep(.arco-form-item-content-flex) {
display: block;
}
:deep(.arco-table-cell .arco-form-item) {
margin-bottom: 0;
}
</style>

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<a-form-item
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
@@ -236,7 +232,7 @@ function swapItems(idx1, idx2) {
;[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
}
// 修改源码上移动和下移动
// 修改源码上移动和下移动
const moveUp = (itemIndex) => {
const itemLength = formModel.value[props.component.dataIndex].length
// 如果是第一个,不做操作
@@ -290,9 +286,15 @@ onMounted(async () => {
})
</script>
<style scoped>
<style scoped lang="less">
:deep(.arco-form-item-content-flex) {
display: block;
position: relative;
.arco-radio-group {
position: absolute;
top: 50%;
transform: translateY(-40%);
}
}
:deep(.arco-table-cell .arco-form-item) {
margin-bottom: 0;

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<td
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<table
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<ma-form-item
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
@@ -68,7 +64,7 @@ const columns = inject("columns")
const rv = async (ev, value = undefined) =>
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
const index = props.customField ?? props.component.dataIndex
//后端传入数字类型导致报错 Invalid prop: type check failed for prop "modelValue". Expected String with value "0", got Number with value 0
// 后端传入数字类型导致报错 Invalid prop: type check failed for prop "modelValue". Expected String with value "0", got Number with value 0
const toVal = ref(`${get(formModel.value, index)}`)
const value = ref()
if (toVal.value != "undefined") {

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<a-form-item
:label="props.component.title"

View File

@@ -341,7 +341,7 @@ const handleStdFormSubmit = async (data, done) => {
}
dictList.value["standard"].push(newInfo)
// 清空当前数据
stdFormData.value = initStdFormData
stdFormData.value = { ...initStdFormData }
Notification.success("添加成功,请回到输入框进行选择")
} catch (err) {
Notification.error("请求错误,请重试或在数据管理页面添加")

View File

@@ -0,0 +1,53 @@
<template>
<!-- 组件外部的 form-item -->
<ma-form-item
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
:component="props.component"
:custom-field="props.customField"
>
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
<!-- 调用自己开发的自定义组件具体名称改成自己的 -->
<ChenDemandList v-model="value"></ChenDemandList>
</slot>
</ma-form-item>
</template>
<script setup>
// ~~~~start~~~~
import ChenDemandList from "../Customs/ChenDemandList.vue"
// ~~~~end~~~~
import { ref, inject, onMounted, watch } from "vue"
// 引入处理索引的函数
import { get, set } from "lodash-es"
// 引入 MaFormItem 组件
import MaFormItem from "./form-item.vue"
// 引入处理事件的函数
import { maEvent } from "../js/formItemMixin.js"
// 组件都需要定义以下的props
const props = defineProps({
component: Object,
customField: { type: String, default: undefined }
})
// form数据列表
const formModel = inject("formModel")
// 该组件在form数据的索引名称
const index = props.customField ?? props.component.dataIndex
// 该组件的表单数据
const value = ref(get(formModel.value, index))
// 监听组件数据的改变
watch(
() => get(formModel.value, index),
(vl) => (value.value = vl)
)
watch(
() => value.value,
(v) => set(formModel.value, index, v)
)
// 绑定组件事件
maEvent.handleCommonEvent(props.component, "onCreated")
onMounted(() => {
maEvent.handleCommonEvent(props.component, "onMounted")
})
</script>

View File

@@ -1,7 +1,3 @@
<!--
- @Author XXX
- @Link XXX
-->
<template>
<div class="w-full">
<a-spin :loading="formLoading" :tip="options.loadingText" class="w-full ma-form-spin">