视图的组成此处所说的视图就是MVC中所说的V层,视图层也要展示层。thinkphp中视图层是由HTML模板文件组成的。也可以说视图跟模板一个意思模板的定义为了对模板文件更加有效的管
视图的组成
此处所说的视图就是MVC中所说的V层,视图层也要展示层。thinkphp中视图层是由HTML模板文件组成的。
也可以说视图跟模板一个意思
模板的定义
为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分
,默认的模板文件定义规则是:视图目录(view)/控制器名(小写)/方法名(小写)+ 模板后缀(框架的默认视图文件后缀是.html)
模板渲染
注意:在控制器中使用视图
渲染模板最常用的是控制器类在继承系统控制器基类(\think\Controller
)后调用fetch
方法,调用格式:
方式一:fetch() 的方式
return $this->fetch('[模板文件]'[,'模板变量(数组)']);
模板文件的写法支持下面几种:
用法 |
描述 |
---|
不带任何参数 |
自动定位当前操作的模板文件 |
[模块@]/[控制器]/[操作] |
常用写法,支持跨模块 |
完整的模板文件名 |
直接使用完整的模板文件名(包括模板后缀) |
例:
在application\index\view\index\index.html
文件中写入如下内容
模板渲染....
在application\index\controller\Index.php
文件中写入如下内容
namespace app\index\controller;
use think\Controller;
//需要继承think\Controller
class Index extends Controller
{
public function index() {
// 不带任何参数 自动定位当前操作的模板文件
// 控制器路径: application\index\controller\Index.php
// 模板文件路径: application\index\view\index\index.html
//return $this->fetch();
//return $this->fetch('index@/index/index');
//这种默认路径就已经在application\index\view 目录下 后缀也不用写了
return $this->fetch('index/index');
}
}
运行结果
方式二:助手函数view()
推荐使用这种,不用引入,不用继承
#这里view里面的参数跟方式一写法一样
return view('[模板文件]'[,'模板变量(数组)']); # 辅助函数
# 针对于自定义路由,使用这种
return view('index@index/index');
例:
定义如下路由:
//定义控制器路由 模块/类名/方法名 路由别名
Route::get('index', 'index/index/index')->name('indexr');
注意使用模板渲染的使用访问不能使用路由别名,如上面的路由应该是/index
在application\index\controller\Index.php
文件中写入如下内容
namespace app\index\controller;
class Index
{
public function index() {
return view('index@index/index');
}
}
运行结果
模板赋值
在模板文件中
模板渲染....
姓名:{$name}
年龄:{$age}
email:{$email}
方式一:$this->assign()
例:
在控制器中
namespace app\index\controller;
//需要继承\think\Controller
class Index extends \think\Controller
{
public function index() {
//单个赋值
$this->assign('name', 'makalo');
// 或者批量赋值
$this->assign([
'age' => '18',
'email' => 'makalo@qq.com'
]);
return view('index@index/index');
}
}
方式二:助手函数view()
例:
在控制器中
namespace app\index\controller;
class Index
{
public function index() {
return view('index@index/index',['name' => 'makalo','age' => '18' ,'email' => 'makalo@qq.com']);
}
}
两种方式运行结果
方式三:view()+compact () 推荐这种
模板文件如下:
模板渲染....
姓名:{$name}
年龄:{$arr['age']}
email:{$arr['email']}
控制器:
namespace app\index\controller;
class Index
{
public function index() {
$name = 'makalo';
$arr = ['age' => '18' ,'email' => 'makalo@qq.com'];
return view('index@index/index',compact('name','arr'));
}
}
运行结果
全局赋值
注意:上面的三种赋值方式只能在自己的模板内使用,那么可不可以赋值给所有模板公用?答案是可以的。
如果需要在控制器之外进行模板变量赋值,可以使用视图类的share
静态方法进行全局公共模板变量赋值,例如:
use think\facade\View;
// 赋值全局模板变量
View::share('name','value');
// 或者批量赋值
View::share(['name1'=>'value','name2'=>'value2']);
全局静态模板变量最终会和前面使用方法赋值的模板变量合并。
模板中使用函数
需要对模板输出使用函数进行过滤或其它处理的时候,就可以使用一下函数来解决。
{$password|md5}
当然也可以写成如下的写法,推荐
{:md5($password)}
注:不但可以用用php系统提供函数,还可以用tp提供的函数,还可以用户在tp规定的文件中定义的写的函数
例:
模板渲染....
姓名:{$name}
年龄:{$arr['age']}
email:{$arr['email']}
//使用函数示例
加密:{$name|md5}
加密:{:md5('aaa')}
运行结果
模板原样输出
可以使用literal
标签来防止模板标签被解析,例如:
{literal}
Hello,{$name}!
{/literal}
上面的{$name}
标签被literal
标签包含,因此并不会被模板引擎解析,而是保持原样输出。
literal
标签还可以用于页面的JS代码外层,确保JS代码中的某些用法和模板引擎不产生混淆。
总之,所有可能和内置模板引擎的解析规则冲突的地方都可以使用literal
标签处理。
例:
模板内置标签
变量输出使用普通标签就足够了,但是要完成其他的控制、循环和判断功能,就需要借助模板引擎的标签库功能了,系统内置标签库的所有标签无需引入标签库即可直接使用。
内置标签主要包括:
标签名 |
作用 |
包含属性 |
---|
include |
包含外部模板文件(闭合) |
file |
load |
导入资源文件(闭合 包括js css import别名) |
file,href,type,value,basepath |
volist |
循环数组数据输出 |
name,id,offset,length,key,mod |
foreach |
数组或对象遍历输出 |
name,item,key |
for |
For循环数据输出 |
name,from,to,before,step |
switch |
分支判断输出 |
name |
case |
分支判断输出(必须和switch配套使用) |
value,break |
default |
默认情况输出(闭合 必须和switch配套使用) |
无 |
compare |
比较输出(包括eq neq lt gt egt elt heq nheq等别名) |
name,value,type |
range |
范围判断输出(包括in notin between notbetween别名) |
name,value,type |
present |
判断是否赋值 |
name |
notpresent |
判断是否尚未赋值 |
name |
empty |
判断数据是否为空 |
name |
notempty |
判断数据是否不为空 |
name |
defined |
判断常量是否定义 |
name |
notdefined |
判断常量是否未定义 |
name |
define |
常量定义(闭合) |
name,value |
assign |
变量赋值(闭合) |
name,value |
if |
条件判断输出 |
condition |
elseif |
条件判断输出(闭合 必须和if标签配套使用) |
condition |
else |
条件不成立输出(闭合 可用于其他标签) |
无 |
php |
使用php代码 |
无 |
循环标签
格式示例:
# foreach 【推荐写法】
{foreach $list as $key=>$vo }
{$vo.id}:{$vo.name}
{/foreach}
或者
# volist
{volist name="list" id="vo"}
{$vo.id}:{$vo.name}
{/volist}
例:
模板文件
{volist name="data" id="vo"}
- {$vo.id} --- {$vo.name}
{/volist}
{foreach $data as $val}
- {$val.id} --- {$val.name}
{/foreach}
控制器
namespace app\index\controller;
use think\Controller;
class Tt extends Controller
{
public function index(){
$data = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
['id' => 3, 'name' => '王五'],
['id' => 4, 'name' => '赵六'],
];
$age = 10;
return view('index@tt/index',compact('data','age'));
}
}
运行结果
条件判断标签
格式示例:
{if ( $name == 1) OR ( $name > 100) } value1
{elseif $name == 2 /} value2
{else /} value3
{/if}
例:
模板文件
条件判断
{if $age <10} 儿童
{elseif $age<30 /} 青年
{else /} 老年
{/if}
控制器
namespace app\index\controller;
use think\Controller;
class Tt extends Controller
{
public function index(){
$data = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
['id' => 3, 'name' => '王五'],
['id' => 4, 'name' => '赵六'],
];
$age = 10;
return view('index@tt/index',compact('data','age'));
}
}
运行结果
模板继承
模板继承其实并不难理解,就好比类的继承一样,模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。
先定义一个基础模板
例:在application\index\view\common\base.html
模板文件中写入
{block name="menu"}菜单{/block}
{block name="left"}左边分栏{/block}
{block name="main"}主内容{/block}
{block name="right"}右边分栏{/block}
{block name="footer"}底部{/block}
父模板
然后我们在子模板(其实是当前操作的入口模板)中使用继承:
application\index\view\index\ext.html 中
{extend name="common/base" /}
{block name="title"}子模板标题{/block}
{block name="left"}{/block}
{block name="main"}
子模板主内容
{/block}
{block name="right"}
子模板右边分栏
{/block}
{block name="footer"}
{__block__}
--->继承父模板,并追加的内容
{/block}
子模板继承
控制器
namespace app\index\controller;
use think\Controller;
class Tt extends Controller
{
public function ext(){
return View('index@/index/ext');
}
}
运行结果