基于Vue的前端架构所实现的技术有哪些

发布时间:2021-10-21 10:42:00 作者:iii
来源:亿速云 阅读:110

这篇文章主要介绍“基于Vue的前端架构所实现的技术有哪些”,在日常操作中,相信很多人在基于Vue的前端架构所实现的技术有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于Vue的前端架构所实现的技术有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1.分解需求

技术栈

建立脚手架

开发规范

2.样式

CSS 预处理器的选择

为什么选择了两个?因为公司团队跟倾向于使用 scss 开发,less 是为了覆盖 ant design vue 的样式,stylus 只有我自己喜欢这种风格。

局部样式与全局样式

局部样式

一般都是使用 scoped 方案:

<style lang="scss" scoped>    ...  </style>  复制代码

全局样式

全局样式 目录:@/styles

variable.scss: 全局变量管理 mixins.scss: 全局 Mixins 管理 global.scss: 全局样式

其中 variable.scss 和 mixins.scss 会优先于 global.css 加载,并且可以不通过 import 的方式在项目中任何位置使用这些变量和 mixins。

// vue.config.js  module.exports = {    css: {      loaderOptions: {        sass: {          prependData: `          @import '@/styles/variable.scss';          @import '@/styles/mixins.scss';          `,        },      },    },  }  复制代码

体验优化

页面载入进度条

使用 nprogress 对路由跳转时做一个伪进度条,这样做在网络不好的情况下可以让用户知道页面已经在加载了:

import NProgress from 'nprogress';  router.beforeEach(() => {    NProgress.start();  });  router.afterEach(() => {    NProgress.done();  });  复制代码

美化滚动条

一直用 Mac 做前端,突然发现同事的 Windows 上出现了十分丑陋的滚动条,为了保持一致:

::-webkit-scrollbar {    width: 6px;    height: 6px;  }  ::-webkit-scrollbar-track {    width: 6px;    background: rgba(#101F1C, 0.1);    -webkit-border-radius: 2em;    -moz-border-radius: 2em;    border-radius: 2em;  }  ::-webkit-scrollbar-thumb {    background-color: rgba(#101F1C, 0.5);    background-clip: padding-box;    min-height: 28px;    -webkit-border-radius: 2em;    -moz-border-radius: 2em;    border-radius: 2em;  }  ::-webkit-scrollbar-thumb:hover {    background-color: rgba(#101F1C, 1);  }  复制代码

静态资源加载页面

首次加载页面时,会产生大量的白屏时间,这时做一个 loading 效果看起来会很友好,其实很简单,直接在 public/index.html 里写一些静态的样式即可。

移动端 100vh 问题

在移动端使用 100vh 时,发现在 Chrome、Safari 浏览器中,因为浏览器栏和一些导航栏、链接栏导致不一样的呈现:

你以为的 100vh === 视口高度

实际上 100vh === 视口高度 + 浏览器工具栏(地址栏等等)的高度

解决方案

安装 vh-check npm install vh-check \--save

import vhCheck from 'vh-check';  vhCheck('browser-address-bar');  复制代码

定义一个 CSS Mixin

@mixin vh($height: 100vh) {    height: $height;    height: calc(#{$height} - var(--browser-address-bar, 0px));  }  复制代码

之后就是哪里不会点哪里。

3.组件库

因为 Element UI 长期没更新,并且之前使用过 React 的 Ant Design(重点),所以组件库选择了Ant Design Vue。

覆盖 Ant Design Vue 样式

设计师眼中的 Ant Design === '丑'(心酸)。

1.使用 .less 文件

Ant Design Vue 的样式使用了 Less 作为开发语言,并定义了一系列全局/组件的样式变量,所以需要安装了 less、less-loader,在 @/styles/antd-theme.less 可以覆盖默认样式。

优点是:

方便快捷,可以修改 class,覆盖默认变量。

缺点是:

必须引入 @import '~ant-design-vue/dist/antd.less'; ,引入后会将所有的组件样式全部引入,导致打包后的 css 体积达到 500kb 左右。

2.使用 JavaScript 对象

通过 JavaScript 对象的方式可以修改内置变量,需要对 Less 进行配置:

// vue.config.js  const modifyVars = require('./src/styles/antdTheme.js');  module.exports = {    css: {      loaderOptions: {        less: {          lessOptions: {            javascriptEnabled: true,            modifyVars,          },        },      },    },  }  复制代码

这一步还可以继续优化,通过 babel-plugin-import 使 Ant Design Vue 的组件样式可以按需加载:

// babel.config.js  module.exports = {    presets: [      '@vue/cli-plugin-babel/preset',    ],    plugins: [      [        'import',        { libraryName: 'ant-design-vue', libraryDirectory: 'es', style: true },      ],    ],  };  复制代码

优点是:

可以按需引入,打包后的 CSS 体积取决于你引用了多少个组件。

缺点是:

不能使用 class 进行样式覆盖。

干掉无用的图标

Ant Design Vue 把所有的 Icon 一次性引入(不管你因用了多少个组件),这使得体积打包后图标所占的体积竟然有几百 kb 之多。这些图标大多数不会被设计师所采纳,所以部分图标都应该被干掉:

创建一个 icons.js 来管理 Ant Design Vue 图标,这里以一个 Loading 图标为例:

// @/src/assets/icons.js  export { default as LoadingOutline } from '@ant-design/icons/lib/outline/LoadingOutline';  复制代码

如何知道你要加载的图标在什么路径下?

在 @ant-design/icons/lib 目录下有三种风格的图标,分别是 fill、outline、twotone,这里面内部的文件并不是 svg 格式,而是 js 和 ts 格式,这就是为什么我们可以这么引入图标的关键所在了。

下一步是通过配置 vue.config.js 将这个文件引入进来:

// vue.config.js  module.exports = {    configureWebpack: {      resolve: {        alias: {          '@ant-design/icons/lib/dist$': path.resolve(__dirname, './src/assets/icons.js'),       },      },    },  }  复制代码

解决 Moment 多国语

解决到这之后,Ant Design Vue 居然还很大,这是因为 moment 是 Ant Design Vue 中有强依赖该插件,所以使用 webpack 插件减小打包体积,这里我们只保留 zh-cn 语言包:

// vue.config.js  module.exports = {    chainWebpack: (config) => {      config        .plugin('ContextReplacementPlugin')        .use(webpack.ContextReplacementPlugin, [/moment[/\\]locale$/, /zh-cn/]);    },  }  复制代码

部分组件需要在页面内引用

Ant Design Vue 中部分体积较大的组件,例如 DatePicker,根据业务需求,应考虑在页面中进行加载,尽量保证首屏加载的速度:

<script>  import { DatePicker } from 'ant-design-vue';  export default {    components: {      ADatePicker: DatePicker,    },  }  </script>  复制代码

4.静态资源与图标

静态资源

所有的静态资源文件都会上传到 阿里云 OSS 上,所以在环境变量上加以区分。

.env.development 与 .env.production 的 VUE_APP_STATIC_URL 属性分别配置了本地的静态资源服务器地址和线上 OSS 的地址。

本地的静态资源服务器是通过 pm2 + http-server 创建的,设计师切完直接扔进来就好了。

自动注册 Svg 图标

在日常的开发中,总是会有着大量的图标需要使用,这里我们直接选择使用 SVG 图标。但是如果每次使用图标还需要通过路径找到这张图标岂不是很麻烦?

下面这种才是我想要的方案(直接 name 等于 文件名即可):

<template>      <svg name="logo" />  </template>  复制代码

而且最后打包后需要合并成一张雪碧图。

首先需要对 @/assets/icons 文件夹下的 svg 图标进行自动注册,需要对 webpack 和 svg-sprite-loader 进行了相关设置,文件全部打包成 svg-sprite。

module.exports = {    chainWebpack: (config) => {      config.module        .rule('svg')        .exclude.add(resolve('src/assets/icons'))        .end();      config.module        .rule('icons')        .test(/\.svg$/)        .include.add(resolve('src/assets/icons'))        .end()        .use('svg-sprite-loader')        .loader('svg-sprite-loader');    },  }  复制代码

写一个全局用的 Vue 组件 <m-svg />:

// @/components/m-svg/index.js

const requireAll = (requireContext) => requireContext.keys().map(requireContext);  const req = require.context('@/assets/icons', false, /\.svg$/);  requireAll(req);  复制代码

@/components/m-svg/index.vue

<template>    <svg class="mw-svg" aria-hidden="true">      <use :xlink:href="iconName"></use>    </svg>  </template>  <script>  export default {    name: 'm-svg',    props: {      name: { type: String, default: '' },    },    computed: {      iconName() {        return `#${this.name}`;     },    },  };  </script>  <style lang="scss" scoped>  .mw-svg {    width: 1.4em;    height: 1.4em;    fill: currentColor;    overflow: hidden;    line-height: 1em;    display: inline-block;  }  </style>  复制代码

参数 name

样式

5.异步请求

封装 Axios

在 @/libs/request.js 路径下对 Axios 进行封装,封装了请求参数,请求头,以及错误提示信息、 request 拦截器、response 拦截器、统一的错误处理、baseURL 设置等。

废话不说直接贴代码:

import axios from 'axios';  import get from 'lodash/get';  import storage from 'store';  // 创建 axios 实例  const request = axios.create({   // API 请求的默认前缀   baseURL: process.env.VUE_APP_BASE_URL,   timeout: 10000, // 请求超时时间  });  // 异常拦截处理器  const errorHandler = (error) => {   const status = get(error, 'response.status');   switch (status) {     /* eslint-disable no-param-reassign */     case 400: error.message = '请求错误'; break;     case 401: error.message = '未授权,请登录'; break;     case 403: error.message = '拒绝访问'; break;     case 404: error.message = `请求地址出错: ${error.response.config.url}`; break;     case 408: error.message = '请求超时'; break;     case 500: error.message = '服务器内部错误'; break;     case 501: error.message = '服务未实现'; break;     case 502: error.message = '网关错误'; break;     case 503: error.message = '服务不可用'; break;     case 504: error.message = '网关超时'; break;     case 505: error.message = 'HTTP版本不受支持'; break;     default: break;     /* eslint-disabled */   }   return Promise.reject(error);  };  // request interceptor  request.interceptors.request.use((config) => {   // 如果 token 存在   // 让每个请求携带自定义 token 请根据实际情况自行修改   // eslint-disable-next-line no-param-reassign   config.headers.Authorization = `bearer ${storage.get('ACCESS_TOKEN')}`;   return config;  }, errorHandler);  // response interceptor  request.interceptors.response.use((response) => {   const dataAxios = response.data;   // 这个状态码是和后端约定的   const { code } = dataAxios;   // 根据 code 进行判断   if (code === undefined) {     // 如果没有 code 代表这不是项目后端开发的接口     return dataAxios;   // eslint-disable-next-line no-else-return   } else {     // 有 code 代表这是一个后端接口 可以进行进一步的判断     switch (code) {       case 200:         // [ 示例 ] code === 200 代表没有错误         return dataAxios.data;       case 'xxx':         // [ 示例 ] 其它和后台约定的 code         return 'xxx';       default:         // 不是正确的 code         return '不是正确的code';     }   }  }, errorHandler);  export default request;  复制代码

跨域问题

跨域问题一般情况直接找后端解决了,你要是不好意思打扰他们的话,可以用 devServer 提供的 proxy 代理:

// vue.config.js  devServer: {    proxy: {      '/api': {        target: 'http://47.100.186.132/your-path/api',        ws: true,        changeOrigin: true,        pathRewrite: {          '^/api': ''        }      }    }  }  复制代码

Mock 数据

一个很常见的情况,后端接口没出来,前端在这干瞪眼。

Mock 数据功能是基于 mock.js (opens new window)开发,通过 webpack 进行自动加载 mock 配置文件。

规则

入口文件

import Mock from 'mockjs';  Mock.setup({    timeout: '500-800',  });  const context = require.context('./services', true, /\.mock.js$/);  context.keys().forEach((key) => {    Object.keys(context(key)).forEach((paramKey) => {      Mock.mock(...context(key)[paramKey]);    }); });  复制代码

示例模板

import Mock from 'mockjs';  const { Random } = Mock;  export default [    RegExp('/example.*'),    'get',    {      'range|50-100': 50,      'data|10': [        {          // 唯一 ID          id: '@guid()',          // 生成一个中文名字          cname: '@cname()',          // 生成一个 url          url: '@url()',          // 生成一个地址          county: Mock.mock('@county(true)'),          // 从数组中随机选择一个值          'array|1': ['A', 'B', 'C', 'D', 'E'],         // 随机生成一个时间          time: '@datetime()',          // 生成一张图片          image: Random.dataImage('200x100', 'Mock Image'),        },      ],    },  ];  复制代码

6.路由

Layout

布局暂时分为三大类:

权限验证

通过获取当前用户的权限去比对路由表,生成当前用户具的权限可访问的路由表,通过 router.addRoutes 动态挂载到 router 上。

在路由中,集成了权限验证的功能,需要为页面增加权限时,在 meta 下添加相应的 key:

auth

permissions

在这里贴一下路由跳转时权限验证的代码:

import router from '@/router';  import store from '@/store';  import storage from 'store';  import util from '@/libs/utils';  // 进度条  import NProgress from 'nprogress';  import 'nprogress/nprogress.css';  const loginRoutePath = '/user/login';  const defaultRoutePath = '/home';  /**  * 路由拦截   * 权限验证   */  router.beforeEach(async (to, from, next) => {    // 进度条    NProgress.start();    // 验证当前路由所有的匹配中是否需要有登录验证的    if (to.matched.some((r) => r.meta.auth)) {      // 是否存有token作为验证是否登录的条件      const token = storage.get('ACCESS_TOKEN');      if (token && token !== 'undefined') {        // 是否处于登录页面        if (to.path === loginRoutePath) {          next({ path: defaultRoutePath });          // 查询是否储存用户信息        } else if (Object.keys(store.state.system.user.info).length === 0) {          store.dispatch('system/user/getInfo').then(() => {            next();          });        } else {          next();        }      } else {        // 没有登录的时候跳转到登录界面        // 携带上登陆成功之后需要跳转的页面完整路径        next({          name: 'Login',          query: {            redirect: to.fullPath,          },        });        NProgress.done();      }    } else {      // 不需要身份校验 直接通过      next();    }  });  router.afterEach((to) => {    // 进度条    NProgress.done();    util.title(to.meta.title);  });  复制代码

页面开发

7、构建优化

包分析工具

构建代码之后,到底是什么占用了这么多空间?靠直觉猜测或者使用 webpack-bundle-analyzer。

const WebpackBundleAnalyzer = require('webpack-bundle-analyzer');  module.exports = {    chainWebpack: (config) => {      if (process.env.use_analyzer) {        config          .plugin('webpack-bundle-analyzer')          .use(WebpackBundleAnalyzer.BundleAnalyzerPlugin);      }    }, };  复制代码

开启 Gzip

对,这这么一句话,后端就得支持你的 .gz 文件了,而你只需要坐着等老板夸:

chainWebpack: (config) => {    config      .plugin('CompressionPlugin')      .use(CompressionPlugin, []);  },  复制代码

路由懒加载

这块 @vue/cli 已经帮忙处理好了,但也需要了解一下他的原理和如何配置。

{    path: 'home',    name: 'Home',    component: () => import(      /* webpackChunkName: "home" */ '@/views/home/index.vue'    ),  },  复制代码

webpackChunkName 这条注释还是很有必要加的,至少你打包后知道又是哪个页面变得又臭又大。

Preload & Prefetch

不清楚这两个功能的去 @vue/cli 补课,这两个功能非常有助于你处理加载的性能。

8.测试框架

直接使用了官方提供的 Vue Test Utils,这东西可以对组件进行测试,很不错。

写单元测试在团队里其实很难推进,不知道大家怎么看。

9.组件库

对于很多第三方的工具,我坚持认为二次封装成 vue 插件并没有多少开发成本,反而让你在后续的开发中变得很灵活。

我对以下库进行了 vue 插件的封装,并提交到 npm 私服:

大文件上传有兴趣的可以留言,我后续单独拎出来详细的写一下这块。

10.Vuex

内置一些功能,主要是对以下这些功能做了一些封装:

11.过滤器

过滤器是 Vue 提供的一个很好用的功能,听说 vue3 没了?

{{ message | capitalize }}  复制代码

我写了几个常用的过滤器:

12.指令

自定义指令可以提供很好的帮助:

13.开发规范

ESLint

不管是多人合作还是个人项目,代码规范都是很重要的。这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性。

这里我们采用了 Airbnb JavaScript Style Guide。

这套规范给我的感觉就是 很严谨!

CSS 规范

降低选择器复杂性

浏览器读取选择器,遵循的原则是从选择器的右边到左边读取。

#block .text p {   color: red;  }  复制代码

选择器优先级

内联 > ID选择器 > 类选择器 > 标签选择器

使用 flexbox

在早期的 CSS 布局方式中我们能对元素实行绝对定位、相对定位或浮动定位。而现在,我们有了新的布局方式 flexbox,它比起早期的布局方式来说有个优势,那就是性能比较好。不过 flexbox 兼容性还是有点问题,不是所有浏览器都支持它,所以要谨慎使用。各浏览器兼容性:

动画性能优化

在 CSS 中,transforms 和 opacity 这两个属性更改不会触发重排与重绘,它们是可以由合成器(composite)单独处理的属性。

属性值

字体排版

Vue 代码规范

常规

vuex

State (opens new window)为单一状态树,在 state 中需要定义我们所需要管理的数组、对象、字符串等等,只有在这里定义了,在 vue 的组件中才能获取你定义的这个对象的状态。

Getters (opens new window)有点类似 vue.js 的计算属性,当我们需要从 store 的 state 中派生出一些状态,那么我们就需要使用 getters,getters 会接收 state 作为第一个参数,而且 getters 的返回值会根据它的依赖被缓存起来,只有 getters 中的依赖值(state 中的某个需要派生状态的值)发生改变的时候才会被重新计算。

Actions

Modules

14.完成详细的使用文档

不论是功能还是组件库等等的工具,都需要完善的文档提供查阅,即使是轮子的构建者,也抵不住时间长了会忘记许多细节。

这里我使用 vuepress 构建文档,方便快捷。

15.Git 多人协作流程

公司使用内部搭建的 GitLab 托管代码

Root 仓库

项目启动时,由项目管理者搭建起最原始的仓库,称为 Root 仓库(源仓库)。

源仓库的有个作用 :

开发者仓库

任何开发者都没有权限对 Root 仓库进行直接的操作,源仓库建立以后,每个开发者需要做的事情就是把源仓库的 Fork 一份,作为自己日常开发的仓库。

Git 流程

基于Vue的前端架构所实现的技术有哪些

到此,关于“基于Vue的前端架构所实现的技术有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. 我所认识的MooseFS
  2. jquery实现改变所匹配的内容

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:Lua coroutine不一样的多线程编程思路是什么

下一篇:kafka的命令管理是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》