Next框架与主流工具的整合(二)—— 完善与优化

栏目: CSS · 发布时间: 5年前

内容简介:前言:18年12月24日项目成功上线了,在经历了两周的线上bug、UI以及代码优化后,解决了不少问题,于是再完善与优化一下这个布局优化在这篇文章完成了 → [移动端优雅布局实践](),最后我使用的方案是——开始项目之前没有对dpr(device pixel radio)与缩放做过多的了解,在项目开发的时候就将它们都直接写死为1了。到后来UI验收的时候发现并没有实现UI设计师预期的细线效果。我在解决这个问题的时候才去认真看了一下dpr的介绍。

前言:18年12月24日项目成功上线了,在经历了两周的线上bug、UI以及代码优化后,解决了不少问题,于是再完善与优化一下这个 项目

  • 布局优化
  • 高清配置
  • antd-mobile 自定义配置
  • antd-mobile Toast组件封装

布局优化

布局优化在这篇文章完成了 → [移动端优雅布局实践](),最后我使用的方案是—— absolute脱离文档流 (好处是设置容器的 height: 100% ,可以直接继承html窗口高度)。

高清配置

问题发现

开始项目之前没有对dpr(device pixel radio)与缩放做过多的了解,在项目开发的时候就将它们都直接写死为1了。到后来UI验收的时候发现并没有实现UI设计师预期的细线效果。我在解决这个问题的时候才去认真看了一下dpr的介绍。 这篇详解dpr的文章 写得还不错。

从概念来说,dpr就是设备的物理像素与设备独立像素(也就是css逻辑像素,以下就称为css逻辑像素)的比率。

比如:iPhone 6的分辨率是750*1334, window.screen.width (css逻辑像素)为375,因此

dpr = 750 /375 = 2

再比如:iPhone X的分辨率是1125*2436, window.screen.width (css逻辑像素)也是375,因此

dpr = 1125 /375 = 3

那么dpr有什么用呢?

在这之前先提一下我们移动端必备的一个 meta 标签:

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

device-width在html中也同样被解读为理想(基准)视口的宽度,即320px,375px,414px,这里的px就是指css像素,通常也被称为逻辑像素;那我们可以认为html中的css像素的显示尺寸应该和NA中的pt、dp的显示尺寸相等。

通过这个meta标签,我们可以实现 initial-scale=1 初始缩放100%, 就可以达到 1px的css逻辑像素 = 眼睛在设备上看起来的1px ,换句话说 body { width: 375px; } 可以在iPhone 6上充满竖屏的整个宽度

那么问题就来了,如果我们要给一个盒子加上一个1px的细线:

border-bottom: 1px solid red; 。那么在iPhone 6上真的是1px吗?

iPhone 6真机截图(宽度为702px):

Next框架与主流 <a href='https://www.codercto.com/tool.html'>工具</a> 的整合(二)—— 完善与优化

可以看出高度明显不止1像素。这就是由于dpr造成的,因为iPhone 6的dpr为2,且缩放比例为100%,1px的css渲染出来就是2px物理像素。

这就是我们UI粑粑和产品们不满意的地方。

那接下来如何去解决这个问题呢?

解决方案

根据设备的dpr来动态计算缩放比例,以及根节点的 font-size

// rem.js
(function(doc, win) {
  var docEl = doc.documentElement,
    dpr = Math.min(win.devicePixelRatio, 3);
  dpr = window.top === window.self ? dpr : 1; //被iframe引用时,禁止缩放
  var scale = 1 / dpr,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
  docEl.dataset.dpr = dpr;
  var metaEl = doc.createElement('meta');
  metaEl.name = 'viewport';
  metaEl.content =
    'initial-scale=' +
    scale +
    ',maximum-scale=' +
    scale +
    ', minimum-scale=' +
    scale +
    ',user-scalable=no,viewport-fit=cover';
  docEl.firstElementChild.appendChild(metaEl);
  var recalc = function() {
    var width = docEl.clientWidth;
    // 大于1280按1280来算
    if (width / dpr > 1280) {
      width = 1280 * dpr;
    }
    // px : rem = 100 : 1
    docEl.style.fontSize = 100 * (width / 375) + 'px';
  };
  recalc();
  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
})(document, window);

如果有显示富文本元素,则需要处理富文本元素的样式

移动端为了适配不同的机型,使用 rem 为单位是一个不错的选择,而且我们也一直在用它。

这里除了根据dpr来计算 initial-scale ,还调整了根节点的 font-size ,以至于在缩放的时候能够还原到视窗大小(因为要缩放,所以要相应的增加 rem 的基数)。

这样我们上面写的 border-bottom: 1px solid red; 在这个方案显示出来就是这样的:

Next框架与主流工具的整合(二)—— 完善与优化

哇咔咔,可以看出明显变细了,这才是我们UI粑粑们想要的O(∩_∩)O~~

但是这样的设置在结合 ant-design-mobile 的时候,发现 ant-design-mobile 的组件都被缩小了。原来是,它的元素都是以px为单位,而我们缩放前没有对它的最小单位乘以相应的基数。 那么,我们需要给它配置一个基数

antd-mobile自定义配置

查文档发现 ant-design-mobile 提供了 主题配置 ,而且它提供了一个 @hd 的变量做为长度基本单位,它的默认值是 1px

我们只需要把 @hd 设置为 0.01rem 就可以解决问题。

这个 主题配置 的文档是以webpack项目来做的例子。那如何在 next.js 项目中完成自定义配置呢?

我在 next.js的examples 中没有找到我所需要的example,不过找到了两个相关的例子:一个是 with-antd-mobile ,一个是 with-ant-design-less 。第二个是 ant-design 的自定义主题配置,那应该就可以仿照这个example去增加 with-antd-mobile 的自定义主题配置。

这里提一下,这个 with-antd-mobile 在我写 Next框架与主流工具的整合 之后更新了 next.config.js 的配置,这里也改成了最新的配置。

  1. 安装解析 Lessnormalize.css 的包
npm i @zeit/next-less @zeit/next-css less less-vars-to-js -S
  1. 修改 .babelrc 配置
{
  "presets": ["next/babel"],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd-mobile",
        "style": true
      }
    ]
  ]
}
  1. 修改 next.config.js 配置
/* eslint-disable */
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass');
const withLess = require('@zeit/next-less');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');

// Where your antd-custom.less file lives
const themeVariables = lessToJS(fs.readFileSync(path.resolve(__dirname, './antd-custom.less'), 'utf8'));

// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
  require.extensions['.less'] = file => {};
  require.extensions['.css'] = file => {};
}

module.exports = withCSS(
  withLess(
    withSass({
      lessLoaderOptions: {
        javascriptEnabled: true,
        modifyVars: themeVariables
      }
    })
  )
);
  1. 在项目下新建Less变量文件 antd-custom.less
@hd: 0.01rem;

重启项目,就大功告成了。

antd-mobile Toast组件封装

antd-mobileToast.info() 组件在显示的时候不能点击背景就消失,与原生的Toast有些差异,为了体验,这里再做了一层封装,在点击背景的时候隐藏Toast。

// utils/toast.js
static info = (content, duration, onClose, mask) => {
    Toast.info(content, duration, onClose, mask);
    const toastElement = document.getElementsByClassName('am-toast-mask')[0];
    toastElement &&
      toastElement.addEventListener('click', () => {
        Toast.hide();
        onClose && onClose();
      });
  };

antd-mobile 的loading图在Android上有些怪异,这里也自定义了Loading:

static loading = (content, duration, onClose, mask) => {
    Toast.info(
      <div>
        <svg className="rotate360-800" width="0.26rem" height="0.26rem" viewBox="0 0 26 26">
          <title>加载</title>
          <desc>Created with Sketch.</desc>
          <g id="首页" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
            <g transform="translate(-185.000000, -519.000000)" fill="#FFFFFF" id="加载">
              <g transform="translate(185.000000, 519.000000)">
                <g id="分组" transform="translate(0.625011, 0.625011)">
                  <path
                    d="M12.3750144,0.0259531552 C5.53983848,0.0259531552 0,5.56600648 0,12.4009676 C0,19.2359286 5.53983848,24.775982 12.3750144,24.775982 C19.2099755,24.775982 24.7500288,19.2359286 24.7500288,12.4009676 C24.7500288,5.56579163 19.2099755,0.0259531552 12.3750144,0.0259531552 Z M12.3750144,22.028385 C7.05736759,22.028385 2.74781179,17.7185714 2.74781179,12.4009676 C2.74781179,7.08332074 7.05741056,2.7735501 12.3750144,2.7735501 C17.6926612,2.7735501 22.0026467,7.08336371 22.0026467,12.4009676 C22.0026467,17.7186144 17.6926182,22.028385 12.3750144,22.028385 Z"
                    id="形状"
                    fillOpacity="0.2"
                    fillRule="nonzero"
                  />
                  <path
                    d="M12.3749972,0.0259402646 L12.3750144,2.77353721 C17.6926612,2.77353721 22.0026467,7.08335082 22.0026467,12.4009547 L24.7500116,12.4009547 C24.7500116,5.56577874 19.2099583,0.0259402646 12.3749972,0.0259402646 Z"
                    id="路径"
                  />
                </g>
              </g>
            </g>
          </g>
        </svg>
        <div style={{ fontSize: '0.12rem' }}>{content}</div>
      </div>,
      duration,
      onClose,
      mask
    );
  };

写在最后

一个项目需要在不断的优化与完善中才能变得更好。搭建项目是对一个项目负责人很大的考验,如果在项目设计的初期有许多的问题没有考虑到,就很有可能导致优化的时候需要耗费很大的精力。

总之,不要逃避困难与问题,这些都是成长路上不可或缺的。


以上所述就是小编给大家介绍的《Next框架与主流工具的整合(二)—— 完善与优化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

跨平台桌面应用开发:基于Electron与NW.js

跨平台桌面应用开发:基于Electron与NW.js

【丹】Paul B. Jensen / Goddy Zhao / 2018-3 / 99

《跨平台桌面应用开发:基于Electron与NW.js》是一本同时介绍 Electron和 NW.js的图书,这两者是目前流行的支持使用 HTML、CSS 和 JavaScript 进行桌面应用开发的框架。书中包含大量的编码示例,而且每个示例都是五脏俱全的实用应用,作者对示例中的关键代码都做了非常详细的解释和说明,可让读者通过实际的编码体会使用这两款框架开发桌面应用的切实感受。除此之外,在内容上,......一起来看看 《跨平台桌面应用开发:基于Electron与NW.js》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换