Skip to content

ProDescriptions ​

Display a single record with table-compatible field schemas, formatting, requests and field editing. Layout props follow the native antdv-next Descriptions component.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Space } from 'antdv-next'
import {
  ProDescriptions,
  type ProDescriptionsColumn,
  type ProDescriptionsInstance,
  type ProKey,
} from '@bubblesjs/antv-next-pro'

interface ProjectDetails extends Record<string, unknown> {
  name: string
  owner: string
  status: string
  budget: number
  createdAt: string
  notes: string
}

const action = ref<ProDescriptionsInstance<ProjectDetails>>()
const server = ref<ProjectDetails>({
  name: '组件升级计划',
  owner: '林晓',
  status: 'active',
  budget: 16800,
  createdAt: '2026-10-21',
  notes: '先完成示例,再安排团队验收。',
})
const requests = ref(0)
const feedback = ref('点击字段旁的编辑图标;清空项目名称后保存可查看校验。')
const columns: ProDescriptionsColumn<ProjectDetails>[] = [
  {
    title: '项目名称',
    dataIndex: 'name',
    formItemProps: { rules: [{ required: true, message: '请输入项目名称' }] },
  },
  { title: '负责人', dataIndex: 'owner' },
  {
    title: '状态',
    dataIndex: 'status',
    valueType: 'select',
    valueEnum: {
      active: { text: '进行中', status: 'Processing' },
      done: { text: '已完成', status: 'Success' },
      pending: { text: '待开始', status: 'Default' },
    },
  },
  { title: '预算', dataIndex: 'budget', valueType: 'money', editable: false },
  { title: '创建日期', dataIndex: 'createdAt', valueType: 'date', editable: false },
  { title: '备注', dataIndex: 'notes', valueType: 'textarea' },
]

async function request() {
  requests.value++
  return { data: { ...server.value }, success: true }
}
async function save(_key: ProKey, record: ProjectDetails) {
  server.value = { ...record }
  feedback.value = `已保存:${record.name} · ${record.owner}`
  return true
}
</script>

<template>
  <div class="descriptions-demo" data-demo="pro-descriptions">
    <ProDescriptions
      ref="action"
      title="项目详情"
      tooltip="通过 request 获取详情,逐字段编辑并保存。"
      :columns="columns"
      :request="request"
      :editable="{ type: 'single', onSave: save }"
      :column="{ xs: 1, sm: 2 }"
      bordered
      @editable-error="feedback = '请检查字段内容后重试。'"
    >
      <template #extra>
        <Space>
          <Button data-demo-descriptions-edit @click="action?.startEditable('name')"
            >编辑名称</Button
          >
          <Button data-demo-descriptions-reload @click="action?.reload()">重新加载</Button>
        </Space>
      </template>
    </ProDescriptions>
    <p data-demo-descriptions-state aria-live="polite">已加载 {{ requests }} 次。{{ feedback }}</p>
    <pre data-demo-descriptions-data>{{ JSON.stringify(server, null, 2) }}</pre>
  </div>
</template>

<style scoped>
.descriptions-demo {
  display: grid;
  gap: 16px;
}
p {
  margin: 0;
}
pre {
  margin: 0;
  overflow: auto;
  padding: 16px;
  border: 1px solid #d9d9d9;
  border-radius: 8px;
}
</style>

Minimal usage ​

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ProDescriptions, type ProDescriptionsColumn } from '@bubblesjs/antv-next-pro'

type Profile = { name: string; status: string }
const profile = ref<Profile>({ name: 'Alex', status: 'active' })
const columns: ProDescriptionsColumn<Profile>[] = [
  { title: 'Name', dataIndex: 'name', formItemProps: { rules: [{ required: true }] } },
  {
    title: 'Status',
    dataIndex: 'status',
    valueType: 'select',
    valueEnum: { active: 'Active', inactive: 'Inactive' },
  },
]
</script>

<template>
  <ProDescriptions
    title="Profile"
    :columns="columns"
    :data-source="profile"
    :editable="{ type: 'single' }"
    @data-source-change="profile = $event"
  />
</template>

API ​

PropBehavior
columnsProDescriptionsColumn<T>[], one entry per field
dataSourceA single object T
request(params: P) => Promise<{ data: T; success?: boolean }>; runs on mount and parameter changes
paramsRequest parameters; stale responses do not overwrite newer results
loadingExplicit override for the request loading state
title / tooltip / extraHeading, heading tooltip and additional content
editablefalse or EditableConfig; editing defaults to one field at a time
formPropsNative editing Form props; merged with editable.formProps, which takes precedence
formRef / editable.formRefRef<FormInstance | undefined>, the actual native editing form
actionRefRef<ProDescriptionsInstance<T> | undefined>; component ref is also supported
emptyTextEmpty field placeholder
Native Descriptions propsbordered, column, size, layout and other native layout props
prefixCls / classes / stylesPublic prefix and semantic styles
Column propBehavior
key / dataIndexField editing identifier uses key, otherwise a derived dataIndex; nested paths use arrays
title / labelA node or (column) => VNodeChild; label is the fallback
span / orderNative item span; higher order values come first
hide / hideInDescriptionsHide a field
valueType / valueEnum / fieldPropsShared ProField display, editing and formatting
request / paramsField option requests, separate from the record request
readonly / editableBlock editing; editable also accepts (record, index) => boolean
formItemPropsNative validation rules and field item props
renderText(value, record, index, action) => unknown
render(dom, record, index, action, schema) => VNodeChild
formItemRender(schema, context, form) => VNodeChild; form is the native FormInstance

The custom input context contains record, index, column, editable, isEditable, recordKey, type="descriptions", dependencies, defaultRender() and update(value). Call update from custom inputs to update the draft. Legacy renderFormItem(schema, context) remains compatible.

Editing and events ​

Editable type single allows one field at a time; multiple allows concurrent fields. When editableKeys is controlled, accept new keys in editable.onChange(keys, rows).

Saving validates and merges only the active field. Other field drafts are isolated. Editable onSave(key, next, origin) may return a Promise; false or validation failure keeps editing open. Cancel restores the current field and calls onCancel. Readonly or explicitly non-editable fields cannot enter editing.

Event/callbackBehavior
dataSourceChange(data)Full record after a successful field save; the caller persists and updates its data
requestError(error)Record request failure
editableError(error)Validation or editing callback errors
onLoadingChange(loading)Record request loading changes
editable.onValuesChange(record, rows)Draft changes

Slots and ref ​

SlotScope and purpose
title / extraReplace the heading or additional content
field-${columnKey}{ record, column }, replaces the read view of that field
DefaultAppend native ProDescriptions.Item / ProDescriptionsItem entries

ProDescriptions.Item and the named ProDescriptionsItem export are native DescriptionsItem components. Native items in the default slot do not become editable schema fields automatically.

MethodBehavior
reload(): Promise<void>Request using current params
getData() / dataSourceRead the current record
setDataSource(data)Replace internal data and draft; undefined resets to an empty object
startEditable(key): booleanStart field editing using the column identifier
saveEditable(key): Promise<boolean>Validate and save a field
cancelEditable(key) / isEditable(key)Cancel or inspect field editing

Styling and configuration ​

Classes/styles accept maps or ({ props }) => map and are forwarded to native Descriptions. Part names follow its semantic styling API. Legacy classNames is compatible; classes wins for matching parts.

The public class defaults to ant-pro-descriptions, or demo-pro-descriptions when native ConfigProvider uses prefixCls="demo". The component prefixCls overrides it. Locale, direction, theme algorithms and native component tokens follow ConfigProvider; configure extension tokens through ProConfigProvider.

FieldRender ​

FieldRender is also available as a named export for composing a single description field. It accepts text, entity (the entire record), action (ProDescriptionsInstance), dataIndex, index, mode, valueType, valueEnum, fieldProps, request, params, dependencies and the rendering callbacks above. Form supplies the native form to custom editing; emptyText sets the placeholder.

Updates emit update:text; field option request errors call onFieldRequestError(error). FieldRender does not create a form or save records. It has no additional slots or instance methods and uses ProField for default rendering.

Released under the MIT License