@holyhigh/crud-vue
TypeScript icon, indicating that this package has built-in type declarations

1.2.2 • Public • Published

!!! 该库已迁移至 Cruda,本仓库不再维护 !!!

CRUD-vue

  基于 Vue 的通用 CRUD 视图模型库;提供对常用 CRUD 场景的视图与操作托管,通过不同适配器可以实现对主流 UI 库的自动适配。

概念图

CRUD-vue

介绍

  在所有存在列表展示的业务系统中,无论使用何种 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()
  • RESTful HTTP Method
$crud.toQuery() //GET
$crud.toDelete() //DELETE
$crud.doUpdate() //PUT

安装

  从 NPM 安装

npm i @holyhigh/crud-vue

  然后选择对应 ui 库并安装适配器

如何使用

1. 安装适配器

  • element-ui
// 安装CRUD
import request from 'axios'
import CRUD from '@holyhigh/crud-vue/element-ui'
//通常request总是会使用封装后的axios实例
Vue.use(CRUD, { request: request })
  • element-plus
// 安装CRUD
import request from 'axios'
import CRUD from '@holyhigh/crud-vue/element-plus'
//通常request总是会使用封装后的axios实例
createApp(App).use(CRUD, { request: request })

2. 激活

  • element-ui
//在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)
  • element-plus
<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>

3. 多实例

  • element-ui
//在一个页面上需要同时处理多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)
  • element-plus
<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>

4. HOOK

  • element-ui
//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 || []
    }
  }
  ...
}
  • element-plus
<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>

5. 自定义组件

  • element-ui
      自定义组件的核心逻辑是封装 crud 页面的数据及操作,比如 crudTable,而前提就是获取$crud实例。通过lookUpCrud方法可以拿到页面入口的$crud 实例。下面以一个查询框为例展示自定义组件需要关注的几个方面
<!--
   通过$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>
  • element-plus
<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>

6. URL 参数

  • element-ui
      CRUD 激活时,REST 地址支持 URL 参数来动态构建。通过 :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 操作

  • element-plus
    逻辑与 element-ui 相同

7. defaults

可以为 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 中查看

8. RESTAPI

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 不会变更

VM

  • view

    业务组件通过 view 来控制 UI

    • queryShow 查询框显示开关
    • queryReset 查询框重置按钮显示开关
    • opAdd 新增按钮显示开关
    • opEdit 编辑按钮显示开关
    • opDel 删除按钮显示开关
    • opExport 导出按钮显示开关
    • opSort 排序按钮显示开关
  • loading

    通过 loading 控制锁定状态

    • query 查询按钮锁定开关
    • table 表格锁定开关
    • del 删除按钮锁定开关
    • export 导出按钮锁定开关
    • submit 提交按钮锁定开关
    • form 表单加载锁定开关
    • sort 排序加载锁定开关
  • query

    托管查询条件的容器

  • sortation

    托管排序结果的容器

  • table

    表格容器托管当前 crud 实例的列表/tree 数据及显示状态

    • data 表格数据
    • selection 当前选中行
    • allColumns 表格所有列,用于动态展示
    • orders 排序列表,会传递给 GET 请求
    • rowKey 表格行的 id key,默认为'id'。通常由适配器自动设置
  • pagination

    分页容器托管当前 crud 实例的列表分页状态

    • pageSize 每页记录数
    • currentPage 当前页号
    • total 总记录数
  • form

    表单容器托管当前 crud 实例的表单数据

  • formStatus

    表单当前状态 0:默认;1:新增;2:编辑;3:查看

  • vm

    crud 的入口 vue 实例

  • params

    crud 激活参数,通过对象方式构造 crud 时可以注入。可用于自定义组件中进行附加操作,比如附加 CRUD 权限控制

  • error

    crud 错误信息{name,message,status}。可以用于监控并作出合适的反馈,比如网络超时提示

表示支持全局默认值

APIs

  • toQuery() : Promise

    启动 crud 实例的查询。向指定 REST 地址发送 GET 请求

  • toDelete(rows) : Promise

    启动 crud 实例的删除。向指定 REST 地址发送 DELETE 请求

  • toExport() : Promise

    启动 crud 实例的导出。向指定 REST 地址发送 GET 请求

  • toImport(file/s) : Promise

    启动 crud 实例的导入。向指定 REST 地址发送 POST 请求

  • toAdd(...args)

    设置 form 状态为新增。

  • toEdit(row) : Promise

    设置 form 状态为编辑。向指定 REST 地址发送 GET 请求

  • toView(row) : Promise

    设置 form 状态为查看。向指定 REST 地址发送 GET 请求

  • toSort()

    触发

  • submitSort() : Promise

    启动 crud 实例的排序。向指定 REST 地址发送 PUT 请求

  • cancel()

    设置 form 状态为取消。

  • submit(formEl) : Promise

    会调用 formEl 的 validate 方法,并在成功后执行 doAdd(POST)/doEdit(PUT)操作。对于验证错误,catch 中会返回 invalidFields

  • submitSort() : Promise

    提交排序结果

  • reload() : Promise

    重置分页信息并执行一次 toQuery()

  • getRestURL()

    获取 crud 实例的服务地址。通常用于 crud 内部

  • setURLParams(paramObj)

    设置服务地址中的参数表

  • getDetails(rowId)

    获取行信息。通常用于 crud 内部

  • changeSelection(selection: Record<string, any>[])

    用在 table 的 selection-change 事件中,记录 table 当前已选记录

  • changeOrder(orderData: { column: Record<string, any> prop: string order: string | null })

    用在 table 的 sort-change 事件,会自动管理排序信息并触发查询

HOOKs

  • BEFORE_QUERY(crud,params,orders,cancel)

    查询前回调,可以修改请求参数(params),比如分页名称等,可取消。取消后不会触发 AFTER_QUERY
    注意 ,params 为提交接口的实际对象(包含 query、pagination),此处修改 crud.query/pagination 的内容不会提交到接口

  • AFTER_QUERY(crud,rs)

    查询后回调,可以获取查询结果,设置表格

  • BEFORE_DELETE(crud,rows,cancel)

    删除前调用,可取消。取消后不会触发 AFTER_DELETE

  • AFTER_DELETE(crud,rs,rows)

    删除后调用

  • BEFORE_ADD(crud,...args)

    新增前调用,可以用来清空表单或产生 uuid 等

  • BEFORE_EDIT_QUERY(crud,params,cancel,row)

    发出编辑查询前调用,可取消。取消后不会触发 BEFORE_EDIT。如需实现row数据回显,可通过cancel取消远程请求并通过row填充crud.form

  • BEFORE_EDIT(crud,rs,row)

    编辑前调用,可以用来锁定某些字段

  • BEFORE_VIEW_QUERY(crud,params,cancel,row)

    发出查看查询前调用,可取消。取消后不会触发 BEFORE_VIEW。如需实现row数据回显,可通过cancel取消远程请求并通过row填充crud.form

  • BEFORE_VIEW(crud,rs,row)

    查看查询结果返回后调用

  • BEFORE_SUBMIT(crud,cancel)

    提交前调用,可对 form 进行最后加工,可取消。取消后不会触发 AFTER_SUBMIT

  • AFTER_SUBMIT(crud,rs)

    提交后调用,可以用来刷新页面、发送通知或其他操作

  • BEFORE_EXPORT(crud,params,orders,cancel)

    导出前调用,同 BEFORE_QUERY,可取消。取消后不会触发 AFTER_EXPORT

  • AFTER_EXPORT(crud,rs)

    获取导出数据后调用

  • ON_ERROR(crud,error)

    操作发生错误时调用

  • ON_CANCEL(crud)

    表单取消编辑时触发(调用 cancel 后)

  • BEFORE_IMPORT(crud,params,cancel)

    导入文件上传前调用,可在 params 中添加额外参数,可取消。取消后不会触发 AFTER_IMPORT

  • AFTER_IMPORT(crud,rs)

    导入上传完成后调用

  • BEFORE_SORT(crud,...args)

    排序前调用,可用来打开排序框或启动自动排序处理

  • BEFORE_SUBMIT_SORT(crud,sortation,cancel)

    提交排序前调用,可对 排序内容 进行最后加工,可取消。取消后不会触发 AFTER_SUBMIT_SORT

  • AFTER_SUBMIT_SORT(crud,rs)

    提交排序后调用,可以用来刷新页面、发送通知或其他操作

可导出

import CRUD,{...} from '@holyhigh/crud-vue/element-ui'
import CRUD,{...} from '@holyhigh/crud-vue/element-plus'
  • CRUD crud 命名空间,可设置全局默认值、调用钩子等

    element-ui

    • useCrud(vm,restURL) : CRUD

      创建一个 crud 单实例入口并绑定指定的 vm(vue 组件)

    • useCruds(vm,restURLMap) : Record<string, CRUD>

      创建一个 crud 多实例入口并绑定指定的 vm(vue 组件)

    • lookUpCrud(vm,crudName?) : CRUD | null

      向上查找最近的 crud 实例

    element-plus

    • useCrud(restURL) : CRUD

      创建一个 crud 单实例入口并返回

    • useCruds(restURLMap) : Record<string, CRUD>

      创建一个 crud 多实例入口并返回

    • lookUpCrud(crudName?) : CRUD | null

      向上查找最近的 crud 实例

    • onHook(hookName,hook) : void

      用于注册钩子

错误信息

  • Must specify 'crudName' when multiple instances detected

    多实例时调用 lookUpCrud 方法未指定 crud 标识。解决方法见【6. 自定义组件】

  • form validation Xxx

    表单提交时验证错误信息

  • Cannot find [request] in the installation options

    安装时未指定请求器。解决方法见【1. 安装】

  • table.rowKey is a blank value 'Xxx', it may cause an error - toDelete/Edit/View()

    进行删除/编辑/查看操作时未指定 table.rowKey。可以设置默认/$crud 实例的对应属性

Package Sidebar

Install

npm i @holyhigh/crud-vue

Weekly Downloads

3

Version

1.2.2

License

MIT

Unpacked Size

43.4 kB

Total Files

13

Last publish

Collaborators

  • holyhigh