Liaoct / blog

在这里记录一些个人经验与思考
22 stars 2 forks source link

根据参数动态换肤办法 #4

Open ghost opened 7 years ago

ghost commented 7 years ago

根据参数动态换肤办法

针对目前赢财富动态换肤办法,我与兴邦暂时想到三种办法。

第一种方法:多入口文件方法

第一种办法,也是最原始的办法,不同渠道入口提供不同HTML,如:index.qd1.html,index.qd2.html,然后在每个HTML中分别引入对应的样式文件。

对于赢财富中的公共样式,还是通过原有的webpack打包样式。而对于需要需要动态维护的多套样式文件可以通过gulp或者webpack分别打包,然后生成不同的css文件。

也可以在app.js入口文件中,分别改变对应的引入方法,然后打包生成分离的css文件。

这种方式,目前还没有试验过。

优点:

缺点:

第二种方法:组件级别换肤

第二种办法,是在组件级别做思考,这种方式也没有试验过,要在组件级别做工,可能会需要较大的精力和时间。具体思考过程如下:

组件,就是封装的一个整体,它具有自己的样式和接口。按照react或者vuejs或者其他的组件库的概念,一个组件中,应该包含的是它自己的样式,可以通过css in js 或者css module的方式来引入它的样式。也就是会形成如下的结构形式:

|--compoent
    |--button
        |--button.js
        |--button.css
    |--header
        |--header.js
        |--header.css

组件的css代码可能如下:

.header{/*common样式*/}
.header-qd1{compose:header,/*第一套样式*/}
.header-qd2{compose:header,/*第二套样式*/}

然后在每个组件中分别引入它所对应的css:

import React from 'react';
import styles from './header.css';//引入样式

export default class Table extends React.Component {
    **(){
        //获得样式参数,可以来自props,可以其他途径控制
        var type = this.props.type || "classic";
        //根绝参数切换需要加载的css样式名。这里有点像css in js
        var classNames = {
            header : type === 'classic' ? "header-qd1" : "header-qd2",
            ...
        }
    }
    render () {
        //这里,我是纯手写的,没有通过实际测试
        return <div className={styles[classNames.header]}>
            <div className={}>
                <div className={}>A0</div>
                <div className={}>B0</div>
            </div>
        </div>;

    }
}

优点:

缺点:

第三种方法:webpack动态加载

第三种方法,也是现在我唯一试验过的方法。就是JS入口文件中,判断当前的条件(比如参数),然后动态加载相应的样式文件,关键代码如下:

//获得参数条件,生成需要加载的样式名称。此处我判断URL参数中的type属性值
var name = location.search.indexOf('type=classic') > -1 ? "classic" : "cupertino";
//使用require.ensure实现动态加载。其实是,每个文件都会被加载,只是不会被执行。这些文件最终会被打包到一个JS文件。
require.ensure(['../asset/sasstest/classic.scss','../asset/sasstest/cupertino.scss'], function() {
    //根据参数条件动态加载。实际是,动态执行对应的模块
    require('../asset/sasstest/'+name+'.scss');
});

在这里,我假设我有两套不同的样式文件classic.scss和cupertino.scss:

classic.scss的内容如下:

#main{
    background-color: red;
}

cupertino.scss的内容如下:

#main{
    background-color: #2d672d;
}

以上代码在打包的时候实际会根据webpack中publicPath生成一个js文件。

这个文件我们不用手动去引入,只需要引入入口文件生成的bundle.js就行。实际运行如下:

上面截图中的JS文件和style都是自动生成不需要我们去手动引入。打开生成的JS文件:

可以看到实际上这两个css文件都被打包到了同一个JS文件中。由此,我们可以推断,我们在require.ensure中动态引入时,就是执行require('../asset/sasstest/'+name+'.scss')时,实际上是在执行上面那个JS文件中对应的模块,执行结果是,在html页面中动态的生成了style标签。

改变URL参数,查看结果:

可以看到,样式切换成功了。

优点:

缺点: