vue大屏项目框架搭建

4,632 阅读5分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

项目介绍

最近两个月完完整整的完成了一个公司大屏展示的项目,从中收获到了许多经验。项目主要涉及到了以下方面:用户中心接入与鉴权、持久化存储、响应式设计、组件化思想与微应用等。

遇到的问题

  • 页面权限判断(权限树的持久化存储,vuex刷新后状态丢失,需要辅助使用localstorage)
  • 打开新标签自动跳转到了登录页(判断了token,但是使用了sessionstorage
  • 页面关闭后重新打开没有记录之前访问页(还是持久化存储的问题)

技术栈

  • 构建工具 @vue/cli
  • 状态管理:vuex
  • 路由:vue-router
  • UI 框架 view-design
  • postcss插件:postcss-px2rem
  • css预处理语言:less
  • 代码规范:eslint

添加可伸缩布局方案

    ! function (window) {
      /* 设计图文档宽度 */
      var docWidth = 1920;
      var doc = window.document,
        docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
      var recalc = (function refreshRem() {
        var clientWidth = docEl.getBoundingClientRect().width;
        docEl.style.fontSize = Math.max(Math.min(20 * (clientWidth / docWidth), 30), 8.55) * 5 + 'px';
        return refreshRem;
      })();

      /* 添加倍屏标识,安卓倍屏为1 */
      docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1);
      if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
        /* 添加IOS标识 */
        doc.documentElement.classList.add('ios');
        /* IOS8以上给html添加hairline样式,以便特殊处理 */
        if (parseInt(window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/)[1], 10) >= 8)
          doc.documentElement.classList.add('hairline');
      }

      if (!doc.addEventListener) return;
      window.addEventListener(resizeEvt, recalc, false);
      doc.addEventListener('DOMContentLoaded', recalc, false);
    }(window);

项目中主要使用了flex布局。由于设计稿是1080 * 1920的大小,还需要兼容在电脑上显示,而在电脑中显示时除去收藏夹等内容,高度是达不到1080的。这部分主要使用了css中的vh单位和calc()方法进行计算。

同时使用postcss,将全局的单位统一成rem。

全局配置

全局配置主要涉及到权限控制,公共样式和公共组件

1. 权限控制分为

  • 登录权限
  • 页面权限(菜单权限 + 按钮权限)
  • 接口权限

登录权限

登录访问权限控制是对用户的校验。在用户登录成功之后,后台将返回一个token,之后前端每次进行接口请求的时候,都要带上这个token。后台拿到这个token后进行判断,如果此token确实存在并且没有过期,则可以通过访问。如果token不存在或后台判断已过期,则会跳转到登录页面,要求用户重新登录获取token。

首先我们调用登录接口,调用成功后我们能够获取到返回数据中的token,我们将token存储到localstorage中(一定不能使用sessionstorage, 因为sessionstorage只能在当前窗口使用,当我们打开新的标签页时会获取不到token,就无法判断是否已经登录)。之后我们在axios的请求拦截器service.interceptors.request.use中将token放入到请求头中

    thisConfig.headers = {
      'Content-Type': 'application/json;charset=utf-8',
      Authorization: window.localStorage.getItem('storagetoken'),
    };

页面权限:

当我们登录后可以通过接口获取用户角色的权限树,这里我们使用vuex + localstorage持久化存储用户权限树。之后我们展示权限树,如果用户通过URL进行强制访问没有权限的页面,在router.beforeEach()中判断权限,无权限直接跳转到404页面。

菜单白名单配置:

我们可以使用路由的meta属性给页面添加白名单权限,如果meta设置了当前页面为所有人都可以访问的话,就直接跳转,不判断是否有权限

按钮权限:

  • 1.每个模块对应有四种权限,查询(get),添加(post),更新(put),删除(delete)

  • 2.利用十进制和二进制来表示当前模块所拥有的权限。1111(15),转换后的二进制与权限的关系表示:从右至左数(1代表拥有该权限,0代表不拥有),第一位代表查询,第二位代表添加,第三位代表更新,第四位代表删除。如eg:二进制1111(15),代表用于查询,添加,更新,删除四种权限。

  • 3.判断对应模块没有此权限时,移除当前按钮dom元素。

接口权限:

最后再加上请求控制作为最后一道防线,路由可能配置失误,按钮可能忘了加权限,这种时候请求控制可以用来兜底,越权请求将在前端被拦截。

2. 公共样式

公共样式主要涉及到

  • 字体,字号
  • 系统主要颜色和背景色
  • 全局变量

3. 公共组件

设计公共组件需要我们先仔细阅读UI的设计图,从中抽离出合适的公共组件。这些组件可以分为偏逻辑的组件偏样式的组件,我们需要使用经验根据设计图来设计组件。

其实就和抽离代码中的公共部分类似,不能把组件设计的过于详细,这样使用起来特别麻烦,最好是能最大程度的完成一个独立的功能模块。

这部分可以看看这篇文章 现代 Web 开发困境与破局 - 牛岱的文章 - 知乎

结尾

到这里我们就能处理掉上面的主要问题了,主要就是持久化存储和权限判断的问题。除此之外,项目中还有其他的收获,下次再谈。