lxepoo 2015-05-05 10:10:41 21261次浏览 21条评论 58 30 0

2.0的变化相信大家都看到了,其中对一个资源包概念做出了很完美的实现,那就是AssetBundle,但是很多初学者朋友可能不太能够正确的领会其中的含义

我画了一张图,大家可以将就看一下:

渲染层级.png

其中,控制器动作的视图(view)渲染顺序是优先于我们的模板页(layout)的,那么一旦我们在某个视图中使用了新的JS库,或新的CSS样式文件,那么我们如何去处理呢?

以下方式是错误的,请避免使用:
有的人会直接在视图里添加对css或者js的link引用,这样引入的文件是在视图区域,而yii的默认JS加载会放在模板页的最后,这样可能导致依赖关系混乱。
比如你视图中引用的js文件里调用了jquery包,但是执行时jquery的加载代码在HTML页面的末尾,这样导致页面脚本错误。

还有人会图省事,直接把项目中所有的js或css文件都书写layout模板页里,这样产生大量的无效样式或js,影响了加载效率及页面错位风险。

所以正确的方式应该是通过AssetBundle去解决这个问题,先发一个简单的类给大家看一下:

namespace app\assets;
use yii\web\AssetBundle;

class AppAsset extends AssetBundle {
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'public/skin/default_skin/css/theme.css',
    ];
    public $js = [
        'public/vendor/jquery/jquery-1.11.1.min.js',
        'public/vendor/jquery/jquery_ui/jquery-ui.min.js',
        'public/js/bootstrap/bootstrap.min.js',
    ];

    //依赖包
    public $depends = [
        //这里写你的依赖包即可,没有就别写
    ];

    //导入当前页的功能js文件,注意加载顺序,这个应该最后调用
    public static function addPageScript($view, $jsfile) {
        $view->registerJsFile($jsfile, [AppAsset::className(), 'depends' => 'app\assets\AppAsset']);
    }

    //导入编辑器
    public static function addCkeditor($view) {
        $view->registerJsFile('/public/js/utility/ckeditor/ckeditor.js', [AppAsset::className(), 'depends' => 'app\assets\AppAsset']);
    }
    
}

可以看到上面我创建的类中已经预定义了两个静态方法addPageScript和addCkeditor,其中addCkeditor是一个第三方的js组件,是个编辑器,具体的开发环境中你们可以写别的方法名及加载别的组件。

那么上的这个东西写好后应该如何去使用呢?
我们在模板页开头部分加上这句话:

//自动加载资源
AppAsset::register($this);

这样会在模板页加载基础的项目资源文件,比如css和js什么的。

现在我们有一个视图叫create-mail,需要使用ckeditor编辑器,那么我们应该在create-mail视图的开头加上这句话:

//导入ckeditor包资源
\app\assets\AppAsset::addCkeditor($this);

最后解释一下,addCkeditor()方法是我们预先定义好的,这样我们可以把一些常见的包都拆包并预处理好,如果你觉得麻烦可以直接使用如下的方式:

//导入ckeditor包资源
\app\assets\AppAsset::addPageScript($this,'js文件相对路径或url');

以上的例子只是使用了js文件作为一个简单的介绍,css样式的加载也是一样的道理。

这样做的好处是,即使在视图里加载css或js也会因为依赖关系而出现在视图外面的常规加载区域中,规范了很多。

同时也因为依赖关系,你在视图里加载的文件肯定会排在你的基础样式或脚本的后面,不会出错。

觉得很赞
  • 评论于 2015-05-05 10:20 举报

    感谢感谢。紫薯布丁。

  • 评论于 2015-05-05 10:25 举报

    赞赞赞赞,再补5个字

  • 评论于 2015-05-05 12:41 举报

    I love you

    1 条回复
    评论于 2015-05-06 23:08 回复

    REALLY???????????

  • 评论于 2015-05-06 11:47 举报

    不错,谢谢分享。一定要十个字吗,呵呵

  • 评论于 2015-05-06 23:07 举报

    不错,谢谢分享。一定要十个字吗,呵呵

  • 评论于 2015-05-08 09:54 举报

    嗯,我试过一个页面模板的思路就是这样做的。

  • 评论于 2015-05-08 10:58 举报

    @布老虎........................

  • 评论于 2015-05-16 12:07 举报

    不错,谢谢分享。一定要十个字吗,呵呵

  • 评论于 2015-05-26 09:17 举报

    楼主,你的JS文件放在的是web下面public/vendor/jquery里面的么。那我想要调用自身的/vendor/jquery/dist里面的怎么弄啊。或者能不能调用的到啊,因为vendor和web同级的,而URL的配置是直接指向basic/web/下面了。我是新手,求指教

    1 条回复
    评论于 2015-05-26 10:14 回复

    $basePath 设置一下,他就会自动帮你索引你的文件,然后发布到web/asset下了。然后引用链接会自动改变。不谢,YII就是这么流弊。

    觉得很赞
  • 评论于 2015-05-27 16:52 举报

    能否判断浏览器版本,并输出相应内容?
    或者应该如何输出带判断的语句,比如

    <!--[if lt IE 9]>
        <script src="test.js"></script>
        <![endif]-->
    
    2 条回复
    评论于 2015-05-28 11:48 回复

    可以,请仔细查看官方文档中关于资源包的处理方式,写的很明白可以支持IF方式。

    评论于 2015-05-28 14:27 回复

    哦,看文档去,E文不好。 是期望知道的直接给出个使用方法。谢了,啃文档去。

  • 评论于 2015-09-09 15:22 举报

    解决了 js依赖问题,非常好

  • 评论于 2015-09-15 17:38 举报

    其实我主要是想看看依赖的,有哪些默认的AssetBundle,比如 'yii\web\YiiAsset','yii\bootstrap\BootstrapAsset'等。不过学到了渲染顺序也不错,那个编辑器插件也是第一次接触。总之谢谢!!!

  • 评论于 2015-10-09 14:43 举报

    新手报到,给我解决了一个大难题呀,感谢仁兄。

  • 评论于 2015-10-20 14:52 举报

    楼主,问一下,全局js配置,注册js文件能到header里面吗?怎样配置

    2 条回复
    评论于 2015-10-20 18:09 回复

    文档里有写,JS可以出现在header里的。
    http://www.yiichina.com/doc/api/2.0/yii-web-view#registerJsFile()-detail

    POS_HEAD: in the head section

    评论于 2015-10-22 17:50 回复

    谢谢,我会了,我是在AppAsset.php 配置全局js ,增加了一个就可以了
    public $jsOptions = [

    	'position' => \yii\web\View::POS_HEAD
    ];
    
  • 评论于 2015-12-16 21:52 举报

    到底什么是依赖关系??

    觉得很赞
  • 评论于 2016-07-05 14:53 举报

    Cannot redeclare class frontend\assets\AppAsset

  • 评论于 2016-08-18 16:49 举报

    都前后端分离了,除了view,其他都扔cdn上去吧。。。。

  • 评论于 2016-11-01 23:53 举报

    谢谢分享

  • 评论于 2017-05-23 14:02 举报

    非常棒的分享,学习了啊,谢谢

  • 评论于 2017-11-22 12:01 举报

    你好 使用了layout之后 子视图里写JS代码 在引入的JQUERY之前 用不了$怎么解决
    怎么保证在视图层写的JS代码在引入JS文件之后

您需要登录后才可以评论。登录 | 立即注册