<!-- * @FileDescription: JSON 对象 预览组件 * @Date: 2023-05-29 * @LastEditTime: 2023-05-29 --> <script setup lang="ts"> import { ref } from 'vue'; import ArrView from './ArrView.vue'; import HtmlView from './HtmlView.vue'; import { isArray, isLastObj, isLastArr, isObject } from '../utils'; interface IDetailProps { data: any; isLast?: boolean; nest?: boolean; mainColor?: string; objSideColor?: string; arrSideColor?: string; stringColor?: string; numberColor?: string; booleanColor?: string; nullColor?: string; otherColor?: string; } const props = withDefaults(defineProps<IDetailProps>(), { data: () => { return {}; }, isLast: true, nest: false, }); const show = ref(true); function clickStart() { show.value = !show.value; } </script> <template> <div style="font-family: 'Gill Sans', sans-serif; position: relative" :style="{ paddingLeft: props.nest ? '16px' : 0 }" > <div :style="{ color: objSideColor }" class="obj-side-start"> <q-icon :name="show ? 'bi-dash-square' : 'bi-plus-square'" @click="clickStart" class="icon-action" /> { </div> <div class="json-fa" v-show="show"> <template v-for="(item, key1, index) in props.data" :key="key1"> <div v-if="isArray(item) && item.length > 0"> <div :style="{ color: mainColor }">"{{ key1 }}":</div> <arr-view v-bind="props" :data="item" :is-last="isLastArr(index, props.data)" class="childrens" /> </div> <div v-else-if="isObject(item) && Object.keys(item).length > 0"> <div :style="{ color: mainColor }">"{{ key1 }}":</div> <obj-view v-bind="props" :data="item" :is-last="isLastObj(index, props.data)" :nest="true" /> </div> <div v-else> <span :style="{ color: mainColor }"> "{{ key1 }}" : </span> <html-view v-bind="props" :data="item" :is-last="isLastObj(index, props.data)" /> </div> </template> </div> <div v-show="!show" class="hide-text" :style="{ color: objSideColor, left: props.nest ? '48px' : '32px' }" > ... </div> <div class="obj-side-end" v-show="show"> <span :style="{ color: objSideColor }">}</span> <span v-if="!props.isLast" :style="{ color: mainColor }"> ,</span> </div> </div> </template> <style lang="scss" scoped> .json-fa { padding-left: 16px; } .childrens { padding-left: 16px; } .obj-side-start { // padding: 0 8px; .icon-action { &:hover { cursor: pointer; } } } .obj-side-end { // padding: 0 8px; } .hide-text { position: absolute; top: 0; &::after { position: absolute; content: '}'; right: -8px; } } </style>