Vue.js中v-html内容截断:保留HTML格式且仅显示200字符
解决Vue中v-html渲染HTML并保留格式截断内容的问题
我完全懂你的困扰:直接截断HTML字符串会把标签切得残缺不全,导致页面渲染出一堆乱码标签;而去掉标签又彻底丢了原本的格式(粗体、斜体这些)。要实现保留HTML格式同时截断到指定字符数,核心是得解析HTML结构,统计可见文本的长度,而不是粗暴截断原始HTML字符串。
下面是一个可行的实现方案,利用浏览器的DOMParser API来处理HTML节点,确保截断后标签结构完整:
步骤1:实现HTML截断函数
先写一个通用函数,它会解析HTML内容,在保留标签的前提下截取指定长度的文本,最后返回合法的HTML字符串:
function truncateHtml(html, maxLength) { if (!html || maxLength <= 0) return ''; // 把HTML解析成DOM对象 const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const body = doc.body; let currentLength = 0; let truncated = false; const openTags = []; // 递归遍历节点,统计文本长度并执行截断 function traverse(node) { if (truncated) return; if (node.nodeType === Node.TEXT_NODE) { const text = node.textContent; if (currentLength + text.length > maxLength) { node.textContent = text.substring(0, maxLength - currentLength) + '...'; currentLength = maxLength; truncated = true; } else { currentLength += text.length; } } else if (node.nodeType === Node.ELEMENT_NODE) { openTags.push(node.tagName.toLowerCase()); // 遍历当前节点的所有子节点 Array.from(node.childNodes).forEach(traverse); if (!truncated) { openTags.pop(); } } } traverse(body); // 自动闭合所有未关闭的标签,避免DOM异常 while (openTags.length > 0) { const tag = openTags.pop(); body.innerHTML += `</${tag}>`; } return body.innerHTML; }
步骤2:在Vue中集成
Vue 2 全局过滤器方式
把函数注册成Vue全局过滤器,就能在模板里直接调用:
Vue.filter('truncateHtml', function(value, length = 200) { return truncateHtml(value, length); });
模板中使用:
<div class="excerpt" v-html="body_html | truncateHtml(200)"></div>
Vue 3 Composition API 方式
在组件里通过计算属性使用:
<script setup> import { computed } from 'vue'; const props = defineProps({ bodyHtml: String }); const truncatedHtml = computed(() => { return truncateHtml(props.bodyHtml, 200); }); // 粘贴上面的truncateHtml函数 function truncateHtml(html, maxLength) { // ... 函数实现同上 } </script> <template> <div class="excerpt" v-html="truncatedHtml"></div> </template>
这个方案的优势很明显:
- 完整保留原始HTML格式(粗体、斜体、链接等)
- 只截断可见文本,绝不破坏标签结构
- 自动闭合未完成的标签,避免页面渲染异常
内容的提问来源于stack exchange,提问作者LOTUSMS
相关产品推荐
相关产品推荐

