视图 - 注册资源包

  • 作者:KK

  • 发表日期:2019.09.18


要点速读

  1. 本质上就是用一个数组描述了一个 JS 和 CSS 资源的集合,然后把这个数组传达到一个视图相关的注册函数里,从而实现在输出视图的时候自动输出相关的 JS和CSS 资源。

  2. 而具体的表现形式就是封装一个类,在它的属性里描述了有哪些 JS和CSS,输出视图时把这个类传达到注册函数里,视图引擎就从这个类的各种属性中收集了“有哪些 JS和CSS,输出在顶部还是底部,先输出哪个才到哪个,输出到哪个URL目录下……”


先看看官方例子的

官方的项目例子里,有一个 app\assets\AppAsset 这个类,它又叫做“资源包”,它的属性大概是这样定义的:

public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
    'css/site.css',
];
public $js = [
];
public $depends = [
    'yii\web\YiiAsset',
    'yii\bootstrap\BootstrapAsset',
];

在视图里调用app\assets\AppAsset::register($this)后,其中$this是指视图组件(yii\web\View),在这个过程中,视图会从这个资源包的属性里获取有哪些JS和CSS,输出在顶部还是底部,先输出哪个才到哪个,输出到哪个URL目录下……这样的信息,然后在视图触发$this->endPage()方法的时候开始输出这些东西到各个位置。

其中如果多次调用这个register注册行为的话,底层会检测是否重复注册的,所以不会存在重复/多次输出脚本样式的情况。


控制输出位置

Asset类里声明这些属性即可控制 JS 或 CSS 输出在 head 标签里或是 body 标签的底部:

//CSS位置声明
public $cssOptions = [
	'position' => \yii\web\View::POS_HEAD,
];

//JS位置声明
public $jsOptions = [
	'position' => \yii\web\View::POS_HEAD,
];

其中\yii\web\View::POS_HEAD就是输出在 head 标签里的意思,要输出到body底部就用\yii\web\View::POS_END,主要就用这两个,其它有兴趣再自己探索框架源码哈。


依赖

如果想注册一个A包的时候,自动注册B包的资源,可以通过声明依赖关系来实现,例如下定义下面两个包:

jQuery资源包:

namespace app\assets;

class JQueryAsset extends \yii\web\AssetBundle{
    public $js = [
        '/resource/js/jquery1.12.7.min.js'
    ];
}

然后是一个基于jQuery开发的插件,比如它是一个轮播图:

namespace app\assets;

class SlideBanner extends \yii\web\AssetBundle{
    public $js = [
        '/resource/plugin/slide-banner/slide-banner.js',
    ];

    public $css = [
        '/resource/plugin/slide-banner/slide-banner.css',
    ];

    public $depends = [
        'app\assets\JQueryAsset'
    ];
}

然后在视图里只要注册app\assets\SlideBanner这个包就可以了,它会自动把$depends属性里描述的app\assets\JQueryAsset包也一起注册,最终的效果就是:依赖的包所定义的JS先被输出,然后才输出当前这个包的JS。