!!! 该库已迁移至 Cruda,本仓库不再维护 !!!
基于 Vue 的通用 CRUD 视图模型库;提供对常用 CRUD 场景的视图与操作托管,通过不同适配器可以实现对主流 UI 库的自动适配。
在所有存在列表展示的业务系统中,无论使用何种 UI 库都存在大量 CRUD 场景。CRUD-vue 为使用者抽象通用行为并内建数据模型统一调度相关操作。通过标准 REST 接口对接服务端,并通过适配器对接不同 UI 库,实现低成本、配置化的界面托管。
<!-- $crud.query 托管搜索数据 -->
<el-input v-model="$crud.query.xxx">
<!-- $crud.table.data 托管表格数据 -->
<el-table v-model="$crud.table.data">
<!-- $crud.form 托管表单数据 -->
<el-form :model="$crud.form">
<!-- $crud.table.data 托管tree(表单数据) -->
<el-tree :model="$crud.table.data"> </el-tree></el-form></el-table
></el-input>
$crud.submit(formEl) //提交表单
$crud.reload() //刷新列表数据
$crud.cancel() //设置表单状态为取消
<!-- 下面的例子实现了一个点击查询时锁定按钮的场景 -->
<button class="..." :loading="$crud.loading.query" @click="$crud.reload()">
查询
</button>
/*调用查询方法时,系统会执行
1. 设置表单与查询按钮的loading状态为true
2. 自动封装查询参数(query、分页、排序、...)
3. 触发钩子
4. 异常捕获
5. ...
*/
$crud.toQuery()
$crud.toQuery() //GET
$crud.toDelete() //DELETE
$crud.doUpdate() //PUT
从 NPM 安装
npm i @holyhigh/crud-vue
然后选择对应 ui 库并安装适配器
// 安装CRUD
import request from 'axios'
import CRUD from '@holyhigh/crud-vue/element-ui'
//通常request总是会使用封装后的axios实例
Vue.use(CRUD, { request: request })
// 安装CRUD
import request from 'axios'
import CRUD from '@holyhigh/crud-vue/element-plus'
//通常request总是会使用封装后的axios实例
createApp(App).use(CRUD, { request: request })
//在vue对象的根属性中标记crud/cruds(多实例)属性
export default {
crud: 'auth/users',
// crud: {url:'auth/users'} 对象方式
mounted() {
// 激活后业务组件会被注入一个名为“$crud”的CRUD实例
this.$crud.reload()
// 以及一个入口标识。标识可以用于区分入口或自定义组件
this.$isCrudEntry
}
...
}
通过对象方式激活 CRUD 时,可以传递除 url 外的其他自定义参数。比如
export default {
crud: {url:'auth/users',permission:'a_b_c'}
...
}
之后可通过 VM 属性params
(read only)来获取激活参数
this.$crud.params.permission
params 参数在创建自定义 CRUD 组件时非常有用,比如通过 permission 参数可以实现组件自动权限管理,控制组件视图展示
v1.1+
//element-ui 也可以使用useCrud动态创建crud实例 const $crud = useCrud(vm, restURLMap)
<script lang="ts" setup>
import { useCrud } from '@holyhigh/crud-vue/element-plus'
//通过useCrud函数获取$crud实例
//对象方式激活时与element-ui行为一致
const $crud = useCrud('/api/single')
//自动加载
onMounted(() => {
$crud.reload()
})
</script>
//在一个页面上需要同时处理多CRUD业务时可以通过修改激活方式来处理
export default {
cruds: {//注意,激活标识与单实例不同,多了一个 "s"
user: '/api/users',// user: {url:'/api/users'} 对象方式
log: '/api/logs'
},
mounted() {
// 多实例激活时注入变量会变成“$cruds”,且必须通过明确的实例标识来调用API
this.$cruds.user.reload()
}
...
}
v1.1+
//element-ui 也可以使用userCruds动态创建cruds实例 const $cruds = useCruds(vm, restURL)
<script lang="ts" setup>
import { useCruds } from '@holyhigh/crud-vue/element-plus'
//通过useCruds函数获取$cruds实例
const $cruds = useCruds({
t1: '/api/single',
t2: {
url: '/api/multiple',
},
})
//自动加载t1
onMounted(() => {
$cruds.t1.reload()
})
</script>
//CRUD提供多种回调钩子以满足不同的业务场景
import CRUD from '@holyhigh/crud-vue'
export default {
crud: '/api/users',
methods:{
[CRUD.HOOK.AFTER_QUERY](crud, rs) {
//根据查询结果设置分页值与表格数据
crud.pagination.total = rs.data.total
crud.table.data = rs.data.records || []
}
}
...
}
<script lang="ts" setup>
import CRUD, { onHook } from '@holyhigh/crud-vue/element-plus'
const $crud = useCrud()
//使用onHook函数进行钩子注册
onHook(CRUD.HOOK.AFTER_SUBMIT, (crud) => {
ElNotification.success('提交成功')
crud.toQuery()
})
</script>
<!--
通过$crud.view控制视图显示/隐藏
通过$crud.loading控制按钮/视图的锁定
通过$crud.query/table/form/pagination/...实现视图映射
通过内置API实现UI交互
-->
<template>
<div v-show="$crud.view.queryShow" class="...">
<slot />
<el-button
class="..."
:loading="$crud.loading.query"
@click="$crud.reload()"
>查询</el-button
>
<el-button v-if="$crud.view.queryReset" class="..." @click="reset()"
>重置</el-button
>
</div>
</template>
<script>
import CRUD, { lookUpCrud } from '@holyhigh/crud-vue/element-ui'
import { each } from '@holyhigh/func.js/collection'
export default {
beforeCreate() {
//通过lookUpCrud方法获取组件所在crud入口页面的$crud实例
//如果启用了多实例,必须指定第二个参数`crudName`
this.$crud = lookUpCrud(this)
},
methods: {
reset() {
each(this.$crud.query, (v, k) => {
this.$crud.query[k] = this.$crud.defaults.query[k]
this.$crud.reload()
})
},
},
}
</script>
<template>
<el-table :data="$crud.table.data" @sort-change="(o) => $crud.changeSort(o)">
<el-table-column prop="uname" label="uname" width="180" />
<el-table-column prop="email" label="email" width="180" sortable="custom" />
<el-table-column prop="ip" label="ip" />
<el-table-column align="right">
<template #default="{ row }">
<el-button size="small" @click="$crud.toEdit(row)">Edit</el-button>
<el-button size="small" type="danger" @click="toDelete(row)"
>Delete</el-button
>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { lookUpCrud } from '@holyhigh/crud-vue/element-plus'
//element-plus的lookUpCrud函数只有一个可选入参`crudName`
const $crud = lookUpCrud()
//自定义组件封装删除逻辑
function toDelete(row: Record<string, any>) {
ElMessageBox.confirm('确认删除?').then(() => {
$crud.toDelete(row)
})
}
</script>
:varName
来声明变量,如下例//user实例的地址使用了orgId参数
export default {
cruds: {
org: '/api/orgs',
user: '/api/orgs/:orgId/users'
},
...
methods:{
//切换org时调用该方法
setOrg(orgId){
this.$cruds.user.setURLParams({orgId})
this.$cruds.user.toQuery()
}
}
}
如你所见,动态 URL 最典型的使用场景就是关联业务(当然,非动态 URL 也可实现相同功能)。通过setURLParams
方法可以动态修改请求地址,之后进行 C/R/U/D 操作
可以为 CRUD 指定全局 defaults 属性
// 如果项目返回值统一格式就可以设置全局HOOK实现查询结果赋值
CRUD.defaults[CRUD.HOOK.AFTER_QUERY] = function (crud, rs) {
crud.pagination.total = rs.data.total
crud.table.data = rs.data.records || []
}
// 可以设置默认的全局分页数
CRUD.defaults.pagination.pageSize = 10
// 可以设置默认的按钮显示状态
CRUD.defaults.view.queryReset = true
// 可以设置默认的列表数据主键key
CRUD.defaults.table.rowKey = 'id'
支持默认值设置的属性可在 VM 中查看
RESTAPI 用来构建资源请求地址。默认 C/R/U/D 的资源标识符都为空,如果服务器有不同模式可以修改 API 地址。
CRUD.RESTAPI = {
QUERY: '', //R
EXPORT: '/export',
ADD: '', //C
UPDATE: '', //U
DELETE: '', //D
IMPORT: '/import',
SORT: '/sort'
}
注意,C/R/U/D 对应的 HTTP Method 不会变更
业务组件通过 view 来控制 UI
- queryShow 查询框显示开关
- queryReset 查询框重置按钮显示开关
- opAdd 新增按钮显示开关
- opEdit 编辑按钮显示开关
- opDel 删除按钮显示开关
- opExport 导出按钮显示开关
- opSort 排序按钮显示开关
通过 loading 控制锁定状态
- query 查询按钮锁定开关
- table 表格锁定开关
- del 删除按钮锁定开关
- export 导出按钮锁定开关
- submit 提交按钮锁定开关
- form 表单加载锁定开关
- sort 排序加载锁定开关
托管查询条件的容器
托管排序结果的容器
表格容器托管当前 crud 实例的列表/tree 数据及显示状态
- data 表格数据
- selection 当前选中行
- allColumns 表格所有列,用于动态展示
- orders 排序列表,会传递给 GET 请求
- rowKey✅ 表格行的 id key,默认为'id'。通常由适配器自动设置
分页容器托管当前 crud 实例的列表分页状态
- pageSize✅ 每页记录数
- currentPage 当前页号
- total 总记录数
表单容器托管当前 crud 实例的表单数据
表单当前状态 0:默认;1:新增;2:编辑;3:查看
crud 的入口 vue 实例
crud 激活参数,通过对象方式构造 crud 时可以注入。可用于自定义组件中进行附加操作,比如附加 CRUD 权限控制
crud 错误信息{name,message,status}。可以用于监控并作出合适的反馈,比如网络超时提示
✅ 表示支持全局默认值
启动 crud 实例的查询。向指定 REST 地址发送 GET 请求
启动 crud 实例的删除。向指定 REST 地址发送 DELETE 请求
启动 crud 实例的导出。向指定 REST 地址发送 GET 请求
启动 crud 实例的导入。向指定 REST 地址发送 POST 请求
设置 form 状态为新增。
设置 form 状态为编辑。向指定 REST 地址发送 GET 请求
设置 form 状态为查看。向指定 REST 地址发送 GET 请求
触发
启动 crud 实例的排序。向指定 REST 地址发送 PUT 请求
设置 form 状态为取消。
会调用 formEl 的 validate 方法,并在成功后执行 doAdd(POST)/doEdit(PUT)操作。对于验证错误,catch 中会返回 invalidFields
提交排序结果
重置分页信息并执行一次 toQuery()
获取 crud 实例的服务地址。通常用于 crud 内部
设置服务地址中的参数表
获取行信息。通常用于 crud 内部
用在 table 的 selection-change 事件中,记录 table 当前已选记录
用在 table 的 sort-change 事件,会自动管理排序信息并触发查询
查询前回调,可以修改请求参数(params),比如分页名称等,可取消。取消后不会触发 AFTER_QUERY
注意 ,params 为提交接口的实际对象(包含 query、pagination),此处修改 crud.query/pagination 的内容不会提交到接口
查询后回调,可以获取查询结果,设置表格
删除前调用,可取消。取消后不会触发 AFTER_DELETE
删除后调用
新增前调用,可以用来清空表单或产生 uuid 等
发出编辑查询前调用,可取消。取消后不会触发 BEFORE_EDIT。如需实现row数据回显,可通过cancel取消远程请求并通过row填充crud.form
编辑前调用,可以用来锁定某些字段
发出查看查询前调用,可取消。取消后不会触发 BEFORE_VIEW。如需实现row数据回显,可通过cancel取消远程请求并通过row填充crud.form
查看查询结果返回后调用
提交前调用,可对 form 进行最后加工,可取消。取消后不会触发 AFTER_SUBMIT
提交后调用,可以用来刷新页面、发送通知或其他操作
导出前调用,同 BEFORE_QUERY,可取消。取消后不会触发 AFTER_EXPORT
获取导出数据后调用
操作发生错误时调用
表单取消编辑时触发(调用 cancel 后)
导入文件上传前调用,可在 params 中添加额外参数,可取消。取消后不会触发 AFTER_IMPORT
导入上传完成后调用
排序前调用,可用来打开排序框或启动自动排序处理
提交排序前调用,可对 排序内容 进行最后加工,可取消。取消后不会触发 AFTER_SUBMIT_SORT
提交排序后调用,可以用来刷新页面、发送通知或其他操作
import CRUD,{...} from '@holyhigh/crud-vue/element-ui'
import CRUD,{...} from '@holyhigh/crud-vue/element-plus'
CRUD crud 命名空间,可设置全局默认值、调用钩子等
element-ui
创建一个 crud 单实例入口并绑定指定的 vm(vue 组件)
创建一个 crud 多实例入口并绑定指定的 vm(vue 组件)
向上查找最近的 crud 实例
element-plus
创建一个 crud 单实例入口并返回
创建一个 crud 多实例入口并返回
向上查找最近的 crud 实例
用于注册钩子
多实例时调用 lookUpCrud 方法未指定 crud 标识。解决方法见【6. 自定义组件】
表单提交时验证错误信息
安装时未指定请求器。解决方法见【1. 安装】
进行删除/编辑/查看操作时未指定 table.rowKey。可以设置默认/$crud 实例的对应属性
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。