houzhongjian
2024-07-11 759b1c71011abd6b58c37d2566f3f3c208c2f1b2
提交 | 用户 | 时间
759b1c 1 <template>
H 2   <div>
3     <el-drawer v-bind="$attrs" v-on="$listeners" @opened="onOpen" @close="onClose">
4       <div class="action-bar" :style="{'text-align': 'left'}">
5         <span class="bar-btn" @click="refresh">
6           <i class="el-icon-refresh" />
7           刷新
8         </span>
9         <span ref="copyBtn" class="bar-btn copy-json-btn">
10           <i class="el-icon-document-copy" />
11           复制JSON
12         </span>
13         <span class="bar-btn" @click="exportJsonFile">
14           <i class="el-icon-download" />
15           导出JSON文件
16         </span>
17         <span class="bar-btn delete-btn" @click="$emit('update:visible', false)">
18           <i class="el-icon-circle-close" />
19           关闭
20         </span>
21       </div>
22       <div id="editorJson" class="json-editor" />
23     </el-drawer>
24   </div>
25 </template>
26
27 <script>
28 import { beautifierConf } from '@/utils'
29 import ClipboardJS from 'clipboard'
30 import { saveAs } from 'file-saver'
31 import loadMonaco from '@/utils/loadMonaco'
32 import loadBeautifier from '@/utils/loadBeautifier'
33
34 let beautifier
35 let monaco
36
37 export default {
38   components: {},
39   props: {
40     jsonStr: {
41       type: String,
42       required: true
43     }
44   },
45   data() {
46     return {}
47   },
48   computed: {},
49   watch: {},
50   created() {},
51   mounted() {
52     window.addEventListener('keydown', this.preventDefaultSave)
53     const clipboard = new ClipboardJS('.copy-json-btn', {
54       text: trigger => {
55         this.$notify({
56           title: '成功',
57           message: '代码已复制到剪切板,可粘贴。',
58           type: 'success'
59         })
60         return this.beautifierJson
61       }
62     })
63     clipboard.on('error', e => {
64       this.$message.error('代码复制失败')
65     })
66   },
67   beforeDestroy() {
68     window.removeEventListener('keydown', this.preventDefaultSave)
69   },
70   methods: {
71     preventDefaultSave(e) {
72       if (e.key === 's' && (e.metaKey || e.ctrlKey)) {
73         e.preventDefault()
74       }
75     },
76     onOpen() {
77       loadBeautifier(btf => {
78         beautifier = btf
79         this.beautifierJson = beautifier.js(this.jsonStr, beautifierConf.js)
80
81         loadMonaco(val => {
82           monaco = val
83           this.setEditorValue('editorJson', this.beautifierJson)
84         })
85       })
86     },
87     onClose() {},
88     setEditorValue(id, codeStr) {
89       if (this.jsonEditor) {
90         this.jsonEditor.setValue(codeStr)
91       } else {
92         this.jsonEditor = monaco.editor.create(document.getElementById(id), {
93           value: codeStr,
94           theme: 'vs-dark',
95           language: 'json',
96           automaticLayout: true
97         })
98         // ctrl + s 刷新
99         this.jsonEditor.onKeyDown(e => {
100           if (e.keyCode === 49 && (e.metaKey || e.ctrlKey)) {
101             this.refresh()
102           }
103         })
104       }
105     },
106     exportJsonFile() {
107       this.$prompt('文件名:', '导出文件', {
108         inputValue: `${+new Date()}.json`,
109         closeOnClickModal: false,
110         inputPlaceholder: '请输入文件名'
111       }).then(({ value }) => {
112         if (!value) value = `${+new Date()}.json`
113         const codeStr = this.jsonEditor.getValue()
114         const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
115         saveAs(blob, value)
116       })
117     },
118     refresh() {
119       try {
120         this.$emit('refresh', JSON.parse(this.jsonEditor.getValue()))
121       } catch (error) {
122         this.$notify({
123           title: '错误',
124           message: 'JSON格式错误,请检查',
125           type: 'error'
126         })
127       }
128     }
129   }
130 }
131 </script>
132
133 <style lang="scss" scoped>
134 @import '@/styles/mixin.scss';
135
136 :deep(.el-drawer__header) {
137   display: none;
138 }
139 @include action-bar;
140
141 .json-editor{
142   height: calc(100vh - 33px);
143 }
144 </style>