混合开发问题

样式适配问题

在这里插入图片描述
同一页面,同一元素,展示出左右2中形态(华为mate30pro设备分辨率1176*2400,宽度单位使用的rem)。

大家思考下,为什么会有这个问题?

引申一下

像素分类:设备像素和CSS像素

  1. 设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的
  2. CSS像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在CSS和javascript中使用的一个抽象的层
  3. 每一个CSS声明和几乎所有的javascript属性都使用CSS像素,因此实际上从来用不上设备像素 。

在桌面端,css的1个像素往往都是对应着电脑屏幕的1个物理像素

​
手机端,由于屏幕尺寸的限制,缩放是经常性的操作。

缩小操作时,一个设备像素覆盖了多个CSS像素

放大操作时,一个CSS像素覆盖了多个设备像素

​ 不论缩小或放大,元素设置的CSS像素(如width:300px)是始终不变的,而一个CSS像素对应多少个设备像素是根据当前的缩放比例来决定的。

在HTML中不得不提到viewport,经常会设置viewport的width=device-width,那这个device-width的值是多少呢?

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>  

​ 在iphone5下device-width=320,iphone6下是375,iphone6+下是414。

DPR:

	设备像素比DPR(devicePixelRatio)是默认缩放为100%的情况下,设备像素和CSS像素的比值

dpr,也被成为device pixel ratio,即物理像素与逻辑像素的比,那也就不难理解:iphone6下dpr=2,iphone6+下dpr=3(考虑的是栅格化时的像素,并非真实的物理像素;
在这里插入图片描述

问题原因:

​ 由于华为浏览器版本问题,低版本华为浏览器支持最小像素为12px,高版本则无限制。

如何规避类似问题:

​ 采用postcss-pxtorem 和 flexible
​ postcss-pxtorem作用:将px转换为rem
flexible 作用:计算根font-size (flexible.js

postcss-pxtorem使用方法:

main.js中
// 引入 flexible 用于设置 rem 基准值
import 'lib-flexible/flexible.js';
.postcssrc.js配置
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    'postcss-pxtorem': {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 117.6;(width/10)
      },
      "propList": ['*'],
    "selectorBlackList": ['.norem']  // 过滤掉 .norem 开头的 class,不进行转换
    }
  }
}

1px 边框(vant)

<!-- 上边框 --> 
<div class="van-hairline--top"></div>
移动端1px实现方案( https://zhuanlan.zhihu.com/p/100752129 )

性能优化

路由懒加载

一、定义

​ 懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。

二、写法

常用的懒加载方式有两种:即使用vue异步组件ES中的import

未懒加载写法:import index from '@/pages/index/index.vue';
懒加载写法1const index = () => import('@/pages/index/index.vue');
	routes: [
    {
      path: '/',
      name: 'index',
	  component:index
	}]
懒加载写法2
	routes: [
    {
      path: '/',
      name: 'index',
      component: resolve=>(require(["@/pages/index/index.vue"],resolve))
    }]
三、打包后区别

未做懒加载dist包中js文件夹
在这里插入图片描述
修改为懒加载dist包中js文件夹
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-se2SOEwe-1640224085403)(C:\Users\0oo0\Desktop\技术分享\懒加载.jpg)]

图片压缩(https://tinypng.com/)

开启gzip

一、配置

config/index.js/productionGzip: true (打包效果如上图)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d6aC5y2e-1640224085403)(C:\Users\0oo0\Desktop\技术分享\开启gzip.jpg)]

二、效果

在这里插入图片描述
在这里插入图片描述
​ 当 HTML 文档解析完成就会触发 DOMContentLoaded,而所有资源加载完成之后,load事件才会被触发。 jQuery 中经常使用的 $(document).ready(function() { // …代码… }); 其实监听的就是 DOMContentLoaded 事件,而 $(document).load(function() { // …代码… }); 监听的是 load 事件。

三、使用安卓壳cdr缓存

在这里插入图片描述
在这里插入图片描述

组件按需加载

一、vant按需加载

在这里插入图片描述

二、echarts按需加载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbvRgKC1-1640224085405)(C:\Users\0oo0\Desktop\技术分享\echarts1.jpg)]
main.js中
在这里插入图片描述

使用cdn缓存(网络限制未使用)

一、资源引入

在index.html中,添加CDN资源,例如bootstrap上的资源:

 <body>
	<div id="app"></div>
	<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
	<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
</body>
二、添加配置

在bulid/webpack.base.conf.js文件中,增加externals,将引用的外部模块导入,如下:

module.exports = {
	entry: {app: './src/main.js'},
	externals:{'vue': 'Vue','vue-router': 'VueRouter'}
}
三、去掉原有的引用

去掉import、去掉Vue.use(XXX)等如:

// import Vue from 'vue'
// import Router from 'vue-router'
// Vue.use(Router)

交互优化

一、增加超时时间

ajax.js中,

ajax.defaults.timeout = 10000;

二、增加超时提示

ajax.js后置拦截器error中,增加

	if (error && error.stack.indexOf('timeout') > -1) {
       		Toast.fail({message: '连接超时,请检查你的网络'});} 
		else if (error && error.stack.indexOf('Network Error') > -1) {        
			Toast.fail({ message: '当前网络不可用,请检查你的网络'});    
	}

weixin-js-sdk用法

npm i -S weixin-js-sdk

使用

//引入
import wx from 'weixin-js-sdk';
//请求接口获取jsapi_ticket
const params = {
    //当前页面url
    url:location.href.split('#')[0],
    //随机字符串
    noncestr:Math.random().toString(36)
    .substr(2, 15),
    //时间戳
    timestamp:parseInt(new Date().getTime() / 1000)
};
//接口返回票据后注册
   wx.config({
       debug: false,
       appId: 'wld341060039',
       timestamp:params.timestamp,
       nonceStr: params.noncestr,
       signature: res.ticket,
       //注册事件 选择照片/拍照  获取本地照片数据
       jsApiList: ['chooseImage', 'getLocalImgData']
   	});
    // 通过ready接口处理成功验证
    wx.ready(function () {
        console.log(666);
    });
    // 通过error接口处理失败验证
    wx.error(function (res) {
        console.log('error', res);
    });
    // 判断当前客户端版本是否支持指定JS接口
    wx.checkJsApi({
        // 需要检测的JS接口列表,所有JS接口列表见附录2,
        jsApiList: ['chooseImage', 'getLocalImgData'],
        success: function (res) {
            console.log(res);
            // 以键值对的形式返回,可用的api值true,不可用为false
            // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
        }
	});

拍照或从手机相册中选图接口

wx.chooseImage({
    count: 1, // 默认9
    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
    quality: 0.8, //压缩质量,范围0~1,数值越小,质量越低,压缩率越高(仅对jpg有效)
    success: function (res) {
    	// 返回选定照片的本地ID列表(绝对路径),localId可以作为img标签的src属性显示图片
   		 var localIds = res.localIds; 
    }
});

获取本地图片接口

wx.getLocalImgData({
    localId: '', // 图片的localID
    success: function (res) {
    //localData是图片的base64数据,可以用img标签显示
    let localData = res.localData;
    //ios与安卓兼容问题
    if (localData.indexOf('data:image') != 0) {
        // 判断是否有这样的头部
        localData = `data:image/jpeg;base64,${localData}`;
        }
        localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg'); 
    }
});

ios压缩图片问题

图片压缩方法
 cutImageBase64(base64, w, callback) {
      const newImage = new Image();
      let quality = 0.6; // 压缩系数0-1之间
      newImage.src = base64;
      newImage.setAttribute('crossOrigin', 'Anonymous'); // url为外域时需要
      let imgWidth, imgHeight;
      newImage.onload = function () {
      imgWidth = this.width;
      imgHeight = this.height;
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      if (Math.max(imgWidth, imgHeight) > w) {
          if (imgWidth > imgHeight) {
                  canvas.width = w;
                  canvas.height = w * imgHeight / imgWidth;
              } else {
                  canvas.height = w;
                  canvas.width = w * imgWidth / imgHeight;
              }
          } else {
              canvas.width = imgWidth;
              canvas.height = imgHeight;
              quality = 0.6;
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
      let base64 = canvas.toDataURL('image/jpeg', quality); // 压缩语句
      // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
      while (base64.length / 1024 > 150) {
          quality -= 0.01;
          base64 = canvas.toDataURL('image/jpeg', quality);
      }
      // 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
      while (base64.length / 1024 < 50) {
          quality += 0.001;
          base64 = canvas.toDataURL('image/jpeg', quality);
      }
      	// 必须通过回调函数返回,否则无法及时拿到该值
      	callback(base64);
      };
  }
使用压缩图片
this.cutImageBase64(base64, 700, this.uploadImgbas);
压缩后的数据
uploadImgbas(base64) {	console.log(base64)}
ios注意事项

在IOS中,canvas绘制图片是有两个限制的:
  首先是图片的大小,如果图片的大小超过两百万像素,图片也是无法绘制到canvas上的,调用drawImage的时候不会报错,但是你用toDataURL获取图片数据的时候获取到的是空的图片数据。
  再者就是canvas的大小有限制,如果canvas的大小大于大概五百万像素(即宽高乘积)的时候,不仅图片画不出来,其他什么东西也都是画不出来的。
  应对上面两种限制,我把图片宽度、高度压缩控制在1000px以内,这样图片最大就不超过两百万像素了。在前端开发中,1000px*1000px基本可以满足绝大部分的需求了。当然了还有更完美的瓦片式绘制的方法,我们这里就说瓦片式绘制方法了。
  如此一来就解决了IOS上的两种限制了。

除了上面所述的限制,还有两个坑,一个就是canvas的toDataURL是只能压缩jpg的,当用户上传的图片是png的话,就需要转成jpg,也就是统一用canvas.toDataURL(‘image/jpeg’, 0.5) , 类型统一设成jpeg,而压缩比就自己控制了。

另一个就是如果是png转jpg,绘制到canvas上的时候,canvas存在透明区域的话,当转成jpg的时候透明区域会变成黑色,因为canvas的透明像素默认为rgba(0,0,0,0),所以转成jpg就变成rgba(0,0,0,1)了,也就是透明背景会变成了黑色。解决办法就是绘制之前在canvas上铺一层白色的底色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值