Literal标签用于原样输出JS等易冲突代码,需完整包裹且禁止混入ThinkPHP语法,仅作用于模板编译期,不解决Vue运行时冲突。

ThinkPHP 默认用 { 和 } 解析模板变量(如 {$name}),而 JS 里大量使用花括号,比如 if (a === b) { ... }、function() { ... }、对象字面量 { id: 1, name: 'a' },甚至 jQuery 选择器 $('div') 后紧跟花括号也容易被误识别——只要 { 后紧跟着 $ 或标签语法(如 <if></if>),模板引擎就可能提前解析,导致 JS 报错、页面白屏或脚本中断。
Literal 标签怎么用才安全
literal 是 ThinkPHP 提供的「原样输出」机制,它让标签内所有内容跳过模板编译阶段,直接原封不动输出到 HTML 中。关键点是:它只在模板渲染时起作用,不参与 Vue/React 运行时逻辑。
- 包裹整段 JS 代码最稳妥:
{literal}<script>console.log({id: 1}); if(true){alert('ok');}</script>{/literal} - 不能混写 ThinkPHP 语法:
{literal}Hello {$user.name}{/literal}里的{$user.name}不会被解析,但若你本意是想输出 PHP 变量值,这就错了——literal 会把它当纯文本输出 - 避免嵌套冲突:不要在 literal 内再写
{include file="xxx"}或{volist name="list"},这些仍会被 TP 尝试解析,大概率报错
比 literal 更轻量的空格绕过法
ThinkPHP 的解析规则其实有“触发条件”:只有 { 紧跟 $、:、(如 <code><if></if>)才会启动解析。所以对简单 JS 场景,加个空格就能避开:
- 错误写法:
{$('input').val()}→ TP 误认成变量 - 正确写法:
{ $('input').val()}或{ $ ('input').val()}→ 空格打断识别链 - 对象字面量也适用:
var obj = { name: '{$name}', age: 25 };改为var obj = { name: '{$name}', age: 25 };(注意{后无$,本身就不触发)
JS 里要动态插 PHP 值?别硬塞,换思路
如果 JS 需要用到服务端数据(比如用户 ID、配置项),不要把 PHP 变量直接写进 script 标签里拼接,尤其别在 literal 里硬塞 {$Think.session.id} —— literal 会原样输出,得不到真实值。
立即学习“PHP免费学习笔记(深入)”;
- 推荐做法:在 HTML 中预留 data 属性,例如
,JS 里用document.body.dataset.userId读取 - 或者统一注入全局变量:
<script>window.__INIT_DATA__ = {$initData|json_encode};</script>(注意确保$initData已转义) - 避免在 JS 字符串中拼接未过滤的 PHP 变量,防止 XSS,比如
alert('{$msg}')必须配合|htmlspecialchars修饰
literal 不是万能,运行时冲突还得靠前端控制
literal 只管模板编译期,不管 JS 执行时。比如 Vue 渲染后生成的 DOM 含 {{item.name}},而页面又用了 TP 模板二次渲染,就会再次冲突——这种属于架构级问题,literal 无能为力。
- 前后端分离场景:TP 只做 API 接口和静态资源托管,JS 完全由前端框架(Vue/React)接管,彻底规避模板层交叠
- 混合渲染场景:TP 输出纯 HTML 结构 + 初始 JSON 数据,JS 初始化后接管全部交互,不再依赖 TP 插值
- 真要共存 Vue 和 TP 模板:必须修改 Vue 的 delimiters,比如设为
['${', '}'],而不是依赖 literal “兜底”



















