The middle and backend CRUD front-end element framework is extremely simple and does not compromise on flexibility.
Committed to overcoming the pain point of "high page duplication and difficulty in extracting public code while taking into account customization needs".
Mid- and back-end templates such as vue-pure-admin, vue-vben-admin, yudao-ui-admin-vue3, etc. are positioned as a complete set of mid- and back-end solutions, which are highly coupled with the UI framework and CSS framework.
View-level technology is competing with each other and changing with each passing day, but CRUD logic remains unchanged. This is the focus of Admate.
Admate focuses on the logic level, is lightweight, and has low intrusion. It can be used independently or can be used with any mid- and back-end templates.
npm i admate
Create a global adaptation layer
Example: src/utils/useAdmateAdapter.js
Import and use in the page
Example: src/views/Page.vue
Split the adaptation layer by module, each module has its own adaptation layer
for example:
Import the adaptation layer of the corresponding module into the page
const { list , listFilterRef , form , faFormDialogRef } = useAdmateAdapter ( {
// ...Admate 配置
} , {
// ...Admate 适配层配置
} )
Example: Interface level request configuration
useAdmate ( {
// Axios 或 Axios 实例
// 用于调用接口
axios ,
} )
useAdmate ( {
// Axios 配置
axiosConfig : {
// 各接口的 URL 前缀
urlPrefix : ` ${ import . meta . env . VITE_BASE_URL } /module` ,
// 列表相关接口
list : {
// 读取列表
read : { } ,
} ,
// 表单相关接口
form : {
// 新增
create : { } ,
// 读取
read : { } ,
// 编辑
update : { } ,
// 删除
delete : { } ,
// 切换状态
switch : { } ,
} ,
} ,
} )
// 示例: URL 前缀不统一
useAdmate ( {
axiosConfig : {
urlPrefix : 'module1' ,
list : {
read : {
// 如果某个接口的前缀不是 'somepage',可以在 URL 前面加斜线,即可忽略该前缀
url : '/module2/selectOne' ,
}
}
}
} )
// src/http/index.js
const axiosInstance = axios . create ( {
headers : {
xxx : 'xxx' ,
} ,
} )
const headers = {
xxx : 'xxx' ,
}
const { list , listFilterRef , form , faFormDialogRef } = useAdmateAdapter ( {
axiosConfig : {
urlPrefix ,
list : {
read : {
url : 'page' ,
headers ,
} ,
} ,
form : {
create : {
url : 'create' ,
headers ,
} ,
read : {
url : 'get' ,
headers ,
} ,
update : {
url : 'update' ,
headers ,
} ,
delete : {
url : 'delete' ,
headers ,
} ,
} ,
} ,
} )
const { list , listFilterRef , form , faFormDialogRef } = useAdmateAdapter ( {
axiosConfig : {
urlPrefix ,
form : {
create : {
url : 'create' ,
headers : {
xxx : 'xxx' ,
} ,
} ,
} ,
} ,
} )
If the interface address needs to be dynamically spliced
// 配置
const { list , form } = useAdmate ( {
axiosConfig : {
urlPrefix : ` ${ import . meta . env . VITE_BASE_URL } /module` ,
form : {
read : ( { id } ) => ( {
method : 'GET' ,
url : id ,
} ) ,
update : ( { id } ) => ( {
method : 'PUT' ,
url : id ,
} ) ,
delete : ( { id } ) => ( {
method : 'DELETE' ,
url : id ,
} ) ,
switch : ( { id } ) => ( {
method : 'PUT' ,
url : id ,
} ) ,
} ,
}
} )
// 使用
form . open ( { id : 1 } , 'config' )
form . read ( { id : 1 } , 'config' )
form . update ( { id : 1 } , 'config' )
form . delete ( { id : 1 } , 'config' )
form . switch ( { id : 1 } , 'config' )
Axios
' data uses application/json
as the MIME type by default. If you need to use multipart/form-data
:
Configure transformRequest
and headers['Content-Type']
for your Axios
Parameter 1 of list.read
, list.search
, list.reset
, form.open
, form.delete
, form.switch
and form.submit
all support the FormData type
<! -- 示例: 局部配置 -->
<script setup>
import useAdmateAdapter from '@/utils/useAdmateAdapter'
// 过滤 list.value.filter 并转换为 FormData 格式
FormData.from = (json) => {
const formData = new FormData()
for (const k in json) {
if (![Number.NaN, null, undefined].includes(json[k])) {
formData.append(k, json[k])
}
}
return formData
}
useAdmateAdapter({
list: {
proxy: {
read(readList, trigger) {
readList(FormData.from(list.value.filter))
},
}
}
})
const FormData = window.FormData
</script>
<template>
<el-table>
<el-table-column label="操作">
<template #default="{ row: { id } }">
<el-button @click="form.read(FormData.from({ id }))">
查看
</el-button>
<el-button @click="form.update(FormData.from({ id }))">
编辑
</el-button>
<el-button @click="form.delete(FormData.from({ id }))">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog>
<template #footer>
<el-button @click="() => form.submit(FormData.from(form.data))">
确 定
</el-button>
</template>
</el-dialog>
</template>
list.filter
useAdmate ( {
list : {
// 页码的参数名称或路径,必填
// 支持属性名,如 `'pageNo'`
// 支持属性路径,如 `'page.pageNo'`
pageNumberAt : undefined ,
// 可以在这里提供筛选参数的默认值
filter : {
'pageNumberAt 生成的页码参数名称' : 1
} ,
} ,
} )
useAdmate ( {
list : {
watchFilter : false ,
}
} )
useAdmate ( {
list : {
watchFilter : true , // 默认值
// 防抖间隔,单位毫秒
// 如果筛选参数不含 input 类型,可以设置为 0,即不防抖
// 翻页不会触发防抖
// watchFilter 开启时有效
debounce : 300 , // 默认值
}
} )
list.data
useAdmate ( {
list : {
// 列表数据
data : [ ] ,
// 指定接口返回值中列表数据的位置
// 支持属性名,如 `'data'`
// 支持属性路径,如 `'data[0].records'`
// 支持 symbol 类型的属性名
// 支持 Function,如 `response => response.data`
dataAt : undefined ,
// 指定接口返回值中记录总数的位置
// 支持属性名,如 `'total'`
// 支持属性路径,如 `'data[0].total'`
// 支持 symbol 类型的属性名
// 支持 Function,如 `response => response.total`
totalAt : undefined ,
}
} )
Read the list, which will be called after entering the page for the first time, changing the list filtering parameters, and adding, deleting, checking, or modifying a single record.
const { list } = useAdmate ( )
/**
* PS: 以下为原始函数签名,如果你配置了 list.proxy.read ,则以 list.proxy.read 为准
*
* @param {any} [payload = list.filter]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* @returns {Promise<any>} 接口返回值
*/
list . read ( ) // 手动读取
Execute list.read
after resetting the page number, which is used to retrieve the list after the filter conditions are changed.
const { list } = useAdmate ( )
/**
* PS: 以下为原始函数签名,如果你配置了 list.proxy.read ,则以 list.proxy.read 为准
*
* @param {any} [payload = list.filter]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* @returns {Promise<any>} 接口返回值
*/
list . search ( ) // 手动检索
Execute list.read
after resetting filter conditions
const { list } = useAdmate ( )
/**
* PS: 以下为原始函数签名,如果你配置了 list.proxy.reset ,则以 list.proxy.reset 为准
*
* @param {any} [payload = list.filter]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* @returns {Promise<any>} 接口返回值
*/
list . reset ( ) // 手动重置
You can use list.proxy.read
to proxy list.read
to perform some operations before and after list.read
, or to change the behavior of list.read
useAdmate ( {
list : {
proxy : {
/**
* @param {Function} readList 被代理的原始 readList
* @param {string} trigger 调用动机 可能的值:
* 'immediate': 初始化立即查询列表
* 'pageNumberChange': 页码改变触发查询列表
* 'filterChange': 筛选项(含分页大小)改变触发查询列表
* 'create': 表单新增触发查询列表
* 'update': 表单编辑触发查询列表
* 'delete': 表单删除触发查询列表
* 'switch': 表单状态变更触发查询列表
*/
read ( readList , trigger ) { } ,
} ,
} ,
} )
// 示例: 读取列表之前,校验参数
useAdmate ( {
list : {
proxy : {
read ( readList , trigger ) {
if ( trigger === 'filterChange' ) {
listFilterRef . value . validate ( ) . then ( ( ) => {
readList ( )
} )
}
else {
readList ( )
}
} ,
}
}
} )
// 示例: 单条记录操作成功后,弹出提示
useAdmate ( {
list : {
proxy : {
read ( readList , trigger ) {
readList ( )
if ( [ 'create' , 'upadte' , 'delete' , 'switch' ] . includes ( trigger ) ) {
currentInstance . value . $message . success ( '操作成功' )
}
} ,
}
}
} )
// 示例: 读取列表后,修改列表数据
const { list } = useAdmate ( {
list : {
proxy : {
read ( readList , trigger ) {
readList ( ) . then ( ( response ) => {
// response 为 axiosConfig.list.read 的接口返回值
list . data = response . data ?. filter ( v => ! v . disabled )
} )
} ,
}
}
} )
You can use list.proxy.reset
to proxy list.reset
to perform some operations before and after list.reset
, or to change the behavior of list.reset
useAdmate ( {
list : {
proxy : {
/**
* @param {Function} resetList 被代理的原始 resetList
*/
reset ( resetList ) { } ,
} ,
} ,
} )
// 示例: 使用 UI 组件库的表单重置函数来重置筛选条件
useAdmate ( {
list : {
proxy : {
reset ( resetList ) {
listFilterElFormRef . value . resetFields ( )
// 如果分页组件不归属于表单,则表单重置时页码不会被重置,需调用 list.search
if ( ! list . watchFilter ) {
list . search ( )
}
} ,
}
}
} )
list.loading
The value is true
when axiosConfig.list.read
is called, otherwise it is false
<! -- 示例 -->
<script setup>
import useAdmate from 'admate'
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const { list } = useAdmate()
function handleTable() {
list.value.loading = true
proxy.$POST('').finally(() => {
list.value.loading = false
})
}
</script>
<template>
<el-table v-loading="list.loading" />
</template>
The form defaults to dialog/drawer style, but it also supports independent page style.
contrast
form.show: boolean
Tip
When the form is closed, the form data is automatically restored to its initial state (not cleared directly)
form.data
useAdmate ( {
form : {
// 可以在这里提供表单数据的默认值
data : { } ,
// 在查看、编辑表单时,可能需要调用接口(axiosConfig.form.read)回显表单的数据
// dataAt 用于指定接口返回值中表单数据的位置
// 支持属性名,如 `'detail'`
// 支持属性路径,如 `'data[0].detail'`
// 支持 symbol 类型的属性名
// 支持 Function,如 `response => response.detail`
dataAt : undefined ,
// 接口(axiosConfig.form.read)返回值与 form.data 合并的方式
mergeData : 'deep' ,
} ,
} )
mergeData:
'deep'
: Deep merge (default)'shallow'
: Shallow merge(newFormData: any) => any
: Customized merging methodfalse
: do not merge, replace directlyWhy is deep merge the default?
In Vue 2, template does not support ?.
syntax. To check for null in template, the code will be very redundant to write. The usual method is to declare null objects in data.
For example, provide a default value for form.data:
< script setup>
import useAdmate from ' admate '
const { form } = useAdmate ({
form : {
data : {
a : {
b : {}
}
}
}
})
</ script >
< template >
{{ form.data.a.b.c }}
</ template >
If the return value of axiosConfig.form.read is: { a: {} }
If shallowly merged with the default value, you will get: { a: {} }
- the object b in the default value is lost, causing a null pointer exception.
If you deep merge with the default value you get: { a: { b: {} } }
- the code works fine.
// 示例: 自定义合并方式
import { mergeWith } from 'lodash'
function defaultFormData ( ) {
return {
a : {
b : { }
}
}
}
const { form } = useAdmate ( {
form : {
data : defaultFormData ( ) ,
// 接口返回值中嵌套的对象可能为 null,会覆盖默认值中的空对象
mergeData (
// 接口返回值在通过 form.dataAt 计算过后的值
newFormData
) {
// Vue 3 中不需要赋值,mergeWith 的改动是响应式的
form . data = mergeWith (
defaultFormData ( ) ,
newFormData ,
( oldObj , newObj ) => [ undefined , null ] . includes ( newObj ) ? oldObj : undefined
)
} ,
} ,
} )
form.status: 'create' | 'read' | 'update'
form.title: string
// 示例: 根据表态形态生成对应的标题
import { computed } from 'vue'
const { form } = useAdmate ( {
form : {
title : computed ( ( ) => ( { create : '新增' , read : '查看' , update : '编辑' } [ form . status ] ) ) ,
} ,
} )
Open the form and axiosConfig.form.create
will be called when submitting.
const { form } = useAdmate ( )
form . create ( )
// 等价于:将表单形态设置为“新增”,然后打开表单
form . status = 'create'
form . open ( )
The initial data of the form is not blank, but copies an existing record.
const { form } = useAdmate ( )
form . create ( row )
// 等价于:将表单形态设置为“新增”,然后打开表单并传参
form . status = 'create'
form . open ( row )
Open the form and call axiosConfig.form.read
to echo the form content
const { form } = useAdmate ( )
form . read ( )
// 等价于:将表单形态设置为“查看”,然后打开表单
form . status = 'read'
/**
* PS: 以下为原始 openForm 的函数签名,如果你配置了 form.proxy.open ,则以 form.proxy.open 为准
*
* @param {any} [payload] 如果 payload 不为空,则会调用 axiosConfig.form.read
* @param {'data'|'params'|'config'|'cache'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* 'cache': 将 payload 直接用作表单数据(不调用读取单条记录的接口)
* @returns {Promise<any>} axiosConfig.form.read 的返回值
*/
form . open ( )
Open the form and call axiosConfig.form.read
to echo the form content. When submitting, axiosConfig.form.update
will be called.
const { form } = useAdmate ( )
form . update ( )
// 等价于:将表单形态设置为“编辑”,然后打开表单
form . status = 'update'
/**
* PS: 以下为原始 form.open 的函数签名,如果你配置了 form.proxy.open ,则以 form.proxy.open 为准
*
* @param {any} [payload] 如果 payload 不为空,则会调用 axiosConfig.form.read
* @param {'data'|'params'|'config'|'cache'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* 'cache': 将 payload 直接用作表单数据(不调用读取单条记录的接口)
* @returns {Promise<any>} axiosConfig.form.read 的返回值
*/
form . open ( )
const { form } = useAdmate ( )
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* @returns {Promise<any>} axiosConfig.form.delete 的返回值
*/
form . delete ( )
Tip
When deleting the last record not on the homepage, automatically switch to the previous page
There are three ways to change status:
< script setup>
import useAdmate from ' admate '
const { form } = useAdmate ()
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* @returns {Promise<any>} axiosConfig.form.switch 的返回值
*/
form . switch ()
</ script >
< template >
< el-table >
< el-table-column
label = "操作"
align = " center "
>
< template # default = " { row: { id , status } } " >
< el-switch @change = " form.switch({ id, status: status ^ 1 }) " />
</ template >
</ el-table-column >
</ el-table >
</ template >
< script setup>
import useAdmate from ' admate '
const { form } = useAdmate ({
axiosConfig : {
form : {
switch : ({ id, status }) => ({
method : ' PUT ' ,
url : ` ${ status === 1 ? ' enable ' : ` disable ` } / ${ id } ` ,
}),
}
},
})
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* @returns {Promise<any>} axiosConfig.form.switch 的返回值
*/
form . switch ()
</ script >
< template >
< el-table >
< el-table-column
label = "操作"
align = " center "
>
< template # default = " { row: { id , status } } " >
< el-switch @change = " form.switch({ id, status: status ^ 1 }, 'config') " />
</ template >
</ el-table-column >
</ el-table >
</ template >
< script setup>
import useAdmate from ' admate '
const { form } = useAdmate ({
axiosConfig : {
form : {
update : {
// ...
},
switch : {
// 按编辑接口进行配置
},
}
},
})
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* 'data': 将 payload 用作请求配置的 `data` 参数(请求方式为 POST / PATCH / PUT / DELETE 时默 认)
* 'params': 将 payload 用作请求配置的 `params` 参数(请求方式为 GET / HEAD 时默认)
* 'config': 将 payload 仅用于构建请求配置(详见 RESTful 章节)
* @returns {Promise<any>} axiosConfig.form.switch 的返回值
*/
form . switch ()
</ script >
< template >
< el-table >
< el-table-column
label = "操作"
align = " center "
>
< template # default = " { row } " >
< el-switch @change = " form.switch({ ...row, status: row.status ^ 1 }) " />
</ template >
</ el-table-column >
</ el-table >
</ template >
Open the form, the function signature depends on the situation:
You can use form.proxy.open
to proxy form.open
to perform some operations before and after form.open
, or to change the behavior of form.open
useAdmate ( {
form : {
proxy : {
/**
* @param {Function} openForm 被代理的原始 openForm
* @returns {Promise<object> | object | void} object 为打开表单后 form 的终态
*/
open ( openForm ) { } ,
}
}
} )
// 示例: 回显表单后,修改表单数据
const { form } = useAdmate ( {
form : {
proxy : {
open ( openForm ) {
// 新增时 openForm 没有返回值
return new Promise ( ( resolve , reject ) => {
openForm ( ) ?. then ( ( response ) => {
// response 为 axiosConfig.r 的接口返回值
// 修改表单数据
form . data . status = 1
resolve ( )
} ) . catch ( ( e ) => {
reject ( e )
} )
} )
} ,
}
}
} )
// 示例: 回显表单后,清除校验
useAdmate ( {
form : {
proxy : {
open ( openForm ) {
return new Promise ( ( resolve , reject ) => {
openForm ( ) ?. finally ( ( ) => {
formRef . value . clearValidate ( )
} ) . then ( ( ) => {
resolve ( )
} ) . catch ( ( e ) => {
reject ( e )
} )
} )
} ,
}
}
} )
// 示例: 回显表单后,自定义表单的开闭和读取状态
useAdmate ( {
form : {
proxy : {
open ( openForm ) {
return new Promise ( ( resolve , reject ) => {
// 可以在 finally 中 resolve
openForm ( ) . then ( ( ) => {
// 回显成功后,默认停止加载
resolve ( {
loading : false ,
} )
} ) . catch ( ( ) => {
// 回显失败后,默认关闭表单并停止加载
resolve ( {
show : false ,
loading : false ,
} )
} )
} )
}
}
}
} )
// 也可以返回一个对象(如果没有异步操作)
useAdmate ( {
form : {
proxy : {
open ( openForm ) {
return {
loading : false
}
}
}
}
} )
form.loading
The value is true
when axiosConfig.form.read
is called, otherwise it is false
This value cannot be used as a sign of the end of the form echo, because axiosConfig.r is not called when reusing list data.
<! -- 示例 -->
<script setup>
import useAdmate from 'admate'
const { form } = useAdmate()
</script>
<template>
<el-dialog>
<el-form v-loading="form.loading" />
</el-dialog>
</template>
Submit the form, call axiosConfig.form.create
when adding, and call axiosConfig.form.update
when editing.
const { form } = useAdmate ( )
/**
* PS: 以下为原始 form.submit 的函数签名,如果你配置了 form.proxy.submit ,则以 form.proxy.submit 为准
*
* @param {any} [payload = form.data]
* @param {'data'|'params'|'config'} [payloadAs] 指定 payload 的用途
* @returns {Promise<any>} 接口返回值
*/
form . submit ( )
You can use form.proxy.submit
to proxy form.submit
to perform some operations before and after form.submit
, or to change the behavior of form.submit
useAdmate ( {
form : {
proxy : {
/**
* @param {Function} submitForm 被代理的原始 submitForm
* @returns {Promise<object> | object | void} object 为提交表单后 form 的终态
*/
submit ( submitForm ) { }
}
}
} )
// 示例: 指定提交参数
form . submit ( {
... form . data ,
status : 1 ,
} )
// form.submit 被代理时
useAdmate ( {
form : {
proxy : {
submit ( submitForm ) {
return new Promise ( ( resolve , reject ) => {
submitForm ( {
... form . data ,
status : 1 ,
} ) . then ( ( ) => {
resolve ( )
} ) . catch ( ( e ) => {
reject ( e )
} )
} )
}
}
}
} )
// 示例: 提交前校验表单
useAdmate ( {
form : {
proxy : {
submit ( submitForm ) {
return new Promise ( ( resolve , reject ) => {
formRef . value . validate ( ) . then ( ( ) => {
submitForm ( ) . then ( ( ) => {
resolve ( )
} ) . catch ( ( e ) => {
reject ( e )
} )
} )
} )
}
}
}
} )
// 示例: 提交表单后,自定义表单的开闭和提交状态
// 返回一个 promise
useAdmate ( {
form : {
proxy : {
submit ( submitForm ) {
return new Promise ( ( resolve , reject ) => {
formRef . value . validate ( ) . then ( ( ) => {
submitForm ( ) . then ( ( ) => {
// 提交成功后,默认关闭表单,并停止加载
resolve ( {
show : false ,
submitting : false ,
} )
} ) . catch ( ( ) => {
// 提交失败后,默认仅停止加载
resolve ( {
show : true ,
submitting : false ,
} )
} )
} )
} )
}
}
}
} )
// 也可以返回一个对象(如果没有异步操作)
useAdmate ( {
form : {
proxy : {
submit ( submitForm ) {
return {
show : false ,
submitting : false ,
}
}
}
}
} )
form.submitting
The value is true
when axiosConfig.form.create
or axiosConfig.form.update
is called, otherwise it is false
<! -- 示例 -->
<script setup>
import useAdmate from 'admate'
const { form } = useAdmate()
</script>
<template>
<el-dialog>
<template #footer>
<el-button :loading="form.submitting">
确 定
</el-button>
</template>
</el-dialog>
</template>
useAdmateAdapter ( { } , {
onListRead ( res , trigger ) {
// res 为接口返回值,trigger 为调用动机
// 可访问 this(组件实例)
}
} )
watch ( ( ) => form . value . show , ( n ) => {
if ( n ) {
// 打开表单
}
} )
// 示例: 适配层提供 onFormOpened
useAdmateAdapter ( { } , {
onFormOpened ( res ) {
// res 为接口返回值(新增时为空)
// 可访问 this(组件实例)
}
} )
// 示例: 适配层提供 onFormRead
useAdmateAdapter ( { } , {
onFormRead ( res ) {
// res 为接口返回值
// 可访问 this(组件实例)
}
} )
useAdmateAdapter ( { } , {
onFormSubmit ( form ) {
// 可访问 this(组件实例)
}
} )
useAdmateAdapter ( { } , {
onFormSubmitted ( res ) {
// res 为接口返回值
// 可访问 this(组件实例)
}
} )
watch ( ( ) => form . value . show , ( n ) => {
if ( ! n ) {
// 关闭表单
}
} )
Extract the form into subcomponents
Example
When operating a single record, jump to a dedicated form page and return after the operation is completed.
Example
The form is open by default and cannot be closed. It is usually used in scenarios where there is only one piece of data in the list, so the list is omitted.
Example
The dialog box of the current page also uses Admate
Example
Please refer to the release notes for detailed changes in each version.