parent
799934171a
commit
b6b97accb1
@ -3,7 +3,12 @@ import type { SetupContext } from 'vue';
|
|||||||
|
|
||||||
import type { Recordable } from '@vben/types';
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import type { JsonViewerProps } from './types';
|
import type {
|
||||||
|
JsonViewerAction,
|
||||||
|
JsonViewerProps,
|
||||||
|
JsonViewerToggle,
|
||||||
|
JsonViewerValue,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
import { computed, useAttrs } from 'vue';
|
import { computed, useAttrs } from 'vue';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -11,7 +16,7 @@ import VueJsonViewer from 'vue-json-viewer';
|
|||||||
|
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import { isBoolean, isString } from '@vben-core/shared/utils';
|
import { isBoolean } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
defineOptions({ name: 'JsonViewer' });
|
defineOptions({ name: 'JsonViewer' });
|
||||||
|
|
||||||
@ -25,15 +30,44 @@ const props = withDefaults(defineProps<JsonViewerProps>(), {
|
|||||||
previewMode: false,
|
previewMode: false,
|
||||||
showArrayIndex: true,
|
showArrayIndex: true,
|
||||||
showDoubleQuotes: false,
|
showDoubleQuotes: false,
|
||||||
parseString: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
parseError: [error: Error];
|
click: [event: MouseEvent];
|
||||||
|
copied: [event: JsonViewerAction];
|
||||||
|
keyClick: [key: string];
|
||||||
|
toggle: [param: JsonViewerToggle];
|
||||||
|
valueClick: [value: JsonViewerValue];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const attrs: SetupContext['attrs'] = useAttrs();
|
const attrs: SetupContext['attrs'] = useAttrs();
|
||||||
|
|
||||||
|
function handleClick(event: MouseEvent) {
|
||||||
|
if (
|
||||||
|
event.target instanceof HTMLElement &&
|
||||||
|
event.target.classList.contains('jv-item')
|
||||||
|
) {
|
||||||
|
const pathNode = event.target.closest('.jv-push');
|
||||||
|
if (!pathNode || !pathNode.hasAttribute('path')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const param: JsonViewerValue = {
|
||||||
|
path: '',
|
||||||
|
value: '',
|
||||||
|
depth: 0,
|
||||||
|
el: event.target,
|
||||||
|
};
|
||||||
|
|
||||||
|
param.path = pathNode.getAttribute('path') || '';
|
||||||
|
param.depth = Number(pathNode.getAttribute('depth')) || 0;
|
||||||
|
|
||||||
|
param.value = event.target.textContent || undefined;
|
||||||
|
param.value = JSON.parse(param.value);
|
||||||
|
emit('valueClick', param);
|
||||||
|
}
|
||||||
|
emit('click', event);
|
||||||
|
}
|
||||||
|
|
||||||
const bindProps = computed<Recordable<any>>(() => {
|
const bindProps = computed<Recordable<any>>(() => {
|
||||||
const copyable = {
|
const copyable = {
|
||||||
copyText: $t('ui.jsonViewer.copy'),
|
copyText: $t('ui.jsonViewer.copy'),
|
||||||
@ -45,28 +79,15 @@ const bindProps = computed<Recordable<any>>(() => {
|
|||||||
return {
|
return {
|
||||||
...props,
|
...props,
|
||||||
...attrs,
|
...attrs,
|
||||||
|
onCopied: (event: JsonViewerAction) => emit('copied', event),
|
||||||
|
onKeyclick: (key: string) => emit('keyClick', key),
|
||||||
|
onClick: (event: MouseEvent) => handleClick(event),
|
||||||
copyable: props.copyable ? copyable : false,
|
copyable: props.copyable ? copyable : false,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const modelValue = defineModel();
|
|
||||||
|
|
||||||
const jsonToShow = computed(() => {
|
|
||||||
if (props.parseString && isString(modelValue.value)) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(modelValue.value);
|
|
||||||
} catch (error) {
|
|
||||||
emit('parseError', error as Error);
|
|
||||||
console.error('Error parsing JSON:', error);
|
|
||||||
return modelValue.value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return modelValue.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VueJsonViewer :value="jsonToShow" v-bind="bindProps">
|
<VueJsonViewer v-bind="bindProps">
|
||||||
<template #copy="slotProps">
|
<template #copy="slotProps">
|
||||||
<slot name="copy" v-bind="slotProps"></slot>
|
<slot name="copy" v-bind="slotProps"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export interface JsonViewerProps {
|
export interface JsonViewerProps {
|
||||||
|
/** 要展示的结构数据 */
|
||||||
|
value: any;
|
||||||
/** 展开深度 */
|
/** 展开深度 */
|
||||||
expandDepth?: number;
|
expandDepth?: number;
|
||||||
/** 是否可复制 */
|
/** 是否可复制 */
|
||||||
@ -19,6 +21,24 @@ export interface JsonViewerProps {
|
|||||||
showArrayIndex?: boolean;
|
showArrayIndex?: boolean;
|
||||||
/** 显示双引号 */
|
/** 显示双引号 */
|
||||||
showDoubleQuotes?: boolean;
|
showDoubleQuotes?: boolean;
|
||||||
/** 解析字符串 */
|
}
|
||||||
parseString?: boolean;
|
|
||||||
|
export interface JsonViewerAction {
|
||||||
|
action: string;
|
||||||
|
text: string;
|
||||||
|
trigger: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonViewerValue {
|
||||||
|
value: any;
|
||||||
|
path: string;
|
||||||
|
depth: number;
|
||||||
|
el: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonViewerToggle {
|
||||||
|
/** 鼠标事件 */
|
||||||
|
event: MouseEvent;
|
||||||
|
/** 当前展开状态 */
|
||||||
|
open: boolean;
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,8 @@ export const json1 = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const json2 = `
|
export const json2 = JSON.parse(`
|
||||||
{
|
{
|
||||||
"id": "chatcmpl-123",
|
"id": "chatcmpl-123",
|
||||||
"object": "chat.completion",
|
"object": "chat.completion",
|
||||||
"created": 1677652288,
|
"created": 1677652288,
|
||||||
@ -46,6 +46,21 @@ export const json2 = `
|
|||||||
"completion_tokens": 12,
|
"completion_tokens": 12,
|
||||||
"total_tokens": 21,
|
"total_tokens": 21,
|
||||||
"debug_mode": true
|
"debug_mode": true
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"startAt": "2021-08-01T00:00:00Z",
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"timestamp": "2021-08-01T00:00:00Z",
|
||||||
|
"message": "This is a debug message",
|
||||||
|
"extra":[ "extra1", "extra2" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2021-08-01T00:00:01Z",
|
||||||
|
"message": "This is another debug message",
|
||||||
|
"extra":[ "extra3", "extra4" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`);
|
||||||
|
@ -1,9 +1,23 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { JsonViewerAction, JsonViewerValue } from '@vben/common-ui';
|
||||||
|
|
||||||
import { JsonViewer, Page } from '@vben/common-ui';
|
import { JsonViewer, Page } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Card } from 'ant-design-vue';
|
import { Card, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { json1, json2 } from './data';
|
import { json1, json2 } from './data';
|
||||||
|
|
||||||
|
function handleKeyClick(key: string) {
|
||||||
|
message.info(`点击了Key ${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleValueClick(value: JsonViewerValue) {
|
||||||
|
message.info(`点击了Value ${JSON.stringify(value)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCopied(_event: JsonViewerAction) {
|
||||||
|
message.success('已复制JSON');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Page
|
<Page
|
||||||
@ -11,16 +25,27 @@ import { json1, json2 } from './data';
|
|||||||
description="一个渲染 JSON 结构数据的组件,支持复制、展开等,简单易用"
|
description="一个渲染 JSON 结构数据的组件,支持复制、展开等,简单易用"
|
||||||
>
|
>
|
||||||
<Card title="默认配置">
|
<Card title="默认配置">
|
||||||
<JsonViewer v-model="json1" />
|
<JsonViewer :value="json1" />
|
||||||
</Card>
|
</Card>
|
||||||
<Card title="可复制、默认展开3层、显示边框" class="mt-4">
|
<Card title="可复制、默认展开3层、显示边框、事件处理" class="mt-4">
|
||||||
<JsonViewer
|
<JsonViewer
|
||||||
v-model="json2"
|
:value="json2"
|
||||||
:expand-depth="3"
|
:expand-depth="3"
|
||||||
copyable
|
copyable
|
||||||
:sort="false"
|
:sort="false"
|
||||||
|
@key-click="handleKeyClick"
|
||||||
|
@value-click="handleValueClick"
|
||||||
|
@copied="handleCopied"
|
||||||
boxed
|
boxed
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Card title="预览模式" class="mt-4">
|
||||||
|
<JsonViewer
|
||||||
|
:value="json2"
|
||||||
|
copyable
|
||||||
|
preview-mode
|
||||||
|
:show-array-index="false"
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user