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

Vue.js中如何在UL内渲染LI?有无隐形标签?v-for渲染LI问题

在Vue.js中正确渲染<ul>内的<li>标签(无多余包裹元素)

你遇到的问题其实很典型——既要循环渲染已有的<li>标签字符串,又要避免引入<span>这类不符合HTML规范的中间包裹元素(毕竟<ul>的直接子元素只能是<li>)。下面给你两种实用的解决方案:

方案1:拼接HTML后直接在<ul>上使用v-html(最简便)

这种方法直接把所有item中的<li>标签拼接成一个完整的HTML字符串,一次性插入到<ul>中,完全不会产生多余DOM元素,还符合HTML规范:

模板代码

<ul class="list-unstyled" v-html="combinedLineItems"></ul>

计算属性处理拼接

computed: {
  combinedLineItems() {
    // 提取lineItem.properties里的所有值,拼接成完整的HTML
    return Object.values(this.lineItem.properties).join('');
  }
}

⚠️ 重要提醒:使用v-html时必须确保内容来自可信数据源,避免XSS攻击风险。如果内容包含用户输入,一定要先做转义处理。

方案2:用渲染函数/JSX解析HTML为VNode(更灵活)

如果你需要对<li>元素做更多Vue层面的控制(比如绑定事件、指令),可以用渲染函数把HTML字符串解析成Vue的虚拟节点(VNode),直接作为<ul>的子元素:

Vue 2渲染函数示例

render(h) {
  const listChildren = [];
  
  // 遍历所有item
  Object.values(this.lineItem.properties).forEach(itemHtml => {
    // 创建临时div解析HTML字符串
    const tempContainer = document.createElement('div');
    tempContainer.innerHTML = itemHtml;
    
    // 把解析后的<li>转换成VNode,添加到列表子元素中
    Array.from(tempContainer.children).forEach(liElement => {
      const attrs = {};
      // 复制原<li>的属性
      Array.from(liElement.attributes).forEach(attr => {
        attrs[attr.name] = attr.value;
      });
      
      listChildren.push(h(
        'li',
        { attrs, domProps: { innerHTML: liElement.innerHTML } },
        []
      ));
    });
  });
  
  // 返回<ul>的VNode
  return h('ul', { class: 'list-unstyled' }, listChildren);
}

Vue 3+ JSX示例(更简洁)

setup() {
  const lineItem = reactive({ /* 你的数据 */ });
  
  const getListChildren = () => {
    const children = [];
    Object.values(lineItem.properties).forEach(itemHtml => {
      const tempContainer = document.createElement('div');
      tempContainer.innerHTML = itemHtml;
      Array.from(tempContainer.children).forEach(li => {
        children.push(<li {...li.attributes} dangerouslySetInnerHTML={{ __html: li.innerHTML }} />);
      });
    });
    return children;
  };
  
  return () => <ul class="list-unstyled">{getListChildren()}</ul>;
}

这种方法虽然稍复杂,但能让你在Vue的生态里操作这些<li>元素,而不是直接插入纯HTML。

最后补充一下你问的“隐形标签”:Vue的<template>标签确实是一种虚拟容器,不会被渲染成真实DOM,但它不能直接承载v-html(因为不是真实元素),所以在你的场景里不太适用——毕竟你需要把HTML字符串插入到DOM中,必须有一个真实元素作为载体,而<template>做不到这一点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 09:37:47