
Security News
vlt Launches "reproduce": A New Tool Challenging the Limits of Package Provenance
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Admate
的目标是以快速简洁的方式开发管理后台页面,
并在此基础上确保灵活可配,杜绝过度封装。
Vue2
& Vue3
Vue
和 axios
,便可以使用周全的收尾工作,没有“后顾之忧”:
https://www.npmjs.com/package/admate/v/0.5.4
将链接末尾替换为你想要查看的版本号即可
npm add admate vue@3 axios
npm add admate vue@2 axios @vue/composition-api
使用代码生成器生成页面模板
::: warning
目前仅支持 element-ui
:::
安装Chrome/Edge插件 YApi2Code
,或使用离线版:
:one: 下载离线包后解压
:two: 打开浏览器 扩展程序
,并开启 开发者模式
:three: 点击 加载已解压的扩展程序
,选择解压后的文件夹
:one: 访问YApi,选中相应模块的 查询列表
接口
:two: 点击浏览器右上角运行插件
:three: 点击 生成代码
,代码将被复制至剪贴板
:four: 创建页面文件 xxx.vue
,粘贴代码
Vuetify@3 仍处于Alpha阶段
Quasar@2尚不支持 Vite
,进度追踪
useAdmate({
// axios或axios实例
// 用于调用接口
axios,
})
useAdmate({
axiosConfig: {
// 查询列表
getList: {
method: 'GET',
},
// 新增一条记录(submitForm在新增时调用)
c: {
method: 'POST',
},
// 查询一条记录(openForm在查看、编辑时调用)
r: {
method: 'GET',
},
// 编辑一条记录(submitForm在编辑时调用)
u: {
method: 'PUT',
},
// 删除一条记录
d: {
method: 'DELETE',
},
// 启用一条记录
enable: {
method: 'PUT',
},
// 禁用一条记录
disable: {
method: 'PUT',
},
// 变更一条记录的状态
updateStatus: {
method: 'PUT',
},
},
})
// 示例:根据传参动态生成配置,常用于RESTful中
// 动态生成配置时,payloadAs将会失效
useAdmate({
axiosConfig: {
// 查询列表
getList: payload => ({
method: 'GET',
}),
// 新增一条记录(submitForm在新增时调用)
c: payload => ({
method: 'POST',
}),
// 查询一条记录(openForm在查看、编辑时调用)
r: payload => ({
method: 'GET',
}),
// 编辑一条记录(submitForm在编辑时调用)
u: payload => ({
method: 'PUT',
}),
// 删除一条记录
d: payload => ({
method: 'DELETE',
}),
// 启用一条记录
enable: payload => ({
method: 'PUT',
}),
// 禁用一条记录
disable: payload => ({
method: 'PUT',
}),
// 变更一条记录的状态
updateStatus: payload => ({
method: 'PUT',
}),
},
})
useAdmate({
// axiosConfig中各个接口的url前缀
urlPrefix: '',
})
// 示例:URL前缀不统一
useAdmate({
urlPrefix: 'somepage',
axiosConfig: {
r: {
// 如果某个接口的前缀不是'somepage',可以在URL前面加斜线,即可忽略该前缀
url: '/anotherpage/selectOne',
},
}
})
如果接口地址需要进行动态拼接
<!-- 示例 -->
// 配置
const { r, u } = useAdmate({
axiosConfig: {
r: config => ({
url: 'module/' + config.id
}),
}
})
// 使用
r(form, 'config')
u(form, 'config')
axios的data默认以 application/json
作为MIME type,如果你需要使用 multipart/form-data
:
给你的axios配置 transformRequest
、headers['Content-Type']
getList
、r
、u
、d
、updateStatus
、enable
、disable
、submitForm
的参数1均支持FormData类型
<!-- 示例:局部配置 -->
<template>
<el-table>
<el-table-column label="操作">
<template #default="{ row: { id } }">
<el-button @click="r(FormData.from({ id }))">查看</el-button>
<el-button @click="u(FormData.from({ id }))">编辑</el-button>
<el-button @click="d(FormData.from({ id }))">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog>
<template #footer>
<el-button @click="submitForm(FormData.from( form.data ))">
确 定
</el-button>
</template>
</el-dialog>
</template>
<script>
import useAdmate from 'admate'
import { jsonToFormData, pickDeepBy } from 'kayran'
export default {
setup: () => {
// 过滤参数并转换为FormData
// 此处示例为将过滤方法绑定到window.FormData,方便其他地方使用
FormData.from = data => jsonToFormData(pickDeepBy(data, (v, k) => ![NaN, null, undefined].includes(v)))
// 直接转换为FormData
//FormData.from = jsonToFormData
return {
...useAdmate({
getListProxy (getList, trigger) {
getList(FormData.from(list.filter))
},
}),
FormData
}
}
}
</script>
list.filter
useAdmate({
list: {
// 可以在这里提供筛选参数的默认值
filter: {
[list.pageNumberKey]: 1,
},
// 必填
// 页码的参数名
pageNumberKey: undefined,
},
})
::: danger
如果你的参数筛选项中包含 el-checkbox
组件,则必须在 data 中声明其初始值,否则将导致无法正确重置(element-ui 的 bug)
:::
<!-- 示例 -->
<template>
<el-form ref="listFilterRef" :model="list.filter" inline>
<el-form-item prop="effect">
<el-checkbox
v-model="list.filter.effect"
label="生效"
border
/>
</el-form-item>
<el-button @click="reset">重置</el-button>
</el-form>
</template>
<script>
import useAdmate from 'admate'
export default {
setup: () => useAdmate({
urlPrefix: '',
list: {
filter: {
effect: null
}
}
}),
}
</script>
查询
按钮触发
useAdmate({
list: {
watchFilter: false,
}
})
useAdmate({
list: {
watchFilter: true, // 默认值
// 节流间隔,单位毫秒
// 如果筛选参数不含input类型,可以设置为0,即不节流
// 翻页不会触发节流
// watchFilter开启时有效
throttleInterval: 500, // 默认值
}
})
list.data
useAdmate({
list: {
// 列表数据
data: [],
// 指定接口返回值中列表数据所在的位置
// 支持属性名如'data',属性路径如'data.records'
// 还支持function,如response => response.data
dataAt: undefined,
// 指定接口返回值中记录总数所在的位置
totalAt: undefined,
}
})
list.loading
axiosConfig.getList
被调用时值为 true
,否则为 false
<!-- 示例 -->
<template>
<el-table v-loading="list.loading"/>
</template>
<script>
import useAdmate from 'admate'
export default {
setup: () => {
const { list } = useAdmate()
return { list }
},
methods: {
handleTable () {
this.list.loading = true
this.$POST('').finally(() => {
this.list.loading = false
})
}
}
}
</script>
getList
:获取列表,在首次进入页面、列表筛选参数改变、单条记录增删查改后会被调用
const {
/**
* PS:以下为原始getList的函数签名,如果你配置了getListProxy,则以getListProxy为准
*
* @param {any} [payload = list.filter]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} 接口返回值
*/
getList
} = useAdmate()
getList() // 手动查询
getListProxy
:你可以使用 getListProxy
来代理 getList
,以便在getList前后做一些操作,或改变getList的行为
useAdmate({
/**
* @param {Function} getList 被代理的原始getList
* @param {string} trigger 调用动机 可能的值:'init' 'pageNumberChange' 'filterChange' 'c' 'r' 'u' 'd' 'updateStatus' 'enable' 'disable'
*/
getListProxy (getList, trigger) {},
})
// 示例:获取列表之前,校验参数
useAdmate({
getListProxy (getList, trigger) {
if (trigger === 'filterChange') {
listFilterRef.value.validate().then(() => {
getList()
})
} else {
getList()
}
},
})
// 示例:单条记录操作成功后,弹出提示
useAdmate({
getListProxy (getList, trigger) {
getList()
if (['c', 'u', 'd', 'updateStatus', 'enable', 'disable'].includes(caller)) {
currentInstance.value.$message.success('操作成功')
}
},
})
// 示例:获取列表后,修改列表数据
const { list } = useAdmate({
getListProxy (getList, trigger) {
getList().then(response => {
// response为axiosConfig.getList的接口返回值
list.data = response.data?.filter(v => !v.disabled)
})
},
})
打开表单,提交时会调用 axiosConfig.c
const { form, openForm } = useAdmate()
// 将表单形态设置为“新增”,然后打开表单
form.status = 'c'
openForm()
打开表单,并调用 axiosConfig.r
回显表单内容
const { form, openForm } = useAdmate()
// 将表单形态设置为“查看”,然后打开表单
form.status = 'r'
/**
* PS:以下为原始openForm的函数签名,如果你配置了openFormProxy,则以openFormProxy为准
*
* @param {any} [payload]
* @param {'data'|'params'|'config'|'cache'} [payloadAs] 指定payload的用途
* @param {'shallow'|'deep'|false} [mergeData = 'shallow'] 接口返回值与form.data合并的方式
* @returns {Promise<any>} axiosConfig.r的返回值
*/
openForm()
payloadAs:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)'cache'
:将payload直接用作表单数据(不调用查询单条记录的接口)mergeData:
shallow
: 浅合并(默认)deep
: 深合并false
: 不合并,直接替换打开表单,并调用 axiosConfig.r
回显表单内容,提交时会调用 axiosConfig.u
const { form, openForm } = useAdmate()
// 将表单形态设置为“编辑”,然后打开表单
form.status = 'u'
/**
* PS:以下为原始openForm的函数签名,如果你配置了openFormProxy,则以openFormProxy为准
*
* @param {any} [payload]
* @param {'data'|'params'|'config'|'cache'} [payloadAs] 指定payload的用途
* @param {'shallow'|'deep'|false} [mergeData = 'shallow'] 接口返回值与form.data合并的方式
* @returns {Promise<any>} axiosConfig.r的返回值
*/
openForm()
payloadAs:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)'cache'
:将payload直接用作表单数据(不调用查询单条记录的接口)mergeData:
shallow
: 浅合并(默认)deep
: 深合并false
: 不合并,直接替换const {
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} axiosConfig.d的返回值
*/
d
} = useAdmate()
参数2的可选值:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)const {
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} axiosConfig.enable的返回值
*/
enable
} = useAdmate()
参数2的可选值:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)const {
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} axiosConfig.disable的返回值
*/
disable
} = useAdmate()
参数2的可选值:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)const {
/**
* @param {any} [payload]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} axiosConfig.updateStatus的返回值
*/
updateStatus
} = useAdmate()
参数2的可选值:
'data'
:将payload用作请求配置的 data
参数(请求方式为POST/PATCH/PUT/DELETE时默认)'params'
:将payload用作请求配置的 params
参数(请求方式为GET/HEAD时默认)'config'
:将payload仅用于构建请求配置(详见RESTful)状态变更的两种方式:
updateStatus
<el-table-column label="操作" align="center">
<template slot-scope="{row:{id,status}}">
<el-switch
@change="updateStatus({id,status:status^1})"
/>
</template>
</el-table-column>
enable
和 disable
<el-table-column label="操作" align="center">
<template slot-scope="{row:{id,status}}">
<el-switch
@change="[enable,disable][status]({id})"
/>
</template>
</el-table-column>
form.data
useAdmate({
form: {
// 可以在这里提供表单数据的默认值,新增时会有用
data: {},
// 在查看、编辑表单时,可能需要调用接口回显表单的数据
// dataAt用于指定接口返回值中表单数据所在的位置
// 支持属性名如'data',属性路径如'data.records'
// 还支持function,如response => response.data
dataAt: undefined,
},
})
form.status
可能的值:
'c'
新增'r'
查看'u'
编辑''
关闭form.loading
axiosConfig.r
被调用时值为 true
,否则为 false
::: warning
不能将该值当作表单回显结束的标志,因为复用列表数据时不会调用axiosConfig.r
:::
<!-- 示例 -->
<template>
<el-dialog>
<el-form v-loading="form.loading"/>
</el-dialog>
</template>
<script>
import useAdmate from 'admate'
export default {
setup: () => {
const { form } = useAdmate()
return { form }
}
}
</script>
form.submitting
axiosConfig.c
或 axiosConfig.u
被调用时值为 true
,否则为 false
<!-- 示例 -->
<template>
<el-dialog>
<template #footer>
<el-button :loading="form.submitting">
确 定
</el-button>
</template>
</el-dialog>
</template>
<script>
import useAdmate from 'admate'
export default {
setup: () => {
const { form } = useAdmate()
return { form }
}
}
</script>
openForm
:打开表单,函数签名要分情况:
openFormProxy
:你可以使用 openFormProxy
来代理 openForm
,以便在openForm前后做一些操作,或改变openForm的行为
useAdmate({
/**
* @param {Function} openForm 被代理的原始openForm
* @returns {Promise<object> | object | void} object为打开表单后form的终态
*/
openFormProxy (openForm) {},
})
// 示例:回显表单后,修改表单数据
const { form } = useAdmate({
openFormProxy (openForm) {
// 新增时openForm没有返回值
return openForm()?.then(response => {
// response为axiosConfig.r的接口返回值
// 修改表单数据
form.data.status = 1
})
},
})
// 示例:回显表单后,清除校验
useAdmate({
openFormProxy (openForm) {
return openForm()?.finally(() => {
formRef.value.clearValidate()
})
},
})
// 示例:回显表单后,自定义表单的开闭和读取状态
// 返回一个promise
useAdmate({
openFormProxy (openForm) {
return openForm().then(() => {
// 回显成功后,默认停止加载
return {
loading: false,
}
}).catch(() => {
// 回显失败后,默认关闭表单并停止加载
return {
show: false,
loading: false,
}
}).finally(() => {
// 注意:在finally中return是无效的,无法获取到finally中的返回
})
}
})
// 也可以再包装一层promise再返回
useAdmate({
openFormProxy (openForm) {
return new Promise((resolve, reject) => {
// 可以在finally中resolve
openForm().then(() => {
// 回显成功后,默认停止加载
resolve({
loading: false,
})
}).catch(() => {
// 回显失败后,默认关闭表单并停止加载
reject({
show: false,
loading: false,
})
})
})
}
})
// 也可以返回一个对象(如果没有异步操作)
useAdmate({
openFormProxy (openForm) {
return {
loading: false
}
}
})
submitForm
:提交表单,新增时调用 axiosConfig.c
,编辑时调用 axiosConfig.u
const {
/**
* PS:以下为原始submitForm的函数签名,如果你配置了submitFormProxy,则以submitFormProxy为准
*
* @param {any} [payload = form.data]
* @param {'data'|'params'|'config'} [payloadAs] 指定payload的用途
* @returns {Promise<any>} 接口返回值
*/
submitForm
} = useAdmate()
submitFormProxy
:你可以使用 submitFormProxy
来代理 submitForm
,以便在submitForm前后做一些操作,或改变submitForm的行为
useAdmate({
/**
* @param {Function} submitForm 被代理的原始submitForm
* @returns {Promise<object> | object | void} object为提交表单后form的终态
*/
submitFormProxy (submitForm) {}
})
// 示例:指定提交参数
submitForm({
...form.data,
status: 1,
})
// submitForm被代理时
useAdmate({
submitFormProxy (submitForm) {
return submitForm({
...form.data,
status: 1,
})
}
})
// 示例:提交前校验表单
useAdmate({
submitFormProxy (submitForm) {
return new Promise((resolve, reject) => {
formRef.value.validate().then(() => {
submitForm().then(() => {
resolve()
}).catch(() => {
reject()
})
})
})
}
})
// 示例:提交表单后,自定义表单的开闭和提交状态
// 返回一个promise
useAdmate({
submitFormProxy (submitForm) {
return new Promise((resolve, reject) => {
formRef.value.validate().then(() => {
submitForm().then(() => {
// 提交成功后,默认关闭表单,并停止加载
resolve({
show: false,
submitting: false,
})
}).catch(() => {
// 提交失败后,默认仅停止加载
reject({
show: true,
submitting: false,
})
})
})
})
}
})
// 也可以返回一个对象(如果没有异步操作)
useAdmate({
submitFormProxy (submitForm) {
return {
show: false,
submitting: false,
}
}
})
将表单抽离为子组件
操作单条记录时,跳转到专用的表单页面,操作完毕后返回
表单默认打开,且无法关闭,通常用于列表中只有一条数据,故列表被省略的场景
嵌套其它也使用Admate的页面
FAQs
Admin CRUD frontend meta framework for Vue 2/3, extremely concise without losing flexibility.
The npm package admate receives a total of 15 weekly downloads. As such, admate popularity was classified as not popular.
We found that admate demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.