且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Yii2 —— 实现自己的iCheck资源包

更新时间:2022-10-02 18:18:03

1.1.1  基本封装

iCheck是配合bootstrap包使用的前端控件,用来美化radiocheckbox的显示样式的,根据前面的“资源管理”的说明,以及官网的文档,可以很方便的把iCheck组件用资源包封装起来,顺便熟悉一下Yii 2中资源包的使用方法:

1、创建iCheck资源包ICheckAssets.php

<?php
 

 
namespace backend\assets;
 
 use
yii\web\AssetBundle;
 
 class
ICheckAsset extends AssetBundle
{
}

 

2、设置资源路径,这里省事,直接将icheck包放到%yii-app%\backend\web\front-lib目录下:

<?php
 

 
namespace backend\assets;
 
 use
yii\web\AssetBundle;
 
 class
ICheckAsset extends AssetBundle
{
   
public $basePath = '@webroot';
    public
$baseUrl = '@web';
    public
$css = [
       
'front-lib/icheck/skins/all.css',
   
];
    public
$js = [
       
'front-lib/icheck/icheck.min.js',
   
];
 
}

 

注:iCheck支持skin,这里暂时先把所有skin全部引入。

3、设置依赖包,iCheck依赖于bootstrap,同时初始化代码依赖于jQuery,所以要将这两个配置上:

<?php
 

 
namespace backend\assets;
 
 use
yii\web\AssetBundle;
 
 class
ICheckAsset extends AssetBundle
{
   
public $basePath = '@webroot';
    public
$baseUrl = '@web';
    public
$css = [
       
'front-lib/icheck/skins/all.css',
   
];
    public
$js = [
       
'front-lib/icheck/icheck.min.js',
   
];
    public
$depends = [
       
'yii\web\JqueryAsset',
       
'yii\bootstrap\BootstrapAsset',
   
];
 
}

 

4、iCheck组件不是直接引入CSS就可以了,而是在页面需要执行一段JS代码才能把显示样式修改过来,因此需要注册iCheck初始化代码:

<?php
 

 
namespace backend\assets;
 
 use
yii\web\AssetBundle;
 
 class
ICheckAsset extends AssetBundle
{
   
public $basePath = '@webroot';
    public
$baseUrl = '@web';
    public
$css = [
       
'front-lib/icheck/skins/all.css',
   
];
    public
$js = [
       
'front-lib/icheck/icheck.min.js',
   
];
    public
$depends = [
       
'yii\web\JqueryAsset',
       
'yii\bootstrap\BootstrapAsset',
   
];
 
    public function
registerAssetFiles($view)
    {
       
parent::registerAssetFiles($view);
 
       
$view->registerJs(
           
'$("input").iCheck({
                checkboxClass: "icheckbox_minimal-blue",
                radioClass: "iradio_minimal-blue",
                increaseArea: "20%" // optional
            });'
       
);
   
}
}

 

注:这里固定配置为使用minimal/blue这个样式。

5、使用资源包,在AppAssets中增加配置(注意路径):

public $depends = [
     
'backend\assets\ICheckAsset',
     
'yii\web\YiiAsset',
     
'yii\bootstrap\BootstrapAsset',
 
];

 

6、显示效果如下:

                           Yii2 —— 实现自己的iCheck资源包  

 

至此,就初步完成了将iCheck封装到资源包的过程,但是现在还有几个遗留问题:

1、从上图可以看出,明显checkbox控件位置偏右了;

2、iCheck支持很多个样式,可是上面代码却固定成minimal/blue,影响适用性;

3、引入的是all.css,没有按需引入,这样会导致CSS文件比较大;

 

下面把上述问题逐一解决。

1.1.2  控件位置

1.1.2.1原因

在使用iCheck之前,checkbox和文字是这样的:

Yii2 —— 实现自己的iCheck资源包

 

input控件在label控件内,label控件为了给checkbox控件空出位置,设置了一个padding-left:20px属性,使得文字向右偏移20个字节。

 

在使用了iCheck之后,checkbox和文字是这样的:

Yii2 —— 实现自己的iCheck资源包

iCheck初始化后,将原来的input控件外面又包了一层div,导致input控件和文字被label视作一个整体,使得“padding-left:20px”属性也作用到div上,使得checkbox和文字都被右移20px

1.1.2.2解决办法

检查label控件的属性,发现这个“padding-left:20px”属性是forms.less中定义的,这个less文件是bootstrap的,所以直接修改这个文件不是个好主意。

 

最终确定在资源包内修改如下:

public function registerAssetFiles($view)
 {
     
parent::registerAssetFiles($view);
 
     
$view->registerJs(
         
'$("input").iCheck({
             checkboxClass:  "icheckbox_minimal-blue",
             radioClass:  "iradio_minimal-blue",
             increaseArea:  "20%" // optional
         });
        
 $(".icheckbox_minimal-blue").css("margin-left",  "-20px");
          $(".iradio_minimal-blue").css("margin-left",  "-20px");
'
     
);
 
}

 

1.1.3  支持多样式

支持iCheck的多个样式,也是在资源包里实现:

1、首先定义样式名称:

<?php
 

 
namespace backend\assets;
 
 use 
yii\web\AssetBundle;
 
 class 
ICheckAsset extends AssetBundle
 {
     
const SKIN_ALL 'all';
     const 
SKIN_FLAT 'flat/_all';
     const 
SKIN_FLAT_AERO 'flat/aero';
     const 
SKIN_FLAT_BLUE 'flat/blue';
     const 
SKIN_FLAT_FLAT 'flat/flat';
     const 
SKIN_FLAT_GREEN 'flat/green';
     const 
SKIN_FLAT_GREY 'flat/grey';
     const 
SKIN_FLAT_ORANGE 'flat/orange';
     const 
SKIN_FLAT_PINK 'flat/pink';
     const 
SKIN_FLAT_PURPLE 'flat/purple';
     const 
SKIN_FLAT_RED 'flat/red';
     const 
SKIN_FLAT_YELLOW 'flat/yellow';
     const 
SKIN_FUTURICO 'futurico/futurico';
     const 
SKIN_LINE 'line/_all';
     const 
SKIN_LINE_AERO 'line/aero';
     const 
SKIN_LINE_BLUE 'line/blue';
     const 
SKIN_LINE_GREEN 'line/green';
     const 
SKIN_LINE_GREY 'line/grey';
     const 
SKIN_LINE_LINE 'line/line';
     const 
SKIN_LINE_ORANGE 'line/orange';
     const 
SKIN_LINE_PINK 'line/pink';
     const 
SKIN_LINE_PURPLE 'line/purple';
     const 
SKIN_LINE_RED 'line/red';
     const 
SKIN_LINE_YELLOW 'line/yellow';
     const 
SKIN_MINIMAL 'minimal/_all';
     const 
SKIN_MINIMAL_AERO 'minimal/aero';
     const 
SKIN_MINIMAL_BLUE 'minimal/blue';
     const 
SKIN_MINIMAL_GREEN 'minimal/green';
     const 
SKIN_MINIMAL_GREY 'minimal/grey';
     const 
SKIN_MINIMAL_LINE 'minimal/minimal';
     const 
SKIN_MINIMAL_ORANGE  'minimal/orange';
     const 
SKIN_MINIMAL_PINK 'minimal/pink';
     const 
SKIN_MINIMAL_PURPLE  'minimal/purple';
     const 
SKIN_MINIMAL_RED 'minimal/red';
     const 
SKIN_MINIMAL_YELLOW  'minimal/yellow';
     const 
SKIN_POLARIS 'polaris/polaris';
     const 
SKIN_SQUARE 'square/_all';
     const 
SKIN_SQUARE_AERO 'square/aero';
     const 
SKIN_SQUARE_BLUE 'square/blue';
     const 
SKIN_SQUARE_GREEN 'square/green';
     const 
SKIN_SQUARE_GREY 'square/grey';
     const 
SKIN_SQUARE_LINE 'square/square';
     const 
SKIN_SQUARE_ORANGE 'square/orange';
     const 
SKIN_SQUARE_PINK 'square/pink';
     const 
SKIN_SQUARE_PURPLE 'square/purple';
     const 
SKIN_SQUARE_RED 'square/red';
     const 
SKIN_SQUARE_YELLOW 'square/yellow';
 
     public static 
$skin 'all';
 
     public 
$basePath '@webroot';
     public 
$baseUrl '@web';
     public 
$css = [
         
'front-lib/icheck/skins/all.css',
     
];
     public 
$js = [
         
'front-lib/icheck/icheck.min.js',
     
];
     public 
$depends = [
         
'yii\web\JqueryAsset',
         
'yii\bootstrap\BootstrapAsset',
     
];
 
 
    public function registerAssetFiles($view)
     {
         
parent::registerAssetFiles($view);
 
         
$view->registerJs(
             
'$("input").iCheck({
                 checkboxClass:  "icheckbox_minimal-blue",
                 radioClass:  "iradio_minimal-blue",
                 increaseArea:  "20%" // optional
             });
              $(".icheckbox_minimal-blue").css("margin-left",  "-20px");
              $(".iradio_minimal-blue").css("margin-left",  "-20px");'
         
);
     
}
 }

 

2、初始化时载入指定的CSS文件:

 

<?php
 

 
namespace backend\assets;
 
 use
yii\web\AssetBundle;
 
 class
ICheckAsset extends AssetBundle
{
 
    public static $skin = self::SKIN_MINIMAL_BLUE;
 


     public 
$basePath '@webroot';
     public 
$baseUrl '@web/front-lib/icheck';
     public 
$depends = [
         
'yii\web\JqueryAsset',
         
'yii\bootstrap\BootstrapAsset',
     
];
 
     
/**
      * @inheritdoc
      
*/
     
public function init()
     {
         parent::init();
         $this->css = [
             'skins/' . self::$skin  . '.css',
         ];
         // detect is debug mode and  select uncompressed js file
         $jsFile = YII_DEBUG ?  'icheck.js' : 'icheck.min.js';
         $this->js = [
             $jsFile,
         ];
     }
 
}

 

3、根据设置的样式名称初始化checkbox控件:

public function registerAssetFiles($view)
 {
     
parent::registerAssetFiles($view);
 
     
$cssClassSuffix = str_replace('/''-'self::$skin);
     
$view->registerJs(
         
'$("input").iCheck({
             checkboxClass:  "icheckbox_' 
$cssClassSuffix '",
             radioClass: "iradio_' 
$cssClassSuffix '",
             increaseArea:  "20%" // optional
         });
         $(".icheckbox_' 
$cssClassSuffix '").css("margin-left",  "-20px");
         $(".iradio_' 
$cssClassSuffix '").css("margin-left",  "-20px");'
     
);
 
}

 

这样,就封装好了,想要什么样式,就配置这个包里的$skin参数即可。

1.1.4  按需载入

实现上一节的支持多样式,其实同时也实现了按需载入的功能,参见下图:

Yii2 —— 实现自己的iCheck资源包

1.1.5  可复用

iCheck是个很常用的前端库,前面是只将其放到了backend端,其实frontend端也很有可能会用到,因此再进一步,可以把iCheck放到框架层,使其可以更好的被复用:

1、vendor下建立frontlib子目录,然后将icheck包拷贝进去,目录结构如下:

Yii2 —— 实现自己的iCheck资源包

 

2、将前面实现的ICheckAsset.php也转到这个目录下(如上图);

3、打开ICheckAsset.php,修改代码:

/*public $basePath =  '@webroot';
 public $baseUrl = '@web/frontlib/icheck';*/
 
public $sourcePath '@vendor/frontlib/icheck';

即注释掉$basePath$baseUrl的赋值,改为对$sourcePath初始化,根据Yii文档,$basePath$baseUrl参数是不能跟$sourcePath共存。Yii在运行时,会根据$sourcePath所指定的路径,将资源文件拷贝到assets目录下。

4、在使用iCheck资源的地方,修改代码如下:

class AppAsset extends AssetBundle
 {
     
public $basePath '@webroot';
     public 
$baseUrl '@web';
     public 
$css = [
         
'css/site.css',
         
'css/common.css',
         
'css/login.css',
     
];
     public 
$js = [
     ]
;
     public 
$depends = [
         
'vendor\frontlib\icheck\ICheckAsset',
         
'yii\web\YiiAsset',
         
'yii\bootstrap\BootstrapAsset',
     
];
 
}







本文转自 tywali 51CTO博客,原文链接:http://blog.51cto.com/lancelot/1880958,如需转载请自行联系原作者