瀏覽代碼

添加JSO/XML格式化功能

lighter 3 年之前
父節點
當前提交
a57e654551
共有 2 個文件被更改,包括 199 次插入0 次删除
  1. 13 0
      src/router/modules/dashboard.js
  2. 186 0
      src/views/utilities/ParseJson.vue

+ 13 - 0
src/router/modules/dashboard.js

@@ -478,6 +478,19 @@ const route = [
       },
     ],
   },
+
+  {
+    path: '/utilities',
+    component: Layout,
+    meta: { title: '通用工具', icon: 'iconfont icon-tool' },
+    children: [
+      {
+        path: 'parseJson',
+        component: createNameComponent(() => import('@/views/utilities/ParseJson.vue')),
+        meta: { title: 'JSON格式化', icon: 'iconfont icon-fasongtongzhi' },
+      },
+    ],
+  },
 ]
 
 export default route

+ 186 - 0
src/views/utilities/ParseJson.vue

@@ -0,0 +1,186 @@
+<template>
+  <el-container>
+    <el-main>
+      <el-row :gutter="5">
+        <el-col :span="2">
+          <div style="height: 30px"></div>
+          <div style="padding: 4px">
+            <el-checkbox v-model="clearWhenChangeType">
+              <div>更换类型时</div>
+              <div>清空文本</div>
+            </el-checkbox>
+          </div>
+          <div style="height: 10px"></div>
+          <div style="padding: 4px"><el-radio v-model="type" label="JSON" @change="onTypeChange">JSON</el-radio></div>
+          <div style="padding: 4px"><el-radio v-model="type" label="XML" @change="onTypeChange">XML</el-radio></div>
+        </el-col>
+        <el-col :span="8">
+          <pre :style="preStyle" class="formatted-body">
+              <el-input v-model="originContent" type="textarea" rows="30" :placeholder="placeholder" @input="executeFormat"></el-input>
+          </pre>
+        </el-col>
+        <el-col :span="14">
+          <pre :style="[preStyle, resultBackGround]" class="formatted-result">{{ formattedResult }}</pre>
+        </el-col>
+      </el-row>
+    </el-main>
+  </el-container>
+</template>
+
+<script>
+import { computed, ref } from 'vue'
+import { useStore } from 'vuex'
+
+export default {
+  setup() {
+    const store = useStore()
+    const windowSize = store.state.app.windowSize
+
+    const clearWhenChangeType = ref(false)
+    const type = ref('JSON')
+
+    const placeholder = computed(() => {
+      return `把要格式化的${type.value}字符串放在这里...`
+    })
+
+    const preStyle = {
+      width: '92%',
+      height: windowSize.h - 50 + 'px',
+      overflowY: 'auto',
+    }
+
+    const onTypeChange = () => {
+      if (clearWhenChangeType.value) {
+        originContent.value = null
+        formattedResult.value = null
+      } else {
+        executeFormat()
+      }
+    }
+
+    const originContent = ref(null)
+    const formattedResult = ref(null)
+    const trueJson = ref(true)
+    const resultBackGround = computed(() => {
+      return {
+        background: trueJson.value ? '#90da6b7a' : '#f3818186',
+      }
+    })
+
+    const formatXml = () => {
+      let text = originContent.value
+      text =
+        '\n' +
+        text
+          .replace(/(<\w+)(\s.*?>)/g, function ($0, name, props) {
+            return name + ' ' + props.replace(/\s+(\w+=)/g, ' $1')
+          })
+          .replace(/>\s*?</g, '>\n<')
+      text = text
+        .replace(/\n/g, '\r')
+        .replace(/<!--(.+?)-->/g, function ($0, text) {
+          var ret = '<!--' + escape(text) + '-->'
+          return ret
+        })
+        .replace(/\r/g, '\n')
+      var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/gm
+      var nodeStack = []
+      var output = text.replace(rgx, function ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) {
+        var isClosed = isCloseFull1 == '/' || isCloseFull2 == '/' || isFull1 == '/' || isFull2 == '/'
+        var prefix = ''
+        if (isBegin == '!') {
+          //!开头
+          prefix = setPrefix(nodeStack.length)
+        } else {
+          if (isBegin != '/') {
+            ///开头
+            prefix = setPrefix(nodeStack.length)
+            if (!isClosed) {
+              //非关闭标签
+              nodeStack.push(name)
+            }
+          } else {
+            nodeStack.pop() //弹栈
+            prefix = setPrefix(nodeStack.length)
+          }
+        }
+        var ret = '\n' + prefix + all
+        return ret
+      })
+      var outputText = output.substring(1)
+      //还原注释内容
+      outputText = outputText.replace(/\n/g, '\r').replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
+        if (prefix.charAt(0) == '\r') prefix = prefix.substring(1)
+        text = unescape(text).replace(/\r/g, '\n')
+        var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/gm, prefix) + '-->'
+        return ret
+      })
+      outputText = outputText.replace(/\s+$/g, '').replace(/\r/g, '\r\n')
+      return outputText
+    }
+
+    //计算头函数 用来缩进
+    const setPrefix = (prefixIndex) => {
+      var result = ''
+      var span = '   ' //缩进长度
+      var output = []
+      for (var i = 0; i < prefixIndex; ++i) {
+        output.push(span)
+      }
+      result = output.join('')
+      return result
+    }
+
+    const executeFormat = () => {
+      if (!originContent.value) {
+        return
+      }
+      try {
+        if (type.value === 'JSON') {
+          formattedResult.value = JSON.stringify(JSON.parse(originContent.value), null, 2)
+          trueJson.value = true
+        } else {
+          if (originContent.value.indexOf('<') === -1 || originContent.value.indexOf('</') === -1 || originContent.value.indexOf('>') === -1) {
+            formattedResult.value = '不正确的XML文本'
+            trueJson.value = false
+          } else {
+            formattedResult.value = formatXml()
+            trueJson.value = true
+          }
+        }
+      } catch (error) {
+        formattedResult.value = error
+        trueJson.value = false
+      }
+    }
+
+    return {
+      type,
+      preStyle,
+      placeholder,
+      clearWhenChangeType,
+      originContent,
+      formattedResult,
+      resultBackGround,
+      onTypeChange,
+      executeFormat,
+    }
+  },
+}
+</script>
+
+<style scoped>
+pre {
+  white-space: pre-wrap;
+  word-wrap: break-word;
+}
+.formatted-body {
+  background: #60a6ec8a;
+  border-radius: 8px;
+  padding: 10px;
+}
+.formatted-result {
+  border-radius: 8px;
+  padding: 10px;
+}
+</style>