基于Vue CLI3 搭建五脏俱全的移动端H5应用

前言
之前开发vue项目,一直是自己搭建脚手架,并没有使用配套的Vue-CLI。一、是3.0之前的CLI无明显优势,配置繁琐;二、是觉得自己从零配置项目可控性更强。
Vue-CLI 3.0 于去年8月份就已发布,却一直没去了解。近日,有新Vue H5项目开发,就想着用Vue CLI3.0脚手架构建项目。并记录一下构建使用过程。

使用脚手架最好的参考就是官方文档,官方文档整体还是比较清晰明了的,更新也很及时。
「链接-官方文档」

CLI3.0 功能优势
Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

Vue-CLI3.0旨在近一步简化Vue项目配置,“傻瓜式”配置,促进团队开发的统一和规范化。同时也完全可以是可配置的,保留足够的扩展性。

功能丰富,实现开箱即用,不用再考虑繁琐的配置。
灵活的插件化机制,增强扩展性。
可以通过配套的图形化界面创建、管理项目的配置。有时看着还是很直观舒服的。
支持直接将一个vue文件跑起来,进行快速原型开发。
不用过多担心配置的更新迭代造成的连带影响。
vue团队出品,很好地维护并跟进官方的最佳实践和前沿技术。
image.png
搭建项目
项目git地址:github.com/now1then/vu…;

初始化项目
安装脚手架:

npm install -g @vue/cli

OR

yarn global add @vue/cli
复制代码
创建一个项目:

vue create my-project

OR

vue ui // 通过图形化界面创建项目
复制代码
选择preset特性(这里选择更多功能):
image.png
选择需要安装的(Babel、Router、Vuex、Pre-processors、Linter / Formatter):
这里先不引入TypeScript和单元测试。

image.png
路由是否使用history模式(Yes)
image.png
选择 CSS 预处理器(Less):
image.png
选择ESLint 配置(ESLint + Standard config)标准配置:
image.png
选择什么时候执行ESLint校验(Lint on save):
image.png
选择以什么样的形式配置以上所选的功能,单独生成配置文件 or 附加到package.json中(In dedicated config files):
image.png
是否将之前的设置保存为一个预设模板(y):
image.png

如果选择 y 后会让输入名称,在下次初始化项目可以使用该预设模板快速构建项目。
运行项目
了解CLI插件命令。

启动开发服务器运行项目:npm run serve;
命令会启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。

image.png
生产环境打包:npm run build;

图形化界面
通过 vue ui命令以图形化界面创建和管理项目:

vue ui
复制代码
运行成功后,在打开的页面中可以新建项目,也可以导入已有项目。

管理界面:
image.png
目录介绍:
**项目仪表盘:**自定义展现一些的功能小部件;
**插件:**可以查看已安装的CLI插件,还可以搜索安装插件;
**依赖:**可以查看和管理项目的运行依赖和开发依赖;
**配置:**项目的配置项配置管理,包括Vue-CLI配置和ESLint配置等。
**任务:**可以执行对应任务(对应于package.json中脚本命令),方便查看运行结果和分析检查。

图形化界面虽然对于实际开发意义不大,但简洁直观,实际体验还是不错的。具体功能最好运行亲自体验。

主流配置插件
Babel
CLI中已预设@vue/cli-plugin-babel,它默认使用 Babel 7 + babel-loader + @vue/babel-preset-app,但是可以通过 babel.config.js 配置使用任何其它 Babel 预设选项或插件。
『当前仅默认配置就够用,后续实际使用时逐步增加』

默认会转换_es6.promise、_``_es6.symbol_等常见ES6语法,对于未引入的语法,采用"显式地列出了需要的 polyfill的方式"。比如项目中使用es6.string.includes,则设置:

presets: [
[’@vue/app’, {
‘polyfills’: [
‘es6.string.includes’
]
}]
],
复制代码
ESLint
@vue/cli-plugin-eslint
『当前仅适用默认配置就够用。』,具体根据个人习惯和项目规范调整即可。
比如,本人一般关闭以下设置:

rules: {
‘no-console’: process.env.NODE_ENV === ‘production’ ? ‘warning’ : ‘off’,
‘no-debugger’: process.env.NODE_ENV === ‘production’ ? ‘warning’ : ‘off’,
‘semi’: 0, // 语句结尾分号
‘camelcase’: 0, //驼峰命名
‘comma-dangle’: 0, // 对象最后逗号
‘space-before-function-paren’: 0, // 函数定义前,括号前分割
},
复制代码
加载mint-ui库
// 安装
npm install mint-ui
复制代码
按需引入
借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。
首先,安装 babel-plugin-component:

npm install babel-plugin-component -D
复制代码
然后,将babel.config.js 修改为:

module.exports = {
presets: [
[’@vue/app’, {
‘polyfills’: [
‘es6.string.includes’
]
}]
],
“plugins”: [
[“component”, {
“libraryName”: “mint-ui”,
“style”: true
}]
]
}

复制代码
这样使用组件就可以按需引入了。

ajax请求封装
借助Axios库实现http请求
「链接-axios中文文档」

安装:
npm install axios;
复制代码
封装要达成的目标:

统一维护管理接口;
支持接口代理转发;
读取环境配置,区分处理环境。
拦截请求和响应,处理登录超时、404等异常情况;
根据请求的配置匹配接口URL前缀且作支持做特殊处理。
具体详见本人另一篇文章:
「漫漫长路-Axios封装」

移动端适配
考虑浏览器兼容性和使用习惯,移动端适配还是手淘模式,采用px转rem + lib-flexible实现。
postcss-pxtorem插件把配置的px转成rem;
lib-flexible库则根据页面尺寸和dpr,自动设置html的字体和meta缩放比例。

安装postcss-pxtorem插件
yarn add postcss-pxtorem -D
复制代码
postcss.config.js中增加pxtorem配置
// postcss.config.js
module.exports = {
plugins: {
“autoprefixer”: {}, 用来自动处理浏览器前缀的一个插件。
“postcss-
“: {
“rootValue”: 37.5, // 设计稿宽度的1/10
“unitPrecision”: 5, //小数位
“minPixelValue”: 1, //转换的最小单位
“selectorBlackList”: [], //忽略的样式, 正则
“propList”: [”*”] // 需要做转化处理的属性,如hightwidthmargin等,*表示全部,正则
}
}
}

复制代码
根据项目实际情况灵活配置。

安装lib-flexible,并在入口文件main.js中引入
// 安装 lib-flexible
yarn add lib-flexible

// main.js中引入lib-flexible
import ‘lib-flexible’;
复制代码
引入移动端调试工具
手机设备上调试H5非常不方便,这时可以引入一个非常好用的调试工具Eruda。

Eruda 是一个专为手机网页前端设计的调试面板,类似 DevTools 的迷你版,其主要功能包括:捕获 console 日志、检查元素状态、显示性能指标、捕获XHR请求、显示本地存储和 Cookie 信息、浏览器特性检测等等。
详情请访问-Github链接

可以通过CDN引用,当然也可以下载到项目中直接使用。

本项目配置中使用CLI环境变量配置,来设置是否加载Eruda。 实际项目使用可灵活配置。
.env.development文件设置环境变量:

VUE_APP_ERUDA=false # ture表示启用Eruda调试工具
复制代码
index.html文件设置:

<% if (VUE_APP_ERUDA === ‘true’) { %>

<% } %>
复制代码
效果:

ereda演示.gif
其他CLI配置
postcss.config.js
postcss-import:该插件主要是解决@import引入路径问题。引入本地文件、node_modules等的文件。
postcss-url:该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。
autoprefixer:用来自动处理浏览器前缀的一个插件。

可视化分析工具
利用可视化资源分析工具插件webpack-bundle-analyzer 分析生产文件打包大小。

// vue.config.js
configureWebpack: config => {
// 生产环境打包分析体积
if (process.env.NODE_ENV === ‘production’ && process.env.npm_config_report) {
return {
plugins: [
new BundleAnalyzerPlugin()
]
}
}
},
复制代码
终端命令:yarn build --report
当然图形化界面任务->build->分析 中也可以粗略分析打包大小。

统一设置less全局变量
参考「链接-Vue-CLI3 css自动导入」。
利用style-resources-loader插件,给Vue单文件自动全局导入配置路径中的LESS变量和mixin函数。 这样在使用时不用每个文件都单独引入,就可以直接使用定义的Less变量。

安装style-resources-loader;
yarn add style-resources-loader -D
复制代码
vue.config.js 配置
chainWebpack: config => { // CLI内部webpack配置
const types = [‘vue-modules’, ‘vue’, ‘normal-modules’, ‘normal’]
types.forEach(type => addStyleResource(config.module.rule(‘less’).oneOf(type)))
},
// 全局样式 变量、函数
function addStyleResource (rule) {
rule.use(‘style-resource’)
.loader(‘style-resources-loader’)
.options({
patterns: [
path.resolve(__dirname, ‘src/styles/variables.less’),
path.resolve(_dirname, ‘src/styles/mixin.less’),
],
})
}
复制代码
项目其他改动:
CSS样式初始化
引入_normalize.css
、_minireset.css _+ 自定义CSS设置,初始化CSS样式,使HTML元素样式在跨浏览器上表现得的高度一致性。
下载对应文件,直接放到src/assets/styles/路径下。

引入fastclick
移动端点击有300ms延迟,主要是为了解决双击缩放,浏览器等待300ms以判断是否是双击操作。
可以采用引入fastclick.js的方式解决移动端300ms延迟的问题。当然,fastclick.js曾经在老版本手机上解决移动端300ms的问题上做出了很大的贡献。时至今日是否还有必要使用,各方还是各持一词。

// 安装
yarn add fastclick

// main.js中引入使用
import FastClick from ‘fastclick’;
FastClick.attach(document.body);
复制代码
项目开发
目录结构
在团队开发时,规范的目录拆分约定,有利于协调开发和项目的长期维护。
根据个人习惯及经验,项目目录构建如下图所示:

image.png

项目开发都在src目录下;
src/assets目录主要存放静态资源文件,比如字体图标、图片、直接引入的或不常变更的第三方库等。
Vue模块说明
全局公共components组件、filter过滤器、directive指令可以直接注入到全局Vue,也可以在使用时页面组件内单独按需注入。
全局组件分为:
components_basics公共基础组件,主要存放封装的与业务无关的基础组件。
components_modules公共业务组件,主要存放提取的可重用业务组件。
对于不重用的业务组件,不用提取到外部,直接存放到具体的页面目录下即可。

页面组件内按需引入模块:

复制代码
Router路由封装
路由懒加载
「链接-Vue Router懒加载」
把组件按组分块,结合 Vue 的异步组件和 Webpack 的代码分割功能,实现路由组件的懒加载。


const Hello = () => import(/* webpackChunkName: “apply” / ‘@/views/hello’);
const Demo = () => import(/
webpackChunkName: “demo” */ ‘@/views/demo’);
复制代码
路由拦截
通过自定义meta参数,设置路由信息。
利用vue-router导航卫士,路由拦截时,作一些自定义处理。比如登录权限校验、页面标题设置等。

// 部分路由信息
{
path: ‘/demo’,
name: ‘demo’,
component: Demo,
meta: {
title: ‘演示Demo’, // 标题
requireAuth: true, // 登录权限
keepAlive: false,
}
},

//路由拦截
// 路由导航守卫
router.beforeEach((to, from, next) => {
// 登录权限
if (to.meta.requireAuth) { // 判断是否校验登录权限
if (!window.userName) { // 判断是否登录,根据实际业务处理
next({
path: ‘/login’,
query: {
redirect: to.fullPath // 未登录,跳转到登录页,登录后跳转回当前页。
}
})
return;
}
}
// 路由发生变化修改页面title
if (to.meta.title) {
document.title = to.meta.title + ’ | vue-h5-pro’;
} else {
document.title = ‘vue-h5-pro’;
}
next()
})
复制代码
页面平滑切换动画
效果图:

页面切换动画.gif
这里实现页面前进/后退时的整屏平滑左划/右划效果。
简单记录5个历史路由,进入新页面有左划切换效果,并记录历史路由;进入历史页面有右划切换效果,并清除历史路由。

router.js文件中拦截路由,记录历史路由信息。

// 路由拦截 router.js
router.afterEach((to, from) => {
// console.log(to, from);
if (!(from.path === ‘/’ && from.name === null)) {
setLocalRoute(to, from)
}
});

function setLocalRoute(to, from) {
// 本地已访问页面路由,存5条
const localRoute = window.myVue.localRoute = window.myVue.localRoute || [];
const from_index = localRoute.indexOf(from.path);
const to_index = localRoute.indexOf(to.path);
if (from_index < 0) {
localRoute.unshift(from.path);
to_index >= 0 && localRoute.splice(to_index, 1)
}
if (localRoute.length > 5) {
localRoute.splice(0, 1)
}
}
复制代码
main.vue文件中根据路由跳转,动态设置过渡动画样式。

复制代码
项目构建及开发细节后续会持续更新。具体的代码欢迎访问项目查看。

通用化组件(更新…)
此处记录封装的通用化基础组件。
通用化基础组件存放于src/component_basic/目录下。

Tip提示组件
比如:tip提示组件,组件使用及代码详见项目。
效果图:

点击tip.gif
项目链接
Github链接:github.com/now1then/vu…;
Vue-CLI3搭建移动端H5应用-语雀:www.yuque.com/nowthen/lon…;
Vue-CLI3搭建移动端H5应用-掘金:juejin.im/post/5d674d…

你可能感兴趣的:(前端工程师,前端,前端程序员)