1. 前端工程化的开始

从这个项目开始,我决定不再使用CDN导入方式来构建一个Vue的项目,因为那样的代码维护性不高,而且规范性也不高。

之前做项目痛点:

  1. 代码管理杂乱不堪, 很难跟踪项目实现过程, 很难回退到指定版本(使用Git解决)
  2. 第三方插件管理杂乱不堪, 每次使用都需要重新导入
  3. CSS3新增属性未添加私有前缀、ES678语法未进行适配,网页兼容性低下
  4. 未对项目文件进行优化,网页性能低下
  5. 引入过多第三方资源请求次数增加,本地js/css代码压缩,本地图片压缩等
  6. 源代码未经压缩混淆等操作,存在一定安全性问题
  7. 未强制要求代码规范,部分代码可能不符合企业要求

2. 使用Vue-CLI

要达到前端工程化,所以就借助Vue的脚手架来开发项目。这里使用vue create 项目名来创建一个项目。

vue create 和vue init webpack的区别

vue createvue-cli3.x的初始化方式,目前模板是固定的,模板选项可自由配置,创建出来的是vue-cli3的项目,与cue-cli2项目结构不同,配置方法不同,具体配置方法参考官方文档网页链接。
vue initvue-cli2.x的初始化方式,可以使用github上面的一些模板来初始化项目,webpack是官方推荐的标准模板名。vue-cli2.x项目向3.x迁移只需要把static目录复制到public目录下,老项目的src目录覆盖3.x的src目录(如果修改了配置,可以查看文档,用cli3的方法进行配置)

我这里使用的是vue-cli3.x的版本

  1. 基于vue-cli创建的默认目录结构如下:
  2. |————music163(项目根目录)
  3. |————node_modules文件夹:存储了依赖的相关的包
  4. |————public文件夹:任何放置在public文件夹的静态资源都会被简单地复制
  5. 而不经过webpack,你需要通过绝对路径来引用它们
  6. 一般用于存储一些永远不会改变的静态资源或者webpack不支持的第三方库
  7. |————src文件夹:代码文件夹
  8. |————assets文件夹:存储项目中自己的一些静态文件(图片、字体等)会被webpack处理
  9. |————components文件夹:存储项目中的自定义组件(小组件、公共组件)
  10. |————views文件夹:存储项目中的自定义组件(大组件、页面级组件、路由级别组件)
  11. |————router文件夹:存储VueRouter相关文件
  12. |————store文件夹:存储Vuex相关文件
  13. |————App.vue:根组件
  14. |————main.js:入口js文件

3. 初始化项目

删掉一些默认创建的文件和路由规则等等

1.初始化HTML代码

初始化public文件夹中的index.html,由于此次做的是网易云音乐项目所以需要引入一些图标,还有基于移动端开发的适配方案(这里用的是淘宝团队开发的flexible.js)。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <!-- 使部分国产浏览器默认采用高速模式渲染页面 -->
  7. <meta name="renderer" content="webkit">
  8. <!-- 使IE浏览器采用最新的渲染模式渲染 -->
  9. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  10. <!-- SEO标签 -->
  11. <title>南先生的网易云</title>
  12. <meta name="keywords" content="网易云音乐,音乐,播放器,网易,下载,播放,DJ,免费,明星,精选,歌单,识别音乐,收藏,分享音乐,音乐互动,高音质,320K,音乐社交,官网,移动站,music.163.com">
  13. <meta name="description" content="网易云音乐是一款专注于发现与分享的音乐产品,依托专业音乐人、DJ、好友推荐及社交功能,为用户打造全新的音乐生活。">
  14. <link rel="shortcut icon" href="./favicon.ico">
  15. <link rel="apple-touch-icon" href="./apple-touch-icon.png">
  16. <link rel="apple-touch-icon" sizes="114x114" href="./apple-touch-icon114.png">
  17. <link rel="apple-touch-icon" sizes="152x152" href="./apple-touch-icon152.png">
  18. <link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon180.png">
  19. <!-- 移动端开发方案 -->
  20. <script src="flexible.js"></script>
  21. </head>
  22. <body>
  23. <div id="app">
  24. </div>
  25. </body>
  26. </html>

2.使用rem+视口缩放方案适配

此次采用的是rem+视口缩放的方案来做移动端适配,这里就直接用的淘宝团队的flexible.js,关于flexible.js的原理解析可以参考:伸手党系列二:移动端rem适配方案(flexible.js)

3.postcss-pxtorem

因为一般UI给我们的稿子大小是750px的。在flexible.js中,它把750px分为10份,每份就占75px,所以font-size的基准值为75px,也就是1rem 为 75px。所以我们为了适应不同尺寸大小时,常常会用Less或者Sass在单位上做一个表达式运算,例:width: 100/75rem这样写虽然没毛病,但每个需要转换的地方都写上是有点蛋疼的。所以在这里还需要借助postcss-pxtorem插件实现自动将px转换为rem。
需要使用npm安装一下postcss-pxtorem(这里的版本是4.0.1),安装完成后还需要在根目录下创建一个名为postcss.config.js的配置文件。配置内容如下:

  1. module.exports = {
  2. plugins: {
  3. 'postcss-pxtorem': {
  4. rootValue: 75, // 根元素字体大小
  5. propList: ['*'] // 默认将所有属性值从px更改到rem的属性
  6. }
  7. }
  8. }

但是有些时候我们并不想把所有属性都从px转换到rem,在写CSS的时候可以将单位px改为Px就不会自动转换为rem了。

4.借助fastclick解决移动端100~300ms的点击事件延迟问题

先npm安装fastclick,再在main.js中import fastclick from 'fastclick'即可

5.初始化默认全局样式

  1. // 清除浏览器默认样式
  2. @import "./reset.scss";
  3. // 定义项目中的全局变量
  4. @import "./variable.scss";
  5. // 定义混合方法
  6. @import "./mixin.scss";
  7. html, body{
  8. width: 100%;
  9. height: 100%;
  10. overflow: hidden;
  11. // 解决IScroll拖拽卡顿问题
  12. touch-action: none;
  13. }
  14. body{
  15. @include font_size($font_medium);
  16. font-family: Helvetica,sans-serif,STHeiTi;
  17. }
  18. img{
  19. vertical-align: bottom;
  20. }

4. 注意点

经过以上步骤之后,项目就算基本初始化完成了,但其中还有一个注意点。因为flexible.js采用的是rem+视口缩放的方案来适配,所以其中会有一个问题,为了使所有的设备都能适配大小,必须利用视口缩放的原理来处理不同设备上的尺寸差异问题,但是在移动端中一般情况下我们不需要让字体大小随着屏幕尺寸的变化而变化,所以我们不能设置字体大小为rem,否则字体大小就会随着屏幕尺寸的变化而变化。flexible.js官方也推荐我们使用px。我们还是希望将字体设置为一个统一的尺寸,也就是px。但是我们不能直接在样式表中直接设置px,例如我们在组件中随便将一段文字设置为15px:

  1. <template>
  2. <div id="app">
  3. <p>你好,世界!</p>
  4. </div>
  5. </template>
  6. <script>
  7. </script>
  8. <style scoped lang="scss">
  9. #app p{
  10. font-size: 15px;
  11. }
  12. </style>

image.png
就会发现原本设置的15px变得非常小,这就是因为flexible.js利用视口缩放原理以后将原本的视口大小从1缩小到了0.5倍,也就是说它把原本的15px也缩小了一半,此时我们看到的15px就不是真正的15px。我们还需要还原回去,也就是缩小多少倍就放大多少倍,此时我们需要借助Scss的混合来完成计算

  1. /*根据dpr计算font-size*/
  2. @mixin font_dpr($font-size){
  3. font-size: $font-size;
  4. [data-dpr="2"] & { font-size: $font-size * 2;}
  5. [data-dpr="3"] & { font-size: $font-size * 3;}
  6. }
  7. /*通过该函数设置字体大小,后期方便统一管理*/
  8. @mixin font_size($size){
  9. @include font_dpr($size);
  10. }

所以我们只需要在使用时调用即可

  1. .header-title{
  2. text-align: center;
  3. line-height: 100px;
  4. color: #fff;
  5. font-weight: bold;
  6. @include font_size(15Px);
  7. }