PropertyDialog 属性对话框
用于编辑组件属性的对话框组件,常配合 PageDesigner 使用。
基础用法
最基础的属性对话框用法。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="componentMeta"
:currentProps="currentProps"
@update:currentProps="handleUpdate"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
const currentProps = ref({
text: '按钮',
type: 'primary',
})
const componentMeta = {
name: 'NButton',
label: '按钮',
icon: '🔘',
description: '常用的操作按钮',
props: [
{
name: 'text',
label: '按钮文字',
type: 'string',
defaultValue: '按钮',
group: '基础',
},
{
name: 'type',
label: '按钮类型',
type: 'select',
options: [
{ label: '默认', value: '' },
{ label: '主要', value: 'primary' },
{ label: '成功', value: 'success' },
{ label: '警告', value: 'warning' },
{ label: '危险', value: 'danger' },
],
defaultValue: '',
group: '基础',
},
],
}
const handleUpdate = (newProps) => {
currentProps.value = newProps
console.log('属性更新:', newProps)
}
</script>分组显示
属性会按照 group 字段自动分组显示。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="componentMeta"
:currentProps="currentProps"
@update:currentProps="handleUpdate"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
const currentProps = ref({
text: '按钮',
type: 'primary',
size: 'default',
disabled: false,
})
const componentMeta = {
name: 'NButton',
label: '按钮',
icon: '🔘',
description: '常用的操作按钮',
props: [
{
name: 'text',
label: '按钮文字',
type: 'string',
defaultValue: '按钮',
group: '基础',
},
{
name: 'type',
label: '按钮类型',
type: 'select',
options: [
{ label: '默认', value: '' },
{ label: '主要', value: 'primary' },
{ label: '成功', value: 'success' },
{ label: '警告', value: 'warning' },
{ label: '危险', value: 'danger' },
],
defaultValue: '',
group: '基础',
},
{
name: 'size',
label: '尺寸',
type: 'select',
options: [
{ label: '大型', value: 'large' },
{ label: '默认', value: 'default' },
{ label: '小型', value: 'small' },
],
defaultValue: 'default',
group: '样式',
},
{
name: 'disabled',
label: '禁用',
type: 'boolean',
defaultValue: false,
group: '状态',
},
],
}
const handleUpdate = (newProps) => {
currentProps.value = newProps
console.log('属性更新:', newProps)
}
</script>重置默认值
点击"重置默认值"按钮可以将所有属性重置为默认值。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="componentMeta"
:currentProps="currentProps"
@update:currentProps="handleUpdate"
@reset="handleReset"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
const currentProps = ref({
text: '按钮',
type: 'primary',
})
const componentMeta = {
name: 'NButton',
label: '按钮',
icon: '🔘',
props: [
{
name: 'text',
label: '按钮文字',
type: 'string',
defaultValue: '按钮',
},
{
name: 'type',
label: '按钮类型',
type: 'select',
options: [
{ label: '默认', value: '' },
{ label: '主要', value: 'primary' },
],
defaultValue: '',
},
],
}
const handleUpdate = (newProps) => {
currentProps.value = newProps
}
const handleReset = () => {
console.log('已重置为默认值')
}
</script>无属性状态
当组件没有可编辑属性时,会显示空状态。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="componentMeta"
:currentProps="currentProps"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
const currentProps = ref({})
const componentMeta = {
name: 'NIcon',
label: '图标',
icon: '🎨',
description: '图标组件',
props: [],
}
</script>空组件元数据
当组件元数据为 null 时,会显示默认状态。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="null"
:currentProps="{}"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
</script>配合 PageDesigner 使用
在 PageDesigner 中选中组件后,打开属性对话框进行编辑。
vue
<template>
<NPageDesigner
:schema="schema"
@select="handleSelect"
/>
<NPropertyDialog
v-model="showDialog"
:componentMeta="selectedMeta"
:currentProps="selectedProps"
@update:currentProps="handleUpdateProps"
/>
</template>
<script setup>
import { ref } from 'vue')
const schema = ref({
components: [
{
id: '1',
type: 'button',
props: { text: '按钮', type: 'primary' },
position: { x: 100, y: 100, width: 120, height: 40 },
},
],
dataFlow: [],
})
const showDialog = ref(false)
const selectedMeta = ref(null)
const selectedProps = ref({})
// 组件元数据映射
const componentMetaMap = {
button: {
name: 'NButton',
label: '按钮',
icon: '🔘',
props: [
{
name: 'text',
label: '按钮文字',
type: 'string',
defaultValue: '按钮',
group: '基础',
},
{
name: 'type',
label: '按钮类型',
type: 'select',
options: [
{ label: '默认', value: '' },
{ label: '主要', value: 'primary' },
],
defaultValue: '',
group: '基础',
},
],
},
}
const handleSelect = (component) => {
selectedMeta.value = componentMetaMap[component.type] || null
selectedProps.value = { ...component.props }
showDialog.value = true
}
const handleUpdateProps = (newProps) => {
selectedProps.value = newProps
// 更新 schema 中对应组件的 props
const component = schema.value.components.find(
(c) => c.id === selectedMeta.value?.name
)
if (component) {
component.props = newProps
}
}
</script>自定义表单项类型
支持多种表单项类型:string、number、boolean、select、color、date 等。
vue
<template>
<NButton @click="show = true">编辑属性</NButton>
<NPropertyDialog
v-model="show"
:componentMeta="componentMeta"
:currentProps="currentProps"
@update:currentProps="handleUpdate"
/>
</template>
<script setup>
import { ref } from 'vue')
const show = ref(false)
const currentProps = ref({
title: '标题',
count: 10,
visible: true,
theme: 'light',
color: '#1890ff',
date: '2024-01-01',
})
const componentMeta = {
name: 'NExample',
label: '示例组件',
icon: '📦',
props: [
{
name: 'title',
label: '标题',
type: 'string',
defaultValue: '标题',
group: '基础',
},
{
name: 'count',
label: '数量',
type: 'number',
defaultValue: 10,
group: '基础',
},
{
name: 'visible',
label: '是否可见',
type: 'boolean',
defaultValue: true,
group: '状态',
},
{
name: 'theme',
label: '主题',
type: 'select',
options: [
{ label: '浅色', value: 'light' },
{ label: '深色', value: 'dark' },
],
defaultValue: 'light',
group: '样式',
},
{
name: 'color',
label: '颜色',
type: 'color',
defaultValue: '#1890ff',
group: '样式',
},
{
name: 'date',
label: '日期',
type: 'date',
defaultValue: '2024-01-01',
group: '其他',
},
],
}
const handleUpdate = (newProps) => {
currentProps.value = newProps
console.log('属性更新:', newProps)
}
</script>API
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 是否显示弹窗 | boolean | false |
| componentMeta | 组件元数据 | ComponentMeta | null | null |
| currentProps | 当前 props 值 | Record<string, any> | {} |
ComponentMeta
| 属性 | 说明 | 类型 |
|---|---|---|
| name | 组件名称 | string |
| label | 组件标签 | string |
| icon | 组件图标 | string |
| description | 组件描述 | string |
| props | 属性列表 | PropMeta[] |
PropMeta
| 属性 | 说明 | 类型 |
|---|---|---|
| name | 属性名称 | string |
| label | 属性标签 | string |
| type | 属性类型 | 'string' | 'number' | 'boolean' | 'select' | 'color' | 'date' |
| defaultValue | 默认值 | any |
| options | 选项(type 为 select 时) | { label: string; value: any }[] |
| group | 分组名称 | string |
Events
| 事件名 | 说明 | 类型 |
|---|---|---|
| update:modelValue | 显示状态改变时触发 | (value: boolean) => void |
| update:currentProps | 属性值改变时触发 | (value: Record<string, any>) => void |
| reset | 点击重置按钮时触发 | () => void |
Slots
| 插槽名 | 说明 |
|---|---|
| header | 自定义头部内容 |
| footer | 自定义底部内容 |