增加 xml <=> 编解码工具
This commit is contained in:
4
src/renderer/components.d.ts
vendored
4
src/renderer/components.d.ts
vendored
@@ -11,11 +11,11 @@ export {}
|
|||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
CoderBaseCard: typeof import('./src/components/CoderBaseCard.vue')['default']
|
||||||
CoderJson: typeof import('./src/components/CoderJson.vue')['default']
|
CoderJson: typeof import('./src/components/CoderJson.vue')['default']
|
||||||
|
CoderXml: typeof import('./src/components/CoderXml.vue')['default']
|
||||||
DetectedIDECard: typeof import('./src/components/DetectedIDECard.vue')['default']
|
DetectedIDECard: typeof import('./src/components/DetectedIDECard.vue')['default']
|
||||||
DetectedIDECardList: typeof import('./src/components/DetectedIDECardList.vue')['default']
|
DetectedIDECardList: typeof import('./src/components/DetectedIDECardList.vue')['default']
|
||||||
DetectedIDEVersionCard: typeof import('./src/components/DetectedIDEVersionCard.vue')['default']
|
|
||||||
DetectedIDEVersionCardList: typeof import('./src/components/DetectedIDEVersionCardList.vue')['default']
|
|
||||||
NAlert: typeof import('naive-ui')['NAlert']
|
NAlert: typeof import('naive-ui')['NAlert']
|
||||||
NButton: typeof import('naive-ui')['NButton']
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { darkTheme, dateZhCN, zhCN } from 'naive-ui'
|
|||||||
import hljs from 'highlight.js'
|
import hljs from 'highlight.js'
|
||||||
import javascript from 'highlight.js/lib/languages/javascript'
|
import javascript from 'highlight.js/lib/languages/javascript'
|
||||||
import json from 'highlight.js/lib/languages/json'
|
import json from 'highlight.js/lib/languages/json'
|
||||||
|
import xml from 'highlight.js/lib/languages/xml'
|
||||||
|
|
||||||
hljs.registerLanguage('javascript', javascript)
|
hljs.registerLanguage('javascript', javascript)
|
||||||
hljs.registerLanguage('json', json)
|
hljs.registerLanguage('json', json)
|
||||||
|
hljs.registerLanguage('xml', xml)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
104
src/renderer/src/components/CoderBaseCard.vue
Normal file
104
src/renderer/src/components/CoderBaseCard.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, onMounted, ref } from 'vue'
|
||||||
|
import { useMessage } from 'naive-ui'
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
cardTitle: string
|
||||||
|
defaultInput: string
|
||||||
|
// 人类友好格式的代码语言
|
||||||
|
codeLanguage1: 'json' | 'xml'
|
||||||
|
// 机器友好格式的代码语言
|
||||||
|
codeLanguage2: 'json' | 'xml'
|
||||||
|
// 转为人类友好格式
|
||||||
|
parser1: (input: string) => string
|
||||||
|
// 转为机器友好格式
|
||||||
|
parser2: (input: string) => string
|
||||||
|
// 转为人类友好格式别名
|
||||||
|
buttonText1?: string
|
||||||
|
// 转为机器友好格式别名
|
||||||
|
buttonText2?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const codingHumanFriendly = ref(true)
|
||||||
|
const inputValue = ref(props.defaultInput)
|
||||||
|
const displayValue = ref('')
|
||||||
|
const errorTip = ref('')
|
||||||
|
|
||||||
|
function generate(humanFriendly: boolean, showSuccessMessage: boolean = true): void {
|
||||||
|
try {
|
||||||
|
displayValue.value = humanFriendly
|
||||||
|
? props.parser1(inputValue.value)
|
||||||
|
: props.parser2(inputValue.value)
|
||||||
|
errorTip.value = ''
|
||||||
|
// 页面挂载时不显示成功提示
|
||||||
|
if (showSuccessMessage) {
|
||||||
|
message.success('没抱错,所以应该成功辽~')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
message.error(error.name)
|
||||||
|
displayValue.value = ''
|
||||||
|
errorTip.value = error.name + ': ' + error.message
|
||||||
|
} else {
|
||||||
|
// TODO 还有什么可能的错误?
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const codeLanguage = computed(() =>
|
||||||
|
codingHumanFriendly.value ? props.codeLanguage1 : props.codeLanguage2
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
generate(true, false)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-card class="default-card" :title="cardTitle">
|
||||||
|
<template #header-extra>
|
||||||
|
<n-flex align="center" justify="center">
|
||||||
|
<n-switch v-model:value="codingHumanFriendly" size="large">
|
||||||
|
<template #checked> {{ buttonText1 ? buttonText1 : '转换为人类友好格式' }} </template>
|
||||||
|
<template #unchecked> {{ buttonText2 ? buttonText2 : '转换为机器友好格式' }} </template>
|
||||||
|
</n-switch>
|
||||||
|
<n-button secondary type="primary" @click="() => generate(codingHumanFriendly)"
|
||||||
|
>生成</n-button
|
||||||
|
>
|
||||||
|
<n-button
|
||||||
|
secondary
|
||||||
|
type="warning"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
inputValue = defaultInput
|
||||||
|
codingHumanFriendly = true
|
||||||
|
generate(true)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>重置</n-button
|
||||||
|
>
|
||||||
|
<n-button secondary type="info">复制结果</n-button>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<n-flex vertical>
|
||||||
|
<n-input v-model:value="inputValue" spellcheck="false" type="textarea" />
|
||||||
|
<div class="scrollarea code-area">
|
||||||
|
<n-code :code="displayValue" :language="codeLanguage" />
|
||||||
|
</div>
|
||||||
|
<n-alert v-if="errorTip !== ''" type="error">
|
||||||
|
{{ errorTip }}
|
||||||
|
</n-alert>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div.code-area {
|
||||||
|
max-height: 600px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,77 +1,16 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue'
|
import CoderBaseCard from '@renderer/components/CoderBaseCard.vue'
|
||||||
import { useMessage } from 'naive-ui'
|
|
||||||
|
|
||||||
const message = useMessage()
|
|
||||||
|
|
||||||
const defaultInput =
|
|
||||||
'{"name":"Code Space","author":1,"url":"https://code.mangofanfan.cn","users":[{"name":"MangoFanFanw","age":18,"male":true}]}'
|
|
||||||
|
|
||||||
const codingHumanFriendly = ref(true)
|
|
||||||
const inputValue = ref(defaultInput)
|
|
||||||
const displayValue = ref('')
|
|
||||||
const errorTip = ref('')
|
|
||||||
|
|
||||||
function generate(humanFriendly: boolean): void {
|
|
||||||
try {
|
|
||||||
displayValue.value = JSON.stringify(JSON.parse(inputValue.value), null, humanFriendly ? 4 : 0)
|
|
||||||
errorTip.value = ''
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof SyntaxError) {
|
|
||||||
message.error('JSON 解析错误,请复制完整并检查是否合法。')
|
|
||||||
displayValue.value = ''
|
|
||||||
errorTip.value = error.message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
generate(true)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-card class="default-card" title="json 格式化/压缩">
|
<CoderBaseCard
|
||||||
<template #header-extra>
|
card-title="json 格式化/压缩"
|
||||||
<n-flex align="center" justify="center">
|
default-input='{"name":"Code Space","author":1,"url":"https://code.mangofanfan.cn","users":[{"name":"MangoFanFanw","age":18,"male":true}]}'
|
||||||
<n-switch v-model:value="codingHumanFriendly" size="large">
|
code-language1="json"
|
||||||
<template #checked> 转换为人类友好格式 </template>
|
code-language2="json"
|
||||||
<template #unchecked> 转换为机器友好格式 </template>
|
:parser1="(code: string) => JSON.stringify(JSON.parse(code), null, 4)"
|
||||||
</n-switch>
|
:parser2="(code: string) => JSON.stringify(JSON.parse(code), null, 0)"
|
||||||
<n-button secondary type="primary" @click="() => generate(codingHumanFriendly)"
|
/>
|
||||||
>生成</n-button
|
|
||||||
>
|
|
||||||
<n-button
|
|
||||||
secondary
|
|
||||||
type="warning"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
inputValue = defaultInput
|
|
||||||
codingHumanFriendly = true
|
|
||||||
generate(true)
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>重置</n-button
|
|
||||||
>
|
|
||||||
<n-button secondary type="info">复制结果</n-button>
|
|
||||||
</n-flex>
|
|
||||||
</template>
|
|
||||||
<template #default>
|
|
||||||
<n-flex vertical>
|
|
||||||
<n-input v-model:value="inputValue" spellcheck="false" type="textarea" />
|
|
||||||
<div class="scrollarea code-area">
|
|
||||||
<n-code :code="displayValue" language="json" />
|
|
||||||
</div>
|
|
||||||
<n-alert v-if="errorTip !== ''" type="error">
|
|
||||||
{{ errorTip }}
|
|
||||||
</n-alert>
|
|
||||||
</n-flex>
|
|
||||||
</template>
|
|
||||||
</n-card>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
div.code-area {
|
|
||||||
max-height: 600px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
30
src/renderer/src/components/CoderXml.vue
Normal file
30
src/renderer/src/components/CoderXml.vue
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import CoderBaseCard from '@renderer/components/CoderBaseCard.vue'
|
||||||
|
import { XMLBuilder, XMLParser } from 'fast-xml-parser'
|
||||||
|
|
||||||
|
const xmlParser = new XMLParser({ ignoreAttributes: false })
|
||||||
|
const xmlBuilder = new XMLBuilder({ format: true, indentBy: ' ', ignoreAttributes: false })
|
||||||
|
|
||||||
|
function parser1(code: string): string {
|
||||||
|
return JSON.stringify(xmlParser.parse(code), null, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
function parser2(code: string): string {
|
||||||
|
return xmlBuilder.build(JSON.parse(code))
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<CoderBaseCard
|
||||||
|
card-title="xml <=> json"
|
||||||
|
default-input='<?xml version="1.0" encoding="UTF-8"?><bookstore><book category="cooking"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book></bookstore>'
|
||||||
|
code-language1="json"
|
||||||
|
code-language2="xml"
|
||||||
|
:parser1
|
||||||
|
:parser2
|
||||||
|
button-text1="xml => json"
|
||||||
|
button-text2="json => xml"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import CoderJson from '@renderer/components/CoderJson.vue'
|
import CoderJson from '@renderer/components/CoderJson.vue'
|
||||||
|
import CoderXml from '@renderer/components/CoderXml.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -10,6 +11,7 @@ import CoderJson from '@renderer/components/CoderJson.vue'
|
|||||||
</n-alert>
|
</n-alert>
|
||||||
|
|
||||||
<CoderJson />
|
<CoderJson />
|
||||||
|
<CoderXml />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
Reference in New Issue
Block a user