x-html HTML绑定 #
什么是 x-html? #
x-html 指令用于设置元素的 HTML 内容。与 x-text 不同,它会解析并渲染 HTML 标签。
基本语法 #
html
<div x-html="表达式"></div>
基本用法 #
绑定 HTML 内容 #
html
<div x-data="{ content: '<strong>Bold</strong> and <em>italic</em>' }">
<div x-html="content"></div>
</div>
输出:Bold and italic
动态 HTML #
html
<div x-data="{
items: ['Apple', 'Banana', 'Orange'],
get listHtml() {
return '<ul>' + this.items.map(i => `<li>${i}</li>`).join('') + '</ul>'
}
}">
<div x-html="listHtml"></div>
</div>
富文本编辑器内容 #
html
<div x-data="{
content: '<h2>标题</h2><p>段落内容</p>'
}">
<div class="preview" x-html="content"></div>
</div>
x-html vs x-text #
| 特性 | x-html | x-text |
|---|---|---|
| HTML 解析 | 解析并渲染 | 原样输出 |
| XSS 风险 | 有风险 | 安全 |
| 使用场景 | 富文本内容 | 纯文本内容 |
对比示例 #
html
<div x-data="{ html: '<strong>Bold</strong>' }">
<p>x-text: <span x-text="html"></span></p>
<p>x-html: <span x-html="html"></span></p>
</div>
输出:
text
x-text: <strong>Bold</strong>
x-html: Bold(加粗显示)
安全注意事项 #
XSS 攻击风险 #
x-html 存在 XSS(跨站脚本攻击)风险,不要绑定用户输入的内容:
html
<div x-data="{ userInput: '' }">
<input x-model="userInput">
<div x-html="userInput"></div>
</div>
如果用户输入 <script>alert('XSS')</script>,脚本可能被执行。
安全使用原则 #
- 不要绑定用户输入
html
<div x-data="{ userInput: '' }">
<input x-model="userInput">
<div x-text="userInput"></div>
</div>
- 只绑定可信内容
html
<div x-data="{
trustedContent: '<p>来自可信源的内容</p>'
}">
<div x-html="trustedContent"></div>
</div>
- 使用内容净化库
html
<div x-data="{
sanitize(html) {
const div = document.createElement('div')
div.textContent = html
return div.innerHTML
}
}">
<div x-html="sanitize(userContent)"></div>
</div>
实用示例 #
富文本渲染 #
html
<div x-data="{
article: {
title: '文章标题',
content: `
<h2>章节一</h2>
<p>这是段落内容。</p>
<ul>
<li>列表项 1</li>
<li>列表项 2</li>
</ul>
`
}
}">
<h1 x-text="article.title"></h1>
<article x-html="article.content"></article>
</div>
Markdown 渲染 #
html
<div x-data="{
markdown: '# Hello\n\nThis is **bold** text.',
renderedHtml: '',
async renderMarkdown() {
const response = await fetch('/api/markdown', {
method: 'POST',
body: JSON.stringify({ markdown: this.markdown })
})
this.renderedHtml = await response.text()
}
}" x-init="renderMarkdown()">
<textarea x-model="markdown" @input="renderMarkdown()"></textarea>
<div class="preview" x-html="renderedHtml"></div>
</div>
图标渲染 #
html
<div x-data="{
icons: {
home: '<svg>...</svg>',
user: '<svg>...</svg>',
settings: '<svg>...</svg>'
}
}">
<span x-html="icons.home"></span>
<span x-html="icons.user"></span>
<span x-html="icons.settings"></span>
</div>
通知消息 #
html
<div x-data="{
notifications: [
{ type: 'success', message: '<strong>成功!</strong> 操作已完成' },
{ type: 'error', message: '<strong>错误!</strong> 操作失败' }
]
}">
<template x-for="notification in notifications">
<div :class="'alert alert-' + notification.type" x-html="notification.message"></div>
</template>
</div>
从 API 加载内容 #
html
<div x-data="{
content: '',
loading: false,
async loadContent() {
this.loading = true
try {
const res = await fetch('/api/content')
this.content = await res.text()
} finally {
this.loading = false
}
}
}" x-init="loadContent()">
<div x-show="loading">加载中...</div>
<div x-show="!loading" x-html="content"></div>
</div>
注意事项 #
1. 替换所有内容 #
x-html 会替换元素的所有内容:
html
<div x-data="{ html: '<span>New</span>' }">
<p x-html="html">原有内容会被替换</p>
</div>
2. 单根元素限制 #
x-html 的内容可以有多个根元素:
html
<div x-data="{ html: '<p>段落1</p><p>段落2</p>' }">
<div x-html="html"></div>
</div>
3. 样式继承 #
插入的 HTML 会继承父元素的样式:
html
<div x-data="{ html: '<span>内容</span>' }" class="text-red">
<div x-html="html"></div>
</div>
4. 事件绑定 #
插入的 HTML 中的内联事件不会执行:
html
<div x-data="{ html: '<button onclick=\"alert(1)\">Click</button>' }">
<div x-html="html"></div>
</div>
点击按钮不会触发 alert。
小结 #
x-html 指令要点:
- 设置元素的 HTML 内容
- 解析并渲染 HTML 标签
- 存在 XSS 风险,谨慎使用
- 不要绑定用户输入的内容
- 只绑定可信来源的内容
下一章,我们将学习 x-bind 指令进行属性绑定。
最后更新:2026-03-28