is 属性
在 Vue 3.1+ 中,以下代码:
<table>
<tr is="vue:my-row-component"></tr>
</table>
使用了 is 属性 的一种特殊语法,目的是 在需要特定 HTML 元素结构的上下文中(如 <table> 内部)插入自定义组件。
背景问题
HTML 对某些元素(如 <table>、<ul>、<select> 等)有严格的嵌套规则。例如:
<table>只能包含<thead>、<tbody>、<tfoot>、<tr>等;<tr>只能包含<td>或<th>。
如果你直接写:
<table>
<my-row-component></my-row-component>
</table>
浏览器会在 Vue 解析前就解析 HTML,而 <my-row-component> 不是合法的 <table> 子元素,会被提升到 <table> 外面,导致组件无法正常渲染或破坏 DOM 结构。
is 属性的作用
为了解决这个问题,Vue 支持使用 is 属性 来“伪装”成合法标签,同时实际渲染的是你指定的组件。
在 Vue 3.1+ 中,为了与原生 Web Components 的 is 属性区分,Vue 引入了前缀语法:
<tr is="vue:my-row-component"></tr>
vue:前缀明确告诉 Vue:这不是原生自定义元素,而是 Vue 组件。- 浏览器看到的是一个合法的
<tr>元素,不会移动它; - Vue 在运行时会用
my-row-component组件替换这个<tr>的内容(但保留<tr>标签本身作为组件的根元素)。
✅ 所以最终效果是:
my-row-component组件被渲染为<tr>,并保留在<table>内部,符合 HTML 规范。
注意事项
-
组件的根元素必须是
<tr>
my-row-component的模板必须以<tr>...</tr>作为根节点,否则会破坏表格结构。<!-- MyRowComponent.vue -->
<template>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</template> -
vue:前缀是 Vue 3.1+ 新增的
在 Vue 3.0 中,直接写is="my-row-component"可能会被当作原生 custom element。3.1+ 引入vue:前缀避免歧义。 -
仅在必要时使用
这种写法主要用于受 HTML 限制的场景(如 table、select、ul 等)。普通场景直接用<my-component />即可。
总结
<tr is="vue:my-row-component"></tr>
意思是:在这个 <tr> 的位置,实际渲染 my-row-component 组件,但对外表现为合法的 <tr> 元素,以满足 HTML 表格结构的要求。
这是 Vue 提供的一种“绕过 HTML 解析限制”的机制,确保自定义组件能在语义化容器中正确渲染。