使用JSONPretty组件库,
配置
| 属性 | 说明 | 类型 | 默认值 |
|---|
| data | 待美化的源数据,注意不是 JSON 字符串 | JSON 对象 | - |
| deep | 数据深度, 大于该深度的数据将不被展开 | number | Infinity |
| showLength | 是否在数据线闭合的时候展示长度 | boolean | false |
| showLine | 是否显示缩紧标识线 | boolean | true |
| showDoubleQuotes | 是否展示key名的双引号 | boolean | true |
| highlightMouseoverNode | 是否在mouseover的时候高亮 | boolean | false |
| v-model | 双向绑定选中的数据层级 | string, array | -, [] |
| path | 定义最顶层数据层级 | string | root |
| pathChecked | 定义哪些数据层级是已被选中的 | array | [] |
| pathSelectable | 定义哪些数据层级是可以被选中的,返回true或false | Function(itemPath, itemData) | - |
| selectableType | 定义组件支持的选中方式,默认无选中功能 | enum: -, multiple, single | - |
| showSelectController | 是否展示选择控制器 | boolean | false |
| selectOnClickNode | 是否在点击节点的时候触发v-model双向绑定 | boolean | true |
| highlightSelectedNode | 是否高亮已选项 | boolean | true |
| customValueFormatter | 可以进行值的自定义渲染 | Function(data, key, parent, defaultFormatted) | - |
Events
| 事件名 | 说明 | 回调参数 |
|---|
| click | 点击某一个数据层级时触发的事件 | (path, data) |
| change | v-model改变的事件(仅在选择模式下可用) | (newVal, oldVal) |
父子组件
<div>
<el-dialog title="配置缓存明细" :visible.sync="dialogShow" :before-close="close" width="700px">
<div class="log-dialog">
<div class="container">
<div class="item first"><span class="title">缓存键:</span>
<div @click="onSync"><span style="font-weight: 600;">{{ params.key }}</span><a href="#" style="color: #4598F0;">
[同步]</a></div>
</div>
<div class="item"><span class="title">缓存值:</span>
<jsonView :config="config" :width="503"></jsonView>
</div>
</div>
<div class="bottom">
<button class="copy" @click="copy">复制</button>
<button class="back" @click="close">返回</button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import jsonView from "./jsonView.vue"
export default {
props: {
// 弹窗是否开启
value: {
type: Boolean,
default: () => false
},
configParams: {
type: Object,
default: () => {}
},
},
data() {
return {
config:{},
configData:{},
dialogShow:false,
params:{
key:'',
configPath: ''
},
}
},
created() {
},
components: {
jsonView,
},
methods: {
//获取配置明细
getConfigDetal() {
console.log("配置明细:", this.params)
this.$api.getConfigDetail(this.params).then(({data})=>{
console.log('配置明细data',data)
this.configData=data
this.config=JSON.parse(data.config)
}).catch(() => {
})
},
//同步事件
onSync() {
console.log("同步:", this.params)
this.$api.getConfigSync(this.params).then((data) => {
console.log('同步数据data', data)
if(data.success){
this.$message({
message: "同步成功!",
type: "success"
})
this.list=[]
this.getConfigDetal()
}
}).catch(() => {
})
},
close() {
this.dialogShow = false
this.config={}
this.$emit("on-cancel")
},
//复制
copy() {
navigator.clipboard.writeText(JSON.stringify(this.config));
this.$message({
message: '复制成功',
type: 'success'
});
}
},
watch: {
value: {
handler(val) {
this.dialogShow = val
}
},
configParams: {
handler(val){
console.log(val)
this.params.key = val.key
this.params.configPath=val.configPath
this.getConfigDetal()
}
}
}
}
</script>
<style lang="less" scoped>
.log-dialog {
.container {
font-size: 14px;
.item {
display: flex;
align-items: flex-start;
gap: 16px;
flex: 1 0 0;
.title {
width: 100px;
display: inline-block;
text-align: right;
}
}
.first {
margin-bottom: 24px;
}
.pre {
display: block;
position: relative;
font-size: 12px;
text-align: left;
word-break: break-all;
word-wrap: break-word;
.json-dict {
list-style-type: none;
margin: 0 0 0 1px;
border-left: 1px dotted #ccc;
padding-left: 2em;
li {
color: #333;
font-feature-settings: 'clig' off, 'liga' off;
font-family: Roboto Mono;
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px;
.json-string {
color: #0B7500;
}
}
}
.jiantou {
position: absolute;
width: 7px;
height: 7px;
left: 9px;
top: 20px;
cursor: pointer;
}
.pick-up {
color: #999;
padding: 0 10px;
}
}
}
.bottom {
padding: 16px 0px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10px;
align-self: stretch;
.copy {
padding: 8px 16px;
font-size: 13px;
border-radius: 4px;
border: 1px solid var(---nc8, #D7DEE3);
background: #fff;
color: black;
cursor: pointer;
&:hover {
background-color: #f4f6fa;
color: black;
}
&:active {
background-color: #D7DEE3;
color: black;
}
}
.back {
border: none;
padding: 8px 16px;
font-size: 13px;
color: white;
border-radius: 4px;
background: var(---blue1-, #4598F0);
cursor: pointer;
&:hover {
opacity: 0.8;
}
&:active {
background: var(---blue1-, #418cdb);
}
}
}
}</style>
子组件
<div class="main">
<div v-if="Object.keys(config).length===0">配置未同步</div>
<JSONPretty
v-else
:data="config"
:deep="deep"
:show-select-controller="true"
:show-length="true"
:showIcon="true"
:virtual="true"
></JSONPretty>
</div>
</template>
<script>
import JSONPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';
export default {
props:{
config:{
type: Object,
default: ()=>{}
},
},
data() {
return {
deep:2, //展开深度
}
},
components: {
JSONPretty
},
}
</script >
<style lang="less" scoped>
.main{
width: 503px;
padding: 11px 11px 11px 11px;
color: #333333;
background-color: #eaeef0;
border: 1px solid #cbd6d6;
border-radius: 4px;
}
/deep/.vjs-tree-node .vjs-indent-unit.has-line{
border-left: 1px dotted #ccc;
}
/deep/.vjs-value-string{
color: #0B7500;
}
/deep/.vjs-value-number,.vjs-value-boolean{
color: blue;
}
/deep/.vjs-value-boolean{
color: blue;
}
/deep/.vjs-tree-node.has-carets.has-selector, .vjs-tree-node.has-selector{
padding-left: 12px;
}
</style>