4 个回答

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .json-view {font-family:Consolas, monospace;}
    .json-view .tpl {display:none;}

    .json-view .k {color:#369;}
    .json-view .k:empty ~ .colon {display:none;}

    .json-view .json-boolean .v {color:#993;}
    .json-view .json-number .v {color:#939;}
    .json-view .json-bigint .v {color:#939;}
    .json-view .json-string .v {color:#393;}
    .json-view .json-null .v {color:#CCC;}

    .json-view a {display:block;}
    .json-view a > .tag-open:before {content:'[+]';margin-right:0.5em;color:#399}
    .json-view a > .tag-ddd {}
    .json-view a > .content {display:none;margin-left:1em;}
    .json-view a.open > .tag-open:before {content:'[-]';color:#F33;}
    .json-view a.open > .tag-ddd {display:none;}
    .json-view a.open > .content {display:block;}

    .json-view a:last-child > .comma {display:none}
    .json-view a .content :last-child > .comma {display:none}
    </style>
    <script>
    document.addEventListener('DOMContentLoaded', function(){
        function json_view_create_value($domBase, $domTpl, $tplClass, $key, $v)
        {
            let domTpl, dom;
            domTpl = $domTpl.querySelector($tplClass);
            dom = domTpl.cloneNode(true);

            if(typeof($key) === 'string')
                dom.querySelector('.k').innerHTML = '"'+$key+'"';

            dom.querySelector('.v').innerHTML = $v;
            $domBase.appendChild(dom);
        }
        function json_view_boolean($domBase, $domTpl, $key, $v)
        {
            json_view_create_value($domBase, $domTpl, '.json-boolean', $key, $v ? 'true' : 'false');
        }
        function json_view_number($domBase, $domTpl, $key, $v)
        {
            json_view_create_value($domBase, $domTpl, '.json-number', $key, $v);
        }
        function json_view_bigint($domBase, $domTpl, $key, $v)
        {
            json_view_create_value($domBase, $domTpl, '.json-number', $key, $v);
        }
        function json_view_string($domBase, $domTpl, $key, $v)
        {
            json_view_create_value($domBase, $domTpl, '.json-string', $key, '"'+$v+'"');
        }
        function json_view_null($domBase, $domTpl, $key, $v)
        {
            json_view_create_value($domBase, $domTpl, '.json-null', $key, 'null');
        }
        function json_view_array($domBase, $domTpl, $key, $arr)
        {
            let domTpl, dom;
            domTpl = $domTpl.querySelector('.json-array');
            dom = domTpl.cloneNode(true);

            if(typeof($key) === 'string')
                dom.querySelector('.k').innerHTML = '"'+$key+'"';

            dom.addEventListener('click', function($evt){
                if($evt.target.classList.contains('tag-ac') === false)
                    return;
                
                let domContent = dom.querySelector(':scope > .content');
                if(this.classList.contains('open') === true)
                {
                    this.classList.remove('open');
                }
                else
                {
                    if(domContent.classList.contains('none') === true)
                    {
                        if(typeof($key) === 'string')
                            dom.querySelector('.k').innerHTML = '"'+$key+'"';

                        domContent.classList.remove('none');
                        for(let i=0; i<$arr.length; i++)
                        {
                            json_view(domContent, $domTpl, null, $arr[i]);
                        }
                    }
                    this.classList.add('open');
                }

                $evt.stopPropagation();
            });
            $domBase.appendChild(dom);
        }
        function json_view_object($domBase, $domTpl, $key, $ob)
        {
            let domTpl, dom;
            domTpl = $domTpl.querySelector('.json-object');
            dom = domTpl.cloneNode(true);

            if(typeof($key) === 'string')
                dom.querySelector('.k').innerHTML = '"'+$key+'"';

            dom.addEventListener('click', function($evt){
                if($evt.target.classList.contains('tag-ac') === false)
                    return;

                let domContent = dom.querySelector(':scope > .content');
                if(this.classList.contains('open') === true)
                {
                    this.classList.remove('open');
                }
                else
                {
                    if(domContent.classList.contains('none') === true)
                    {
                        if(typeof($key) === 'string')
                            dom.querySelector('.k').innerHTML = '"'+$key+'"';

                        domContent.classList.remove('none');
                        for(let key in $ob)
                        {
                            json_view(domContent, $domTpl, key, $ob[key]);
                        }
                    }
                    this.classList.add('open');
                }

                $evt.stopPropagation();
            });
            $domBase.appendChild(dom);
        }
        function json_view($domBase, $domTpl, $key, $json)
        {
            let mapView = {
                'boolean' : json_view_boolean,
                'number' : json_view_number,
                'bigint' : json_view_bigint,
                'string' : json_view_string,
                'null' : json_view_null,
                'array' : json_view_array,
                'object' : json_view_object,
            };

            let type = typeof($json);
            if(type === 'object')
            {
                if($json === null) type = 'null';
                else if(Array.isArray($json) === true) type = 'array';
            }

            if(type in mapView === false)
                throw 'invalid type ['+type+']';

            mapView[type]($domBase, $domTpl, $key, $json);
        }

        let json = {
            'null' : null,
            'number' : 123,
            'string' : 'abc',
            'array' : [null, 123, 'abc', false, {
                'null' : null,
                'number' : 123,
                'string' : 'abc',
            }],
            'object' : {
                'boolean' : true,
            },
        };
        let domRoot = document.querySelector('.json-view .json-root');
        let domTpl  = document.querySelector('.json-view .tpl');
        json_view(domRoot, domTpl, null, json);
    });
    </script>
</head>
<body>
<div class="json-view">
    <div class="json-root"></div>
    <div class="tpl">
        <div class="json-boolean">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="v"></span>
            <span class="comma">,</span>
        </div>
        <div class="json-number">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="v"></span>
            <span class="comma">,</span>
        </div>
        <div class="json-bigint">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="v"></span>
            <span class="comma">,</span>
        </div>
        <div class="json-string">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="v"></span>
            <span class="comma">,</span>
        </div>
        <div class="json-null">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="v"></span>
            <span class="comma">,</span>
        </div>
        <a class="json-array">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="tag-ac tag-open">[</span><span class="tag-ac tag-ddd">...</span><div class="content none"></div><span class="tag-ac tag-close">]</span>
            <span class="comma">,</span>
        </a>
        <a class="json-object">
            <span class="k"></span>
            <span class="colon">:</span>
            <span class="tag-ac tag-open">{</span><span class="tag-ac tag-ddd">...</span><div class="content none"></div><span class="tag-ac tag-close">}</span>
            <span class="comma">,</span>
        </a>
    </div>
</div>
</body>
</html>

不折叠

如果你只需要格式化展示并且不需要折叠,那么可以直接使用<pre>标签来展示json字符串,但是单单使用这个还不行,你还需要把你格式化的字符串做处理。可能很多人知道JSON.stringify(str)可以格式化字符串,但是很多人不知道其实JSON.stringify(str, replacer, space),即它有三个参数,MDN;
所以代码如下:

<template>
  <div>
    <pre>{{ str }}</pre>
  </div>
</template>
<script>
export default {
  data() {
    return {
      str: "",
    };
  },
  mounted() {
    let obj = {
      name: "张三",
      age: 18,
      gender: "男",
      child: [{ name: "张三", age: 18, gender: "男" }],
    };
    this.str = JSON.stringify(obj, null, 2);
  },
};
</script>

可折叠

但是可折叠却无法实现,当然它肯定是可以实现的,但是很麻烦而且你还需要做适配什么的,所以可以选择插件vue-json-viewer

我不知道你是原生还是Vue还是react,如果是其他的话你可以搜一下。

新手上路,请多包涵

看你使用什么框架了。大概率是 React 或者 Vue

推荐问题
宣传栏