You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS/NUXTJS项目中如何在textarea内高亮XML/JSON语法错误对应行

解决方案

你要实现的效果可以分两步完成:先获取语法错误的行号,再实现textarea区域的错误行高亮,以下是可直接落地的实现方案:


第一步:获取XML/JSON语法错误的行号

JSON错误行号获取

原生JSON.parse无法返回行位置,你可以替换为jsonlint-mod库,校验错误时会直接返回错误行、列信息:

  1. 安装依赖:npm i jsonlint-mod
  2. 替换原有校验逻辑:
import jsonlint from 'jsonlint-mod'

try {
  jsonlint.parse(inputJSON)
  // 校验通过后的业务逻辑
} catch (e) {
  const errLine = e.line // 错误行号
  const errCol = e.column // 错误列号
  const message = `Provided JSON is syntactically incorrect. Error at line ${errLine}: ${e.message}`
  console.log(message)
}

XML错误行号获取

你在用的fast-xml-parser本身就支持返回错误位置,只要开启includeLocations配置即可:

import { XMLValidator } from 'fast-xml-parser'

const validationResult = XMLValidator.validate(inputXML, {
  includeLocations: true // 开启位置信息返回
})
if (validationResult !== true) {
  const errLine = validationResult.err.lineNumber // 错误行号
  const errCol = validationResult.err.colNumber // 错误列号
  const message = `Provided XML is syntactically incorrect. Error at line ${errLine}: ${validationResult.err.msg}`
  console.log(message)
  return
}

第二步:实现textarea错误行高亮

原生textarea不支持局部内容样式自定义,有两种成熟方案可以选:

方案1:轻量自定义封装(无额外编辑器依赖)

原理是在透明的原生textarea下方叠加一个等高的背景容器,渲染每行内容和错误高亮样式,和你原有输入逻辑完全兼容,Vue/Nuxt下的示例代码如下:

<template>
  <div class="code-editor-wrap">
    <!-- 背景层:渲染行号和错误高亮 -->
    <div class="code-bg" aria-hidden="true">
      <div 
        v-for="(line, idx) in contentLines" 
        :key="idx"
        class="code-line"
        :class="{ 'error-line': idx + 1 === currentErrorLine }"
      >
        <span class="line-num">{{ idx + 1 }}</span>
        <span class="line-content">{{ line }}</span>
      </div>
    </div>
    <!-- 原生输入层:透明覆盖在背景上方 -->
    <textarea
      v-model="inputContent"
      class="code-textarea"
      @input="clearError"
      rows="15"
    ></textarea>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
const inputContent = ref('')
const currentErrorLine = ref(0) // 校验完成后把错误行号赋值给这个变量即可触发高亮

const contentLines = computed(() => inputContent.value.split('\n'))
const clearError = () => currentErrorLine.value = 0
</script>

<style scoped>
.code-editor-wrap {
  position: relative;
  border: 1px solid #eee;
  border-radius: 4px;
  font-family: monospace;
  font-size: 14px;
}
.code-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 8px 0;
  background: #fff;
}
.code-line {
  display: flex;
  padding: 0 8px;
  line-height: 22px;
}
.line-num {
  width: 40px;
  color: #999;
  text-align: right;
  padding-right: 12px;
  user-select: none;
}
.error-line {
  background: #fee2e2; /* 错误行高亮颜色,可自定义 */
}
.code-textarea {
  position: relative;
  z-index: 1;
  width: 100%;
  padding: 8px 8px 8px 60px;
  border: none;
  outline: none;
  background: transparent;
  color: transparent;
  caret-color: #000;
  font-family: inherit;
  font-size: inherit;
  line-height: 22px;
  resize: vertical;
}
</style>

方案2:使用成熟代码编辑器组件(开发效率更高)

如果不需要严格限制依赖,直接用封装好的代码编辑器组件即可,自带语法校验、错误高亮、行号显示能力,不需要自己写校验和渲染逻辑:

  • Vue3/Nuxt3场景推荐用vue-codemirror,搭配@codemirror/lang-json、@codemirror/lang-xml语言包,开启语法校验配置后会自动标记错误行
  • 也可以用VSCode同款的monaco-editor的Vue封装版本,内置JSON/XML语法校验能力,开启配置后自动返回错误位置并高亮

内容的提问来源于stack exchange,提问作者BATMAN_2008

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:45:02