index.vue 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <script lang="ts" setup>
  2. import type { SetupContext } from 'vue';
  3. import type { Recordable } from '@vben/types';
  4. import type {
  5. JsonViewerAction,
  6. JsonViewerProps,
  7. JsonViewerToggle,
  8. JsonViewerValue,
  9. } from './types';
  10. import { computed, useAttrs } from 'vue';
  11. // @ts-ignore
  12. import VueJsonViewer from 'vue-json-viewer';
  13. import { $t } from '@vben/locales';
  14. import { isBoolean } from '@vben-core/shared/utils';
  15. defineOptions({ name: 'JsonViewer' });
  16. const props = withDefaults(defineProps<JsonViewerProps>(), {
  17. expandDepth: 1,
  18. copyable: false,
  19. sort: false,
  20. boxed: false,
  21. theme: 'default-json-theme',
  22. expanded: false,
  23. previewMode: false,
  24. showArrayIndex: true,
  25. showDoubleQuotes: false,
  26. });
  27. const emit = defineEmits<{
  28. click: [event: MouseEvent];
  29. copied: [event: JsonViewerAction];
  30. keyClick: [key: string];
  31. toggle: [param: JsonViewerToggle];
  32. valueClick: [value: JsonViewerValue];
  33. }>();
  34. const attrs: SetupContext['attrs'] = useAttrs();
  35. function handleClick(event: MouseEvent) {
  36. if (
  37. event.target instanceof HTMLElement &&
  38. event.target.classList.contains('jv-item')
  39. ) {
  40. const pathNode = event.target.closest('.jv-push');
  41. if (!pathNode || !pathNode.hasAttribute('path')) {
  42. return;
  43. }
  44. const param: JsonViewerValue = {
  45. path: '',
  46. value: '',
  47. depth: 0,
  48. el: event.target,
  49. };
  50. param.path = pathNode.getAttribute('path') || '';
  51. param.depth = Number(pathNode.getAttribute('depth')) || 0;
  52. param.value = event.target.textContent || undefined;
  53. param.value = JSON.parse(param.value);
  54. emit('valueClick', param);
  55. }
  56. emit('click', event);
  57. }
  58. const bindProps = computed<Recordable<any>>(() => {
  59. const copyable = {
  60. copyText: $t('ui.jsonViewer.copy'),
  61. copiedText: $t('ui.jsonViewer.copied'),
  62. timeout: 2000,
  63. ...(isBoolean(props.copyable) ? {} : props.copyable),
  64. };
  65. return {
  66. ...props,
  67. ...attrs,
  68. onCopied: (event: JsonViewerAction) => emit('copied', event),
  69. onKeyclick: (key: string) => emit('keyClick', key),
  70. onClick: (event: MouseEvent) => handleClick(event),
  71. copyable: props.copyable ? copyable : false,
  72. };
  73. });
  74. </script>
  75. <template>
  76. <VueJsonViewer v-bind="bindProps">
  77. <template #copy="slotProps">
  78. <slot name="copy" v-bind="slotProps"></slot>
  79. </template>
  80. </VueJsonViewer>
  81. </template>
  82. <style lang="scss">
  83. @use './style.scss';
  84. </style>