tool.xpcool.com/src/views/yaml-json/YamlJsonView.vue

121 lines
3.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
YAML JSON 转换工具基于 js-yaml 在浏览器本地完成 YAML JSON 互转内容不上传
-->
<template>
<div class="page-wrap">
<h2 class="page-title">YAML JSON 转换</h2>
<p class="page-desc">YAML JSON 格式互转全部在浏览器本地完成内容不会上传</p>
<!-- YAML 隐式类型解析提示未加引号的日期/数字字符串可能被解析为对应类型 -->
<t-alert
class="tip-alert"
theme="warning"
message="提示YAML 解析可能将未加引号的日期或数字字符串解析为日期/数字类型,若有歧义建议给字符串加引号。"
/>
<t-card class="tool-section" title="转换">
<t-radio-group v-model="direction" variant="default-filled">
<t-radio-button value="y2j">YAML → JSON</t-radio-button>
<t-radio-button value="j2y">JSON → YAML</t-radio-button>
</t-radio-group>
<t-textarea
v-model="input"
class="input-area"
:placeholder="placeholder"
:autosize="{ minRows: 8, maxRows: 16 }"
/>
<div class="form-actions">
<t-button theme="primary" @click="convert">转换</t-button>
</div>
</t-card>
<ErrorAlert :message="error" @close="error = ''" />
<t-card v-if="output" class="tool-section" title="转换结果">
<t-textarea v-model="output" :autosize="{ minRows: 6, maxRows: 16 }" readonly />
<div class="form-actions">
<CopyButton :text="output" />
</div>
</t-card>
<HistoryPanel
:items="history.items"
@select="onHistorySelect"
@remove="history.remove"
@clear="history.clear"
/>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { load, dump } from 'js-yaml'
import ErrorAlert from '@/components/common/ErrorAlert.vue'
import CopyButton from '@/components/common/CopyButton.vue'
import HistoryPanel from '@/components/common/HistoryPanel.vue'
import { useHistory } from '@/composables/useHistory'
type Direction = 'y2j' | 'j2y'
const direction = ref<Direction>('y2j')
const input = ref('')
const output = ref('')
const error = ref('')
const history = useHistory('yaml-json')
// 占位提示随方向切换,放在脚本中避免模板内多行表达式
const placeholder = computed(() =>
direction.value === 'y2j'
? '输入 YAML 内容,例如:\nname: 张三\nage: 18'
: '输入 JSON 内容,例如:\n{ "name": "张三", "age": 18 }',
)
function convert() {
error.value = ''
output.value = ''
const text = input.value.trim()
if (!text) {
error.value = '请输入要转换的内容'
return
}
try {
if (direction.value === 'y2j') {
// load 返回 unknown空文档会返回 undefined此时按解析失败处理
const data = load(text)
if (data === undefined) {
error.value = 'YAML 内容为空或无法解析'
return
}
output.value = JSON.stringify(data, null, 2)
} else {
output.value = dump(JSON.parse(text))
}
// 历史只保留前 300 字符,避免长文本撑爆 localStorage
history.add(input.value.slice(0, 300))
} catch (e) {
error.value = `转换失败:${(e as Error).message}`
}
}
function onHistorySelect(text: string) {
input.value = text
convert()
}
</script>
<style scoped>
.input-area {
margin-top: 12px;
}
.form-actions {
display: flex;
gap: 8px;
margin-top: 16px;
flex-wrap: wrap;
}
.tip-alert {
margin-bottom: 12px;
}
</style>