从头搭建一个 Vue.js 项目工程

Posted 前端外刊评论

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从头搭建一个 Vue.js 项目工程相关的知识,希望对你有一定的参考价值。

前言

在很多人眼里能用 vue-cli 脚手架直接搭建 Vue.js 项目工程很爽,很方便,但是当遇到问题的时候我相信会有一堆人一脸茫然,有时候会不知所措。而我不喜欢用别人准备好的架子,无论做什么项目必须从0到1的搭建起来,每次构建项目体系的时候如同搭积木一般,每次积攒不同的技术实战经验。我一直认为:“只有自己亲身体验才能印象深刻的理解,才能控制住局面,才能成长!”。之前一直使用的是 React 体系做项目,但最近我经历了几次vue体系的项目获取了很多知识,也产生了浓厚兴趣,Vue.js 是一套构建用户界面的渐进式框架,而一个网站所涉及到元素很多,单纯一个 Vue.js 库是不足以支撑,它需要结合很多不同的库去做一个生态体系,比如(路由、数据源、UI组件等),下面我来总结一下我的经历,如果有欠缺的地方可以反馈给我,相互学习成长!

Vue.js

我使用的版本是v2.3.3

路由(vue-router)

vue 生态系统中的路由(vue-router)是我们在做vue.js单页面应用体系必用到的机制,这里经常会用到以下几种:

动态路由

 
   
   
 
  1. const router = new VueRouter({

  2.  routes: [

  3.      path: '/',

  4.      component: resolve => require(['./pages/Home.vue'], resolve)

  5.  ]

  6. })

路由重定向

有些场景也需要重定向(redirect)来做默认路径配置

 
   
   
 
  1. const router = new VueRouter({

  2.  routes: [

  3.        path: '*',

  4.        redirect: '/index'

  5.  ]

  6. })

嵌套路由

这种场景最常见,尤其是组件存在父子关系的时候,我需要在路由里面也配置出相对应的关系结构

 
   
   
 
  1. const router = new VueRouter({

  2.  routes: [

  3.      path: '/regist',

  4.      component: Regist,

  5.      children: [{

  6.            path: 'index',

  7.            component: resolve => require(['./pages/Regist.vue'], resolve)

  8.      }]

  9.  ]

  10. })

编程式路由

有些场景需要在js里面去控制路由的跳转

 
   
   
 
  1. router.push({ name: 'user', params: { userName: 'Stars' }})

有时候会在template里面去控制路由

 
   
   
 
  1. <router-link :to=""></router-link>

我在一个项目中会经常用到这些形式的路由操作,在调用路径时候基本使用异步加载方式。

数据源(vuex)

vuex是vue生态系统中管理数据源的库!它提供了状态树(state),这里定义了全局的数据结构,但在使用中不是什么数据都往这里塞,需要慎重考虑!同时提供了mutations事件操作改变数据源,这是唯一的改变state数据的方式,或者使用异步操作的action,通过触发store.dispatch()找到action中定义的函数,此函数再触发mutations中的函数去实现数据改变。其次当我们项目体系复杂的时候,光靠一个state管理很不方便,vuex提供了modules机制,让我们可以管理多个状态树,达到支撑复杂场景的应用,而我现在用的方式就是多modules来管理,对于每个大模块做了一个modules,参考官方例子,一看便知道。

 
   
   
 
  1. const moduleA = {

  2.  state: { ... },

  3.  mutations: { ... },

  4.  actions: { ... },

  5.  getters: { ... }

  6. }

  7. const moduleB = {

  8.  state: { ... },

  9.  mutations: { ... },

  10.  actions: { ... }

  11. }

  12. const store = new Vuex.Store({

  13.  modules: {

  14.    a: moduleA,

  15.    b: moduleB

  16.  }

  17. })

数据分为2种:动态数据和静态数据,在vuex我只放动态数据,把静态数据放入到vue.js的data里面,我是这么划分的,如果有更好的意见可以微博上联系“前端艺术者”。

UI组件库(iview)

在vue生态体系里面有很多专业的UI组件库,比如Element ui、Mint ui等一些,虽然很多组件的交互大体相似,但我个人觉得iview元素设计方案很漂亮,所以就选择了。iview的css样式是基于less,并提供了主题可定制化方案。

 
   
   
 
  1. @import './src/styles/index.less';

  2. // 下面是要覆盖的变量,例如:

  3. @primary-color: #333;

更多的配置信息在 https://github.com/iview/iview/blob/master/src/styles/custom.less iview现有的组件已经足够支撑我们很多业务场景需求,如果需要拓展我也可以在iview基础上再编写新的UI组件

vue-bus

经常会遇到2个平级组件之间的通讯,vue-bus提供了一个全局事件中心,并将其注入每一个组件,可以像使用内置事件流一样方便的使用全局事件,这样就解决了平级组件之间无法通信的问题。但是vue-bus的使用需要合理的规划和规范,比如请求接收的事件名,比如严格规定使用场景,不能平凡,无章法的使用,为了以后维护思路更清晰,乱用会造成“蜘蛛网式”混乱。

数据获取(axios

我在vue.js社区咨询过,现在基本使用axios来做获取数据操作,放弃使用vue-resource,通过几个项目中的实践,感觉axios用起来很顺手,在POST请求的时候需要配合“qs”插件来做,遇到跨域场景我使用CORS方式,需要浏览器和服务器同时支持,axios里面的withCredentials配置可以控制,因为axios源码里面是基于XMLHttpRequest对象来实现。

 
   
   
 
  1. //axios部分源码

  2. var request = new XMLHttpRequest();

  3. // Add withCredentials to request if needed

  4. if (config.withCredentials) {

  5. request.withCredentials = true;

  6. }

而服务器端需要针对“Access-Control-Allow-Origin”、“Access-Control-Allow-Credentials”、“Access-Control-Expose-Headers”去设置配置好即可,总体来说简单快捷。

PostCSS

之前Less、Sass都使用过,这次我的css方案选择PostCSS,它已经出现了一段时间了,并且有些大公司开始实践了,为此买了一本《深入PostCSS Web设计》自学并实践,这里简单介绍一下,不细说了:

  1. PostCSS 提供核心工具

  2. PostCSS是基于node.js构建一个css插件化的平台

  3. PostCSS不是一个预处理器也不是一个后处理器

性能看下图便可知道

注:此图来自css专家“大漠”授权使用

在使用过程中会用很多插件:

  1. 比如解决css全局作用域问题使用PostCSS-modules

  2. 比如经常会清除浮动,可使用postcss-clearfix

  3. 比如要像Stylus,Sass或Less一样编写css结构,可使用PreCSS

  4. 比如项目中会加载很多样式表,可使用postcss-import将样式表合并成压缩成一个

  5. 比如页面中我们会直接用html+css实现一个小图标的操作(如三角形,圆形等)可以使用postcss-circle

  6. 比如你想简写css属性名使用postcss-alias,代码示例如下:

 
   
   
 
  1. //编写css代码

  2. @alias {

  3.  bg: background;

  4. }

  5. .set-bg {

  6.  bg: red;

  7. }

 
   
   
 
  1. //转译后css代码

  2. .set-bg {

  3.  background: red;

  4. }

还有很多插件,postcss也提供了编写插件的方式,可以自定义一些新的postcss插件去丰富css体系,在使用期间遇到一些问题请教了"大漠",让我脑洞大开并顺利的解决。

二维码

我们的业务场景会用到二维码展示,所以找到了qrcode.vue来解决此场景,这个插件使用简单不多说

国际化(i18n)

前几天听了小春分享的i18n体系真是感悟颇深,他们使用场景较复杂,涉及的国家语言种类多,更全面,而我使用的是vue-i18n来处理,我们的翻译语种不多,就英文和中文切换,下面的zh.js和en.js就是语言脚本文件

 
   
   
 
  1. import Vue from 'vue'

  2. import VueI18n from 'vue-i18n'

  3. import Zh from './zh.js'

  4. import En from './en.js'

  5. Vue.use(VueI18n)

  6. export function createI18n() {

  7.    return new VueI18n({

  8.        locale: 'zh',

  9.        messages: {

  10.            'zh': Zh,

  11.            'en': En

  12.        }

  13.    })

  14. }

在使用过程中遇到一个问题,在页面切换的时候如果使用iview组件展示就会报错,查出原因是vue-i18n解析报错!一脸蒙~在github上面有人说换版本vue-i18n的版本,但我试一下无效,也请教了vue-i18n作者,后来找到新的方式并解决了i18n和iview的冲突,具体代码如下:

 
   
   
 
  1. //在vue组册iview的时候做一下处理

  2. Vue.use(iView, {

  3.    i18n: (key, value) => i18n.vm._t(key, value)

  4. })

代码规范(Eslint)

这个工具一开始我是不喜欢使用的,后来为了让团队编写代码更规范些,把Eslint加进了项目工程,在以前没有这些工具的时候,我们都是输出一份规范文档,大家都是按此文档上的规范定义去执行,但是也不乏有些人不愿意去做。现在有了工具强执行机制,做到了更好的约束。我在使用的时候有2种选择:

1.配置一套规范
2.继承airbnb的规范

最终选择了配置一套规范更符合团队需要。

如果想看Eslint的报错日志集合可以在使用一个命令,会在项目根目录下生成一个名为eslint.report的文件

 
   
   
 
  1. eslint --ext .js,.vue --format unix -o eslint.report src/**; echo

webpack打包

这个打包工具做前端的再熟悉不过了,很好的帮我们把代码压缩,也可以打包在一个文件夹里,里面有单独的css文件,分包压缩的js,转成base64码引用的图片等文件。

BundleAnalyzerPlugin

为了看清楚打包情况,会使用这个插件来生成一个打包详情图,分析打包情况,可以针对打包情况做分包的优化。

HtmlWebpackPlugin

我想把入口的html文件也打包到指定目录下,并自动加上打包后的css,js的引用,这时候就用到HtmlWebpackPlugin插件来解决。

总结

我开始涉及做vue.js项目时间较晚,通过这几次磨练,不断的加深理解,不断地实践,不断地看源码分析,vue.js是渐进式框架,我也是渐进式学习vue.js。当中遇到坑,基本都是靠自己解决掉!对我来说这是最好的技术成长,最好的收获,其次用vue.js做过渡动画的时候可以结合animate.css提升UI交互效果,真心的感觉非常棒!后续我们还有拓扑图的场景开发,我打算用vue.js+d3.js来完成效果,现在暂时用echarts去支撑,还有建站场景的开发,用vue.js完全没问题!前端是一条非常折腾的路,保持激情的心态走下去!


以上是关于从头搭建一个 Vue.js 项目工程的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js---实现前后端分离架构中前端页面搭建

Vue.js—单元测试

vue-cli 项目搭建

从头写一个 React-like 框架:工程搭建

vue项目搭建和运行

如何运行一个vue工程