视图系统
最后更新: 2026-01-27 11:02:47视图系统
Unicode Framework 提供了灵活的视图系统,支持多种模板引擎,包括 Smarty 和 Vue3。
视图基础
渲染视图
使用 view() 辅助函数渲染视图:
use function view;
// 渲染视图
return view('user/profile', [
'user' => $user,
'title' => '用户资料',
]);
// 使用指定引擎
return view('user/profile', ['user' => $user], 'vue');
在控制器中使用
namespace App\Index\Controller;
use Unicode\Framework\Http\Request;
use Unicode\Framework\Http\Response;
class UserController
{
public function profile(Request $request): Response
{
$user = db('users')->where('id', 1)->first();
$html = view('user/profile', [
'user' => $user,
'title' => '用户资料',
]);
return Response::html($html);
}
}
检查视图是否存在
use Unicode\Framework\View\View;
if (View::exists('user/profile')) {
return view('user/profile', ['user' => $user]);
}
Smarty 模板引擎
基本语法
Smarty 是框架默认的模板引擎,提供强大的模板功能。
#### 变量输出
{ 输出变量 }
{$user.name}
{$user.email}
{ 数组访问 }
{$user.profile.bio}
{ 默认值 }
{$user.name|default:'匿名用户'}
#### 条件判断
{if $user.status == 'active'}
<p>用户已激活</p>
{else}
<p>用户未激活</p>
{/if}
{ 多条件 }
{if $user.age >= 18}
<p>成年人</p>
{elseif $user.age >= 13}
<p>青少年</p>
{else}
<p>儿童</p>
{/if}
#### 循环
{ foreach 循环 }
{foreach $users as $user}
<div>
<h3>{$user.name}</h3>
<p>{$user.email}</p>
</div>
{/foreach}
{ 带索引的循环 }
{foreach $users as $index => $user}
<div class="user-{$index}">
{$user.name}
</div>
{/foreach}
#### 包含模板
{ 包含其他模板 }
{include file='header.html'}
{ 传递变量 }
{include file='user/card.html' user=$user}
{ 包含公共模板 }
{include file='common/footer.html'}
#### 函数和修饰符
{ 字符串修饰符 }
{$user.name|upper}
{$user.name|lower}
{$user.name|capitalize}
{$user.name|truncate:20}
{ 日期格式化 }
{$user.created_at|date_format:'%Y-%m-%d'}
{ HTML 转义 }
{$user.bio|escape:'html'}
{ 默认值 }
{$user.avatar|default:'/images/default-avatar.png'}
Smarty 配置
在 config/view.php 中配置:
return [
'default_engine' => 'smarty',
'engines' => [
'smarty' => [
'template_extension' => '.html',
'compile_dir' => 'runtime/view/smarty/compile',
'cache_dir' => 'runtime/view/smarty/cache',
'caching' => false,
'cache_lifetime' => 3600,
'debugging' => false,
'escape_html' => true,
],
],
];
模板目录结构
app/index/view/
├── user/
│ ├── profile.html
│ └── list.html
├── common/
│ ├── header.html
│ └── footer.html
└── index.html
Vue3 模板引擎
基本语法
Vue3 模板引擎支持 Vue3 的模板语法。
#### 插值表达式
<template>
<div>
<h1>{{ user.name }}</h1>
<p>{{ user.email }}</p>
</div>
</template>
#### 指令
<template>
{ v-if 条件渲染 }
<div v-if="user.status === 'active'">用户已激活</div>
<div v-else>用户未激活</div>
{ v-for 列表渲染 }
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
{ v-bind 属性绑定 }
<img :src="user.avatar" :alt="user.name" />
{ v-model 双向绑定(表单) }
<input v-model="user.name" type="text" />
{ v-show 显示/隐藏 }
<div v-show="user.isVisible">可见内容</div>
{ v-html 原始 HTML }
<div v-html="user.bio"></div>
</template>
#### 事件处理
<template>
<button @click="handleClick">点击</button>
<button @click="handleSubmit($event)">提交</button>
</template>
Vue3 SSR
框架支持 Vue3 服务端渲染(SSR)。
#### 启用 SSR
在 config/view.php 中配置:
return [
'engines' => [
'vue' => [
'vue3_ssr' => [
'enabled' => true,
'node_path' => '/usr/bin/node',
'script_path' => 'runtime/vue3-ssr/render.js',
],
],
],
];
#### 使用 SSR
use function vue_spa;
// 渲染 Vue3 SPA 入口页面
return vue_spa(
initialData: ['user' => $user],
appId: 'app',
entryFile: 'js/main.js',
options: [
'title' => '我的应用',
'meta' => [
'description' => '应用描述',
],
]
);
Vue3 SPA 支持
框架提供了 vue_spa() 辅助函数来渲染 Vue3 单页应用入口:
use function vue_spa;
return vue_spa([
'user' => $user,
'config' => [
'apiUrl' => '/api',
],
], 'app', 'js/main.js');
视图配置
全局配置
config/view.php:
return [
// 默认模板引擎
'default_engine' => 'smarty',
// 视图文件目录(null 表示使用默认路径)
'path' => null,
// 模板引擎配置
'engines' => [
'smarty' => [
'template_extension' => '.html',
'compile_dir' => 'runtime/view/smarty/compile',
'cache_dir' => 'runtime/view/smarty/cache',
'caching' => false,
'escape_html' => true,
],
'vue' => [
'vue3_ssr' => [
'enabled' => false,
],
],
],
];
应用级配置
在多应用模式下,可以在 app/{app-name}/config/view.php 中配置应用特定的视图设置:
// app/index/config/view.php
return [
'default_engine' => 'vue',
'engines' => [
'smarty' => [
'template_dir' => 'app/index/view',
],
],
];
视图路径
框架会自动检测视图路径:
- 多应用模式:
app/{app-name}/view/ - 单应用模式:
app/{default-app}/view/ - 自定义路径:在配置中指定
path
视图辅助函数
view()
use function view;
// 基本用法
$html = view('template', ['data' => $data]);
// 指定引擎
$html = view('template', ['data' => $data], 'vue');
vue_spa()
use function vue_spa;
// 渲染 Vue3 SPA 入口
$html = vue_spa(
initialData: ['user' => $user],
appId: 'app',
entryFile: 'js/main.js',
options: [
'title' => '页面标题',
'meta' => [
'description' => '页面描述',
],
]
);
最佳实践
1. 模板组织
app/index/view/
├── layouts/ # 布局模板
│ ├── main.html
│ └── admin.html
├── components/ # 组件模板
│ ├── header.html
│ └── footer.html
├── user/ # 用户相关模板
│ ├── profile.html
│ └── list.html
└── index.html # 首页模板
2. 使用布局
{ layouts/main.html }
<!DOCTYPE html>
<html>
<head>
<title>{$title|default:'我的网站'}</title>
</head>
<body>
{include file='components/header.html'}
<main>
{block name='content'}{/block}
</main>
{include file='components/footer.html'}
</body>
</html>
{ user/profile.html }
{extends file='layouts/main.html'}
{block name='content'}
<h1>用户资料</h1>
<p>{$user.name}</p>
{/block}
3. 数据转义
{ 自动转义 HTML(推荐) }
{$user.bio|escape:'html'}
{ 需要输出 HTML 时 }
{$user.bio|unescape}
4. 缓存优化
// 在配置中启用缓存(生产环境)
'engines' => [
'smarty' => [
'caching' => true,
'cache_lifetime' => 3600,
],
],
5. 模板继承
{ base.html }
<!DOCTYPE html>
<html>
<head>
<title>{block name='title'}默认标题{/block}</title>
</head>
<body>
{block name='content'}{/block}
</body>
</html>
{ page.html }
{extends file='base.html'}
{block name='title'}页面标题{/block}
{block name='content'}
<h1>页面内容</h1>
{/block}
常见问题
Q: 如何切换模板引擎?
A: 在配置中设置 default_engine,或在调用 view() 时指定引擎。
Q: 视图文件应该放在哪里?
A: 默认在 app/{app-name}/view/ 目录下,可以在配置中自定义。
Q: 如何传递数据给视图?
A: 使用 view() 函数的第二个参数传递数据数组。
Q: 支持哪些模板引擎?
A: 目前支持 Smarty 和 Vue3,可以通过接口扩展其他引擎。
Q: 如何启用视图缓存?
A: 在配置中设置 caching => true 和 cache_lifetime。