从css、js到scss、ts

1,292 阅读5分钟

更新技术栈vue + typeScript + scss

typeScript

文件分离

刚开始使用ts确实特别难受呀,写法规定怎么那么多,还老出现红色波浪线。
但是ts确实好用啊,自动导包、格式校验。

遵循views文件夹中尽可能少的原则,尽量将页面组件化。
将vue文件拆分成vue、ts、scss文件,在vue文件中引入ts与scss。

<!--  
├── home // home页面文件
│   ├── Home.vue
│   ├── Home.ts
│   ├── Home.scss
-->
 <script src="./Home.ts"></script>
<style lang="scss" scoped src="./Home.scss"></style>

在ts文件中

import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import HomeController from '@/siteScript/HomeController';
@Component
export default class Home extends Vue {
    private mounted() {
     this.trend('/trend');
  }
   private trend(params: string) {
     HomeController.getUrl(params).then((data) => {		//调用接口
      let res = Decrypt(data);	//Decrypt为加密解密方法 可忽略
       console.log(res);
     });
   }
}
  //HomeController文件 controller层AxiosHelper将axios请求方法封装
import AxiosHelper from '@/server/helper/axiosHelper';
export default class HomeController {
  public static getUrl<T>(url: string): Promise<T> {
    return new Promise((fulfill, reject) => {
      AxiosHelper.Get(url)
        .then((res) => {
          fulfill(<any> res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

在引入scss时,不太建议使用@import方法引入。一般页面都需要加上scoped,对于@import而言依旧是全局。只有src方法才是局部作用。

配置部署环境

我接触过主要两种部署方法:
1. 使用环境变量,进行判断开发环境和部署环境:
在文件根目录下新建.env.development和.env.production文件。
// .env.development 开发环境访问后端ip
VUE_APP_BASE_API=http://192.168.1.106:8080/
APP_NAME=pcsjw
// .env.production 部署环境访问后端ip
VUE_APP_BASE_API=http://15.168.1.106:8080/
APP_NAME=pcsjw

配置好后,在创建axios时加上环境变量的ip。

const service = axios.create({  //创建一个请求
  //访问的api地址
  baseURL: process.env.VUE_APP_BASE_API, //请求后端的ip
  //超时时间
  timeout: 5000 // request timeout
})

在vue中默认使用开发环境下的ip,在run build后就会使用production下的变量。
在此,配置测试环境以此类推。
2. 在我接触ts后,学到的另一种方法:
可以在public下的static文件夹下建立config.js文件

 // 实际部署的地址
VUE_APP_BUILD_BASE_API='http://15.240.15.101:9501/'
//开发环境
VUE_APP_DEV_BASE_API='http://192.168.1.106:8080/'

接着在src目录下建立一个配置文件config.ts

  export default class Config {
    static get isDevelopment(): boolean {
        return process.env.NODE_ENV === 'development';
    }
    static get RequestInfoUrl(): string {
        return this.isDevelopment
        ? (window as any).VUE_APP_DEV_BASE_API
        : (window as any).VUE_APP_BUILD_BASE_API;
    }
}

然后在调用后端接口的地方添加

import Config from '@/config';
const GlobalAxios = new MKAxios();	//MKAxios创建axios的类
GlobalAxios.Initialize({
  usesbp: true,
  config: {
    baseURL: Config.RequestInfoUrl,
    timeout: 10000,
    headers: {
      'Cache-Control': 'no-cache',
      'Pragma': 'no-cache',
      'Expires': -1
    }
  }
});

此外,经常会遇到get请求后携带参数的请求格式。 http://192.168.1.106:8080/eventcount?areaCode=32000320000而一般传入是以json格式传入。可以将json转为key=value的方法封装成公用的类。

  export default class PublicGet {
  public static GetString(data: any) {
    let tempArr = [];
    // tslint:disable-next-line: forin
    for (let i in data) {
      let key = encodeURIComponent(i);
      let value = encodeURIComponent(data[i]);
      tempArr.push(key + '=' + value);
    }
    let urlParamsStr = tempArr.join('&');
    return urlParamsStr;
  }
}

scss

全局scss文件

根目录创建vue.config.js文件,该文件可配置webpack打包相关项。

const webpack = require('webpack');
module.exports = {
  transpileDependencies: ['vue-class-component'],
  configureWebpack: {
  },
  chainWebpack: config => {
    config
      .entry('index')
      .add('@babel/polyfill')
      .end();
  //引入scss全局文件 方法一
    const scssRes = config.module.rule('scss').oneOfs.store;
    scssRes.forEach(item => {
      item
      .use("sass-resource-loader")
        .loader('sass-resources-loader')
        .options({
          resources: './src/assets/_variable.scss'	//全局scss路径
        }).end();
    })
  },
  //引入全局scss 方法二
  // css: {
  //   loaderOptions: {
  //     scss: {
  //       additionalData: `@import "@/assets/_variable.scss";`
  //     },
  //   }
  // },
  publicPath: '/' + process.env.APP_NAME,
  outputDir: "dist",
  assetsDir: 'static',
  devServer: {
    port: 53250,
    https: false
  }
}

在此,推荐方法一的引入,方法二在引入时,会将每个需要的文件都导入全局scss文件,造成浪费。

scss变量

在全局的scss文件中,可以定义一些局部文件使用率较高的css代码段。
比如占位符:
  %displaycenter {
  display        : flex;
  justify-content: center;
  align-items    : center;
}

混合宏:

  /*宽高*/
@mixin Mwh($width:100%, $height:100%) {
  height: $height;
  width : $width;
}

在组件样式中就可以直接使用这些样式。

.body{
  @extend %displaycenter;
  @include Mwh(100%, 100%);
}

css自适应兼容

最近,有做到大屏的项目,接触到最大的问题就是自适应问题。
刚开始做的时候,是使用百分比,但是后来发现百分比不能拥有固定的宽高,对于边距、居中等存在一定的问题。后来确定使用vh、vw。
其实接触vh、vw已经好久了,以前都是登录、首页使用100vh、100vw,但是它的真实用处是自适应啊!
在全局样式中可以设置它的自适应字体。比如:
假如最终要在3820*1620的屏幕上显示,设计图上的64px字体,就可以使用vh表示。
  p{
  //1vh == 16.2px
	font-size:3.95vh;	//字体64px
  }

关于兼容性问题,最近被ie浏览器搞得头昏脑涨。

  1. ie动画不支持更换背景图片
    在实现每隔几秒高亮一个div的特效时,ie成功不兼容。(尴尬而不失礼貌的微笑)
    css方法:
@keyframes show1 {
20% {
  //高亮样式
}

50% {
  //normal
}
}
div{
-webkit-animation: show1 12s ease infinite;
-moz-animation   : show1 12s ease infinite;
-o-animation     : show1 12s ease infinite;
animation        : show1 12s ease infinite;
animation-delay  : 0s;
}

div动画时长12s 在2s(12*20%)左右后不高亮显示。假设有6个div轮流高亮,在第二个div是可以设置animation-delay属性延迟2s,第三个延迟4s...这样css就可以实现div轮流高亮的效果,但是一旦设计背景图片的切换时,ie浏览器基本就没效果了。
针对于背景图片,可以使用定时器,轮流定时几秒给一个div加上高亮样式,其他div恢复normal样式。

  private lightImg() {
    let i = 0;
    this.timmer = setInterval(() => {
      this.lightHight = ['', '', '', '', '', ''];	//6个div normal样式
      this.lightHight[i] = 'lighthight';	//一个高亮
      i++;
      if (i >= 6) {
        i = 0;
      }
    }, 2000);
  }
  1. ie不支持渐变字体
    可以使用svg方法.将svg渐变字体封装成组件。
  <template>
  <div class="preliminary">
    <svg>
      <defs>
        <linearGradient id="grad" x1="50%" y1="0%" x2="50%" y2="100%">
          <stop
            offset="0%"
            :style="'stop-color:' + startColor + '; stop-opacity:1'"
          />
          <stop
            offset="100%"
            :style="'stop-color:' + endColor + '; stop-opacity:1'"
          />
        </linearGradient>
      </defs>
      <text x="0" y="0" fill="url(#grad)">	//可以通过控制xy实现字体所在svg区域的位置
        {{ text }}
      </text>
    </svg>
  </div>
</template>
  1. ie对于body或html加上层级,将覆盖住内部元素,致使内部鼠标悬浮、点击等事件无法触发。
body{
  	position: relative;
  	z-index: -2;		
 }

chrome中body将会定位,至于-2层。但是在ie上body会覆盖住内部元素。在ie情况下,谨慎使用z-index。