页面模型
# 自定义方法 TgRequest
//文件夹 web/apis/...
import TgRequest from '@coreRequest'
export function declare(params) {
return TgRequest({
url: '/...',
method: 'post',
data: params
})
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<tg-button type="primary" @click="declareHandle(scope.row)">申报</tg-button>
1
import {declareHandle} from '@/web/apis/...'
const declareHandle = (row)=>{
declare({}).then((data)=>{
})
}
1
2
3
4
5
2
3
4
5
# 列表页面
# 1. Setting.js 配置文件
// setting.js 配置文件
{
"whereList": [
{
"label": "cbeInvtCancel_inputDate",
"columnCode": "inputDate",
"span": 8,
"show": true,
"queryMode": "d",
"type": "date",
"start-placeholder": "开始时间",
"end-placeholder": "结束时间"
}
],
"selectList": [
{
"label": "cbeInvtCancel_platNo",
"columnCode": "platNo",
"show": true,
"sort": false,
"width": "100px",
"export": true,
"align": "left",
"header-align": "left",
"show-overflow-tooltip": false
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
属性名 | 说明 | 类型 | 可选值 | 默认值 | |
---|---|---|---|---|---|
whereList | 查询条件 | object | -- | -- | |
label | 字段名称(国际化标志) | string | -- | -- | |
columnCode | 字段名称 对应列内容的字段名 | string | -- | -- | |
span | 布局,一行24 | number | -- | -- | |
show | 是否默认显示。 不显示 false | 显示 true | 显示同时不支持用户自定义切换显示 1 (数字)。 | boolean | Number | -- | false | |
queryMode | 查询字段匹配规则 | string | -- | -- | |
type | 控件类型 | string | text 输入框 ; | -- | |
date 日期 (格式:年月日) | |||||
datetime 日期时间(格式:年月日:时分秒) | |||||
placeholder | 输入框占位文本(输入框,下拉框) | string | -- | -- | |
start-placeholder | 范围选择时开始日期的占位内容 | string | -- | -- | |
end-placeholder | 范围选择时结束日期的占位内容 | string | -- | -- | |
selectList | 查询结果 | -- | -- | ||
label | 字段名称(国际化标志) | string | -- | -- | |
columnCode | 字段名称 对应列内容的字段名 | string | -- | -- | |
show | 是否默认显示 | boolean | -- | false | |
sort | 是否排序 | boolean | -- | false | |
width | 列宽 | string | 例如 100px | 160px | |
export | 是否默认导出此项 | boolean | number | string | 1 不支持用户设置是否导出此项,此项默认不导出 | false | |
align | 对齐方式 | string | left / center / right | left | |
header-align | 表头对齐方式, 若不设置该项,则使用表格的对齐方式 | string | left / center / right | ||
show-overflow-tooltip | 是否隐藏额外内容并在单元格悬停时使用 Tooltip 显示它们。这将影响全部列的展示。 | boolean | -- | false |
# 2. 筛选条件 TgFilter
# 2.1 重置查询项组件内容 template
<!-- 筛选条件 -->
<tg-filter :version="version" :data="setting.whereList" @search="search" @reset="reset" @updateConfig="customConfig">
<!-- 插槽名为 whereList中对应的 columnCode 的值 -->
<template #logisticsCode>
<tg-choose v-model="form.logisticsCode" data-type="EBC_CODE" />
</template>
</tg-filter>
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2.2 查询条件增加校验 addRuleEx
<!--
如下校验提示,选其中一个
validateMessage="提示信息" 或者 <template #tg_validate>提示信息</template>
-->
<tg-filter
<!-- 增加如下校验规则 -->
:rules="rules"
validateMessage="提示信息"
>
<template #tg_validate>提示信息</template>
</tg-filter>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
// 编辑页面
import { ref } from 'vue'
import { addRuleEx } from "@coreTools";
const rules = ref([]);
onMounted(() => {
rules.value = addRuleEx("code");
})
// setting.js
{
"whereList":
[
{
"label": "cmpEnt_code",
"columnCode": "code",
"span": 8,
// 如下配置需要修改为 数字 1,必填项或者必选项的筛选项,不进行用户私有化配置展示和隐藏
"show": 1,
"queryMode": "l",
"type": "text"
}]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2.3. 查询条件设置默认值 search
const {
- search
+ search: _search
} = useSearch({
- queryField: SysOperLogSetting.whereList,
+ queryField: SysOperLogSetting.whereList.concat([{columnCode:'filterItem',queryMode:'='}]),
// 如果没有筛选条件 'filterItem|=,test|l'
+ queryField: 'filterItem|='
})
+ const search = (val={})=>{
+ form.value.filterItem = 1
+ _search(val)
+ }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3. 表格列表:TgTableList 组件
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
export-config | 是否显示配置项 “是否导出此项” | boolean | -- | true |
# 3.1. 列表重写列
<tg-table-list>
<!-- 插槽名为 selectList 中对应的 columnCode 的值 -->
<template #logisticsCode="{ scope }">
{{ scope.row.logisticsCode }}
</template>
</tg-table-list>
1
2
3
4
5
6
2
3
4
5
6
# 3.2. 列表页面显示 开关
<el-table-column :label="$t('tg_operation')" fixed="right">
<template #default="scope">
<el-switch
v-model="tableData[scope.$index].fileNumber"
active-value="1"
inactive-value="0"
/>
</template>
</el-table-column>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.3. 列表默认排序字段
const {
} = useSearch({
// 排序字段
sortField: 'iEMark',
})
1
2
3
4
5
2
3
4
5
# 3.4. 设置CheckBox 是否可以勾选
<!--
1. 去除 isCheckbox 选项
-->
<tg-table-list>
<!-- 2. 增加 selection 如下代码 -->
<template #tg_column>
<el-table-column type="selection" width="46" align="center" :selectable="selectable" />
</template>
</tg-table-list>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
/*
增加如下方法
return 返回值 true 可以被勾选 false 不可以被勾选
*/
const selectable = (row,index)=>{
return index > 3
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3.5. 表格:多选
<tg-table-list
isCheckbox
@selection-change="selectionChange"
>
</tg-table-list>
1
2
3
4
5
2
3
4
5
const {
selectionChange,
selectionList,
} = useSearch()
1
2
3
4
2
3
4
# 3.6. 新增 / 修改 / 预览 方法:设置初始值
<!-- List.vue 页面 -->
<!-- 注:data 数据值请根据实际业务设置数据值 -->
新增
<tg-button @click="edit()" icon="CirclePlus" :name="$t('tg_add')" />
改为如下:
@click="edit()" 修改为 @click="edit({type:'add',data: {test:1}})"
修改 / 预览
<tg-button type="primary" text @click="edit('edit',scope.row)">{{$t('tg_btn_edit')}}</tg-button>
改为如下
<!--
注: 第一个参数 修改
编辑 'edit' 修改为 {type:'edit',data: {100test:1}}
预览 'view' 修改为 {type:'view',data: {100test:1}}
-->
<tg-button type="primary" text @click="edit({type:'edit',data: {test:1}},scope.row)">{{$t('tg_btn_edit')}}</tg-button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Edit.vue 页面
/*
data {type:'add',data: {100test:1}}
*/
const handleShow = (data,row)=>{
show(data,row)
// form.value.100test = data.type
}
defineExpose({
// show
show: handleShow
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 4. 查阅
# 4.1单页面
<!-- List.vue 页面 -->
<!-- 查阅按钮 -->
<tg-button type="primary" text @click="edit('view',scope.row)">{{$t('tg_btn_view')}}</tg-button>
1
2
3
2
3
// Edit.vue 页面
<tg-dialog ref="dialogRef" :title="type ==='add' ? $t('tg_add'): $t('tg_edit')" @confirm="save" :footer="true">
修改内容
:title="type ==='add' ? $t('tg_add'): $t('tg_edit')" 改为 :title="$t(`tg_${type}`)"
footer="up" 改为 :footer=" type==='view'?false:'up'"
// 控件修改为禁用
<tg-input v-model="form.id" />
增加内容为: :disabled="type==='view'"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4.2 多表体页面
edit/EditTab.vue 页面
<!-- 组件增加 :type="type" -->
<template #bodyIndex>
<bodyIndex ref="bodyIndexRef" :type="type" />
</template>
1
2
3
4
2
3
4
const {
// 增加 type
type
} = useEdit()
1
2
3
4
2
3
4
表体页面
<!-- 查阅按钮 -->
<tg-button type="primary" text @click="edit('view',scope.row)">{{$t('tg_btn_view')}}</tg-button>
不可见按钮增加 v-if="!(type==='view')"
<tg-button type="primary" text @click="edit('edit',scope.row)" v-if="!(type==='view')">{{$t('tg_btn_edit')}}</tg-button>
1
2
3
4
2
3
4
const props = defineProps({
type: {
type: [String,Object],
default:()=>''
}
})
1
2
3
4
5
6
2
3
4
5
6
# 4.3 新增/编辑时,部分表体不显示
方案一(单表体 / 多表体):
import { watch } from 'vue'
let a = [{label:proxy.$t('SjmfBaseTable'),name:'first',disabled:false}]
let b = [{label:proxy.$t('SjmfBaseTableColumn'),name:'second',disabled:false}]
const {
type
} = useEdit({
tabsSource: a.concat(b),
})
watch(()=>type.value,(val)=>{
tabsSource.value = a.concat(val === 'view' ? b : [])
},{
immediate: true
})
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
方案二(单表体):
<edit ref="EditRef" @updateTabs="updateTabs" @update="search" v-if="type!=='view'" />
<!-- 如下增加 v-else -->
<tg-tabs :tabsSource="tabsSource" :activeTabs="activeTabs" @handleClick="changeTabs">
1
2
3
2
3
const {
type
} = useEdit({})
1
2
3
2
3
# 编辑页面
const {
} = useEdit({
onSuccess(data) {
$emit('updateTabs')
$emit('update')
},
closeDialog: true
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
描述 | 备注 |
---|---|
onSuccess(data) | onSuccess 保存按钮点击后成功的回调函数 |
data 保存按钮点击后成功接口返回的值 | |
closeDialog | 默认值 true true 关闭 false 不关闭 保存数据成功后,是否关闭弹框 |
# 1. 表单校验 addRuleEx
// 自定义校验
const validatePass = (rule, value, callback)=>{
if (value === '') {
callback(new Error('Please input the password again'))
} else {
callback()
}
}
addRuleEx('gNum,itemNo',{
// 验证数值
age: [{
// required: true,
type: 'number',
// message: '必须为数值',
// trigger: ['blur','change']
}],
// 邮箱
email: [{
type: 'email'
}],
// 长度
lengthMax: [{
max: 10
}],
lengthMin: [{
min: 1
}],
lengthBetween: [{
max: 10,
min: 1
}],
// 自定义校验
psd: [{
validator: validatePass,
trigger: 'blur'
}],
// 正则表达式
num:[{
required: true,
pattern: /[0-9]/ ,
message:'请输入数字',
trigger: 'blur'
}]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
只读 readonly true 是 false 否
禁用 disabled true 是 false 否
*/
<tg-input v-model="form.id" readonly />
<tg-input v-model="form.id" :readonly="true" />
<tg-input v-model="form.id" :readonly="false" />
<tg-input v-model="form.id" disabled />
<tg-input v-model="form.id" :disabled="true" />
<tg-input v-model="form.id" :disabled="false" />
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 1.1 校验规则如果部分字段为异步加载
const icCardNotNull = () => {
return new Promise((resolve,reject)=>{
resolve(true)
})
}
onMounted(async() => {
const _icCardNotNull = await icCardNotNull()
addRuleEx('bizType',{
iccode: [
{
required: _icCardNotNull,
message: "IC卡必填"
}
]
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2. 触发编辑页面再次查询对应数据
// EditHead.vue
const {
// 查询数据的方法
selectOneById
} = useEdit({
});
const refreshOne = ()=>{
selectOneById({
url: '/portManifestHead/selectOneById',
data: {
// 主键
baseId: form.value.baseId
}
}).then(({data,row})=>{
show(data,row)
})
}
defineExpose({
refreshOne
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- EditTab.vue -->
<tg-tabs :tabsSource="tabsSource" :activeTabs="activeTabs" @handleClick="changeTabs">
<template #first>
<edit ref="EditRef" @updateTabs="updateTabs" @update="search" />
</template>
<template #bodyIndex>
<bodyIndex ref="bodyIndexRef" :type="type" @updateHead="updateHead"/>
</template>
</tg-tabs>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
const EditRef = ref()
const updateHead = ()=>{
EditRef.value.refreshOne()
}
1
2
3
4
2
3
4
// 表体
const $emit = defineEmits(["updateHead"]);
$emit('updateHead')
1
2
3
2
3
# 3. 关闭页面触发页面查询
<!-- 增加 before-close -->
<tg-dialog :before-close="beforeClose"></tg-dialog>
1
2
2
// const $emit = defineEmits(['update'])
const beforeClose = (done)=>{
$emit('update')
done()
}
1
2
3
4
5
2
3
4
5
# 4. 表头表体绑定
# 4.1. 表头表体切换文件位置
```json
{表头}.vue # 生成主页面的index.vue 文件
│
└───edit # 编辑文件夹
│ │
│ └─── {表头}EditTab.vue # 新增的文件
│ └─── {表头}Edit.vue # 生成主页面的新增/编辑文件
│ └─── {表头}Setting.js # 生成表头列表的配置文件文件
└───item # 表体文件夹
│
└─── {表体}Edit.vue # 生成表体的新增/编辑文件
└─── {表体}List.vue # 生成表体的列表文件
└─── {表体}Setting.js # 生成表体列表的配置文件文件
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.2. 单表列表页面改成弹框表体页面
(1) EditTab.vue 文件
<template #bodyIndex>
<bodyIndex ref="bodyIndexRef"></bodyIndex>
</template>
<!--
如下问新增内容:
1. 插槽名称 为组件名称
2. ref 值为 组件名称Ref
-->
<template #gjgoodIndex>
<gjgoodIndex ref="gjgoodIndexRef"></gjgoodIndex>
</template>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
tabsSource: [
{ label: proxy.$t('hfBodyPre'), name: 'bodyIndex', disabled: false },
// 如下为新增内容 name 为组件名称
{ label: proxy.$t('hfGjgoodsPre'), name: 'gjgoodIndex', disabled: false }
]
1
2
3
4
5
2
3
4
5
(2) List 列表页面
// 如下为变更内容
const {
tabsSearch,
keyValue
} = useSearch({
// queryField: HfGjgoodsPreSetting.whereList,
queryField: HfGjgoodsPreSetting.whereList.concat([{
queryMode: '=',
columnCode: 'workNo'//从表关联键
}]),
cascade: {
field: "workNo", //从表关联键
headField: "workNo",//主表关联键
}
});
onMounted(() => {
// search();
// customConfig();
});
defineExpose({
tabsSearch,
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
上次更新: 2024/3/21 08:50:37