@axm-pack/manage-render v0.2.9
manage-render
English | 简体中文
基于 ElementPlus 的 CRUD
构造器。
Demo
使用 JSX 的前提是需要安装
@vitejs/plugin-vue-jsx
插件。
安装
pnpm i @axm-pack/manage-render
在 main.ts 中引入
...
import { Context } from '@axm-pack/manage-render'
import '@axm-pack/manage-render/dist/style.css'
const app = createApp(App)
app.use(Context)
...
使用
Dialog
一个十分方便的 Dialog 组件
- 函数式调用
- 顺序关闭 & Esc 关闭
- 自定义内容
- 支持
h()
&JSX
import { defineComponent } from 'vue'
import { Dialog } from '@axm-pack/manage-render'
const DialogContent = defineComponent({
render() {
return (
<div>
<p>Dialog Content.</p>
</div>
)
}
})
// JSX
const show = () => {
const instance = Dialog.init({
title: '🎄 Title'
width: 500,
content: () => <DialogContent />,
})
}
// h()
const show = () => {
const instance = Dialog.init({
title: '🎄 Title'
width: 500,
content: (h) => h(DialogContent),
})
}
对于 Vue 的单文件组件,可以这样写
import { Dialog } from '@axm-pack/manage-render'
import DialogContent from './DialogContent.vue'
// JSX
const show = () => {
const instance = Dialog.init({
title: '🎄 Title'
width: 500,
content: () => <DialogContent />,
})
}
// h()
const show = () => {
const instance = Dialog.init({
title: '🎄 Title'
width: 500,
content: (h) => h(DialogContent),
})
}
这里的 instance
是一个 Dialog
实例,可以通过 instance.close()
来关闭 Dialog。
QueryForm
如其名,用于构建查询表单
- 支持自定义渲染,
JSX
&h()
- 包含内置实现,如
Input
、Select
、DatePicker
等 - TS 类型支持
import { QueryForm } from '@axm-pack/manage-render'
import { ref } from 'vue'
type QueryFormType = {
name: string
age: number
}
const queryForm = ref<QueryFormType>({})
const QueryFormNode = QueryForm<QueryFormType>({
modelValue: queryForm,
formItems: [
{
label: 'Name',
key: 'name',
},
{
label: 'Age',
key: 'age',
type: () => <Component />,
},
],
actions: [
{
text: '查询',
type: 'primary',
handler: () => {
// TODO
},
},
]
})
<template>
<div>
<QueryFormNode />
</div>
</template>
type
默认为文本框,支持自定义,已实现的类型:
useTextField
文本框useSelectorField
下拉框useDatePickerField
日期选择器useDateRangePickerField
日期范围选择器useCascaderField
级联选择器
均为 ElementPlus 的组件,具体的 Props
, Events
可以参考 ElementPlus 的文档。
类型参照
/**
* Defines the properties of a form.
*/
export type FormDefine<T> = {
/** The initial value of the form. */
modelValue?: any
/** The validation rules for the form. */
rules?: any
/** Whether the form is disabled or not. */
disabled?: boolean
/** The width of the form label. */
labelWidth?: number | string
/** The form items to be displayed. */
formItems?: FormItem<T>[]
/** The class name of the form. */
className?: string
/** The actions to be displayed in the form. */
actions?: Actions[]
}
/**
* Defines the properties of a form item.
*/
export type FormItem<T, K = keyof T> = {
/** The type of the form item. */
type?: VNode | (() => VNode)
/** The key of the form item. */
key?: K
/** The label of the form item. */
label?: string
}
/**
* Defines the properties of an action.
*/
export type Actions = {
/** The type of the action. */
type: 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
/** The text to be displayed for the action. */
text: string
/** The icon of the form item. */
icon?: string
/** The function to be called when the action is triggered. */
handler: () => void
}
DataTable
用于构建数据表格,基于 ElementPlus 的 Table
组件
- 支持自定义渲染,
JSX
&h()
- TS 类型支持
import { DataTable } from '@axm-pack/manage-render'
import { ref } from 'vue'
type TableDataType = {
name: string
age: number
}
type PageDataType = {
pageNum: number
pageSize: number
}
const queryForm = ref<PageDataType>({
pageNum: 1,
pageSize: 10,
})
const tableData = ref<TableDataType[]>([])
const loading = ref<boolean>(false)
const total = ref<number>(0)
const DataTableNode = DataTable<TableDataType, PageDataType>({
modelValue: tableData,
loading,
total,
pagination: {
pageSize: () => queryForm.value.pageSize,
pageNum: () => queryForm.value.pageNum,
},
dataFetch: (pageNum, pageSize) => {
// TODO
},
columns: [
{
label: 'Name',
prop: 'name',
},
{
label: 'Age',
prop: 'age',
render: item => {
return <span>{item.age}</span>
},
},
],
action: {
width: 200,
items: [
{
text: 'View',
type: 'primary',
onClick: item => {
// TODO
},
},
],
},
})
<template>
<div>
<DataTableNode />
</div>
</template>
✅ 关于勾选行
import { useSelection } from '@/core/DataTable/fields'
import { DataTable } from '@axm-pack/manage-render'
const selection = ref<string[]>([])
const DataTableNode = DataTable<TableDataType, PageDataType>({
...
columns: [
{
label: '',
width: 50,
...useSelection({
selection,
tableData,
field: 'id',
single: true,
}),
},
],
...
})
selection
的值为选中行的 id
数组
selection
类型参照
type IProps<T> = {
selection: Ref<string[]>
tableData: Ref<T[]>
field: Extract<keyof T, string>
single?: boolean // 是否单选
}
类型参照
/**
* Defines the structure of a table in the DataTable component.
* @template T The type of data displayed in the table.
*/
export type TableDefine<T> = {
/** Whether the table is currently loading data. */
loading?: Ref<boolean>
/** The total number of items in the data set. */
total?: Ref<number>
/** The data items to display in the table. */
items?: Ref<T[]>
/** The height of the table. */
height?: string | number
/** The columns to display in the table. */
columns?: ColumnItem<T>[]
/** A function to handle the click event for a row in the table. */
rowClick?: (row: T) => void
/** The action to display for each row in the table. */
action?: {
/** The label to display for the action. */
label?: string
/** The width of the action. */
width?: string | number
/** The actions to display for the action. */
items?: {
/** The text to display for the action. */
text?: string | ((item: T) => string)
/** The type of button to display for the action. */
type?: 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
/** The icon to display for the action. */
icon?: string
/** Whether the action is disabled. */
show?: (item: T) => boolean
/** A function to handle the click event for the action. */
onClick?: (item: T) => void
/** A function to render custom content for the action. */
render?: (item: T, h: any) => VNode
}[]
}
/** The pagination settings for the table. */
pagination?: {
/** Whether to display the pagination controls. */
show?: boolean
/** The current page number. */
pageNum?: () => number
/** The number of items to display per page. */
pageSize?: () => number
/** The available page sizes to choose from. */
pageSizes?: number[]
}
/** A function to fetch data for the table. */
dataFetch?: (pageNum: number, pageSize: number) => void
}
/**
* Represents a column item in a data table.
* @template T The type of the data item.
* @template K The type of the key of the data item property.
*/
export type ColumnItem<T, K = keyof T> = {
/** The label to display for the column. */
label?: string
/** The key of the data item property to display in the column. */
key?: K
/** The width of the column. */
width?: string | number
/** A function to render custom content in the column. */
render?: (item: T, h: any) => VNode
/** A function to render custom content in the column header. */
header?: (h: any) => VNode
}
DataForm
用于构建数据表单,基于 ElementPlus 的 Form
组件
- 支持自定义渲染,
JSX
&h()
- TS 类型支持
本质上和 QueryForm
差不多,和 QueryForm
共用已实现的组件,但是增加了一些参数,更加适用于构建数据表单
import { DataForm, useTextField } from '@axm-pack/manage-render'
import { ref } from 'vue'
type FormDataType = {
name: string
age: number
}
const formData = ref<FormDataType>({})
const DataFormNode = DataForm<FormDataType>({
modelValue: formData,
labelWidth: 100,
formItems: [
{
label: 'Name',
key: 'name',
type: useTextField(),
},
{
label: 'Age',
key: 'age',
type: () => <Component />,
},
],
actions: [
{
text: '提交',
type: 'primary',
handler: () => {
// TODO
},
},
]
})
<template>
<div>
<DataFormNode />
</div>
</template>
类型参照
/**
* Represents the form definition for creating a form component.
* @template T - The type of the form model.
*/
export type FormDefine<T> = {
class?: string
modelValue?: any
readonly?: boolean
disabled?: boolean
labelWidth?: string | number
rowGap?: number
formItems?: FormItem<T>[]
actions?: ActionItem<T>[]
}
/**
* Represents a form item in the form definition.
* @template T - The type of the form model.
* @template K - The key of the form item.
*/
export type FormItem<T, K = keyof T> = {
label?: string
key?: K
type?: VNode | (() => VNode)
readonly?: boolean
rules?: any
col?: number
rowEnd?: boolean
remark?: string
show?: (item: T) => boolean
}
/**
* Represents an action item in the form definition.
* @template T - The type of the form model.
*/
type ActionItem<T> = {
type: 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
text: string
icon?: string
verify?: boolean
show?: (item: T) => boolean
handler: () => void
}
配合 Dialog 使用
import { defineComponent, ref, PropType } from 'vue'
import { Dialog, DataForm } from '@axm-pack/manage-render'
type FormDataType = {
name: string
age: number
}
const DialogContent = defineComponent({
props: {
item: {
type: Object as PropType<TableDataType>,
default: () => ({}),
required: false,
},
close: {
type: Function as PropType<() => void>,
required: false,
}
}
setup(props) {
const formData = ref<FormDataType>(props.item)
const DataFormNode = DataForm<FormDataType>({
modelValue: formData,
labelWidth: 100,
formItems: [
{
label: 'Name',
key: 'name',
type: useTextField(),
},
{
label: 'Age',
key: 'age',
type: useTextField(),
},
],
actions: [
{
text: '提交',
type: 'primary',
handler: () => {
// TODO
},
},
]
})
return {
DataFormNode,
}
},
render() {
return (
<div>
{this.DataFormNode}
</div>
)
}
})
const show = ({item} : {item: FormDataType}) => {
const instance = Dialog.init({
title: '🎄 Title'
width: 500,
content: () => <DialogContent item={item} close={instance?.close} />,
})
}
export { show }
这种组件我一般会命名为 EditDialog
, 使用的话则直接调用 EditDialog.show({ item })
即可。
eg.
...
<button @click="EditDialog.show({ item })">Edit</button>
...
<script setup>
import EditDialog from './EditDialog.tsx'
</script>
8 months ago
8 months ago
10 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
10 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago