@@ -3,7 +3,12 @@ import type { SetupContext } from 'vue';
|
||||
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import type { JsonViewerProps } from './types';
|
||||
import type {
|
||||
JsonViewerAction,
|
||||
JsonViewerProps,
|
||||
JsonViewerToggle,
|
||||
JsonViewerValue,
|
||||
} from './types';
|
||||
|
||||
import { computed, useAttrs } from 'vue';
|
||||
// @ts-ignore
|
||||
@@ -11,7 +16,7 @@ import VueJsonViewer from 'vue-json-viewer';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { isBoolean, isString } from '@vben-core/shared/utils';
|
||||
import { isBoolean } from '@vben-core/shared/utils';
|
||||
|
||||
defineOptions({ name: 'JsonViewer' });
|
||||
|
||||
@@ -25,15 +30,44 @@ const props = withDefaults(defineProps<JsonViewerProps>(), {
|
||||
previewMode: false,
|
||||
showArrayIndex: true,
|
||||
showDoubleQuotes: false,
|
||||
parseString: true,
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
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 copyable = {
|
||||
copyText: $t('ui.jsonViewer.copy'),
|
||||
@@ -45,28 +79,15 @@ const bindProps = computed<Recordable<any>>(() => {
|
||||
return {
|
||||
...props,
|
||||
...attrs,
|
||||
onCopied: (event: JsonViewerAction) => emit('copied', event),
|
||||
onKeyclick: (key: string) => emit('keyClick', key),
|
||||
onClick: (event: MouseEvent) => handleClick(event),
|
||||
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>
|
||||
<template>
|
||||
<VueJsonViewer :value="jsonToShow" v-bind="bindProps">
|
||||
<VueJsonViewer v-bind="bindProps">
|
||||
<template #copy="slotProps">
|
||||
<slot name="copy" v-bind="slotProps"></slot>
|
||||
</template>
|
||||
|
@@ -1,4 +1,6 @@
|
||||
export interface JsonViewerProps {
|
||||
/** 要展示的结构数据 */
|
||||
value: any;
|
||||
/** 展开深度 */
|
||||
expandDepth?: number;
|
||||
/** 是否可复制 */
|
||||
@@ -19,6 +21,24 @@ export interface JsonViewerProps {
|
||||
showArrayIndex?: 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user