1. webpack 打包扩展
  2. css:sass支持、normalize.css、_mixin.scss、_variables.scss
  3. vw、rem布局
  4. 跨域设置
  5. eslint设置
  6. cdn引入
  7. 路由设计、登录拦截
  8. axios、api 设计
  9. vuex状态管理

项目地址: vue-cli3-H5

demo地址: zhouyupeng.github.io/vuecli3H5/#…

webpack 打包扩展

vue-cli3.*后目录结构大改,去除了以往的build,config文件夹,要实现配置的改动在根目录下增加vue.config.js进行配置

css:sass支持、normalize.css、_mixin.scss、_variables.scss

使用的css预处理器是sass,对于css mixin,变量这里做了全局引入,并且引入normalize.css 使HTML元素样式在跨浏览器上表现得的高度一致性 vue.config.js配置

css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
// 启用 CSS modules for all css / pre-processor files.
modules: false,
sass: {
data: '@import "style/_mixin.scss";@import "style/_variables.scss";' // 全局引入
}
}
}
复制代码

vw、rem布局

对于移动端适配方案使用的是网易新闻的方法, 使用vw + rem布局

/**
750px设计稿
取1rem=100px为参照,那么html元素的宽度就可以设置为width: 7.5rem,于是html的font-size=deviceWidth / 7.5
**/
html {
font-size: 13.33333vw
} @media screen and (max-width: 320px) {
html {
font-size: 42.667PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 321px) and (max-width:360px) {
html {
font-size: 48PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 361px) and (max-width:375px) {
html {
font-size: 50PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 376px) and (max-width:393px) {
html {
font-size: 52.4PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 394px) and (max-width:412px) {
html {
font-size: 54.93PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 413px) and (max-width:414px) {
html {
font-size: 55.2PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 415px) and (max-width:480px) {
html {
font-size: 64PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 481px) and (max-width:540px) {
html {
font-size: 72PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 541px) and (max-width:640px) {
html {
font-size: 85.33PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 641px) and (max-width:720px) {
html {
font-size: 96PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 721px) and (max-width:768px) {
html {
font-size: 102.4PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 769px) {
html {
font-size: 102.4PX;
font-size: 13.33333vw
}
} @media screen and (min-width: 769px) {
html {
font-size: 102.4PX; #app {
margin: 0 auto
}
} }
复制代码

vue.config.js配置

loaderOptions: {
postcss: {
// 这是rem适配的配置
plugins: [
require('postcss-px2rem')({
remUnit: 100
})
]
}
}
复制代码

开发时跨域设置

devServer: {
open: true, // 启动服务后是否打开浏览器
host: '127.0.0.1',
port: 8088, // 服务端口
https: false,
hotOnly: false,
proxy: 'https://easy-mock.com/' // 设置代理
}
复制代码

配置完后,本地开发环境的axios的baseUrl要写为 '' ,即空字符串。 发布到线上时如果前端代码不是和后台api放在同源下的,后台还需做跨域处理,

eslint standard设置

使用的是JavaScript standard 代码规范,一个好的编码风格它可以帮助减少团队之间的摩擦,代码阅读起来也更加清爽,更加可读性,不要觉得烦,用了都说好。 这是 JavaScript standard 代码规范的全文

自定义配置,在.eslintrc.js里修改,这里是我给出的配置,4个空格缩进,不检查结尾分号,关闭单var 声明,可自行配置

rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
indent: [
'error',
4,
{
SwitchCase: 1
}
],
semi: 0, // 不检查结尾分号,
// 强制使用单引号
quotes: ['error', 'single'],
// 关闭函数名与后面括号间必须空格规则
'space-before-function-paren': 0,
// 关闭var 声明,每个声明占一行规则。
'one-var': 0
}
复制代码

cdn引入

对于 vue、vue-router、vuex、axios等等这些不经常改动的库、我们让webpack不对他们进行打包,通过cdn引入,可以减少代码的大小、也可以减少服务器的带宽 这里使用的是360的cdn,附上一份公共cdn评测文章 点我

vue.config.js配置

const externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
'mint-ui': 'MINT',
axios: 'axios' } const cdn = {
// 开发环境
dev: {
css: [
'https://lib.baomitu.com/mint-ui/2.2.13/style.min.css'
],
js: []
},
// 生产环境
build: {
css: [
'https://lib.baomitu.com/mint-ui/2.2.13/style.min.css'
],
js: [
'https://lib.baomitu.com/vue/2.6.6/vue.min.js',
'https://lib.baomitu.com/vue-router/3.0.1/vue-router.min.js',
'https://lib.baomitu.com/vuex/3.0.1/vuex.min.js',
'https://lib.baomitu.com/axios/0.18.0/axios.min.js',
'https://lib.baomitu.com/mint-ui/2.2.13/index.js'
]
}
} configureWebpack: config => {
if (isProduction) {
// externals里的模块不打包
Object.assign(config, {
externals: externals
}) } else {
// 为开发环境修改配置...
}
},
chainWebpack: config => {
// 对vue-cli内部的 webpack 配置进行更细粒度的修改。
// 添加CDN参数到htmlWebpackPlugin配置中, 详见public/index.html 修改
config.plugin('html').tap(args => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = cdn.build
}
if (process.env.NODE_ENV === 'development') {
args[0].cdn = cdn.dev
}
return args
})
}
复制代码
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- DNS预解析 -->
<link rel="dns-prefetch" href="//lib.baomitu.com" />
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=0,minimal-ui,viewport-fit=cover" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<!-- 使用CDN加速的CSS文件,配置在vue.config.js下 -->
<% for (var i in
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
<% } %> <title>vuedemo</title>
</head> <body>
<noscript>
<strong>We're sorry but vuedemo doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %> <!-- built files will be auto injected -->
</body> </html> 复制代码

路由设计、登录拦截

const router = new Router({
routes: [
{
path: '/',
name: 'home',
component: Home,
meta: {
auth: false, // 是否需要登录
keepAlive: true // 是否缓存组件
}
},
{
path: '/about',
name: 'about',
component: () =>
import(/* webpackChunkName: "about" */ './views/About.vue'),
meta: {
auth: true,
keepAlive: true
}
},
{
path: '/login',
name: 'login',
component: () =>
import(/* webpackChunkName: "login" */ './views/login.vue'),
meta: {
auth: false,
keepAlive: true
}
},
{
path: '*', // 未匹配到路由时重定向
redirect: '/',
meta: {
// auth: true,
// keepAlive: true
}
}
]
}) // 全局路由钩子函数 对全局有效
router.beforeEach((to, from, next) => {
let auth = to.meta.auth
let token = store.getters['login/token']; if (auth) { // 需要登录
if (token) {
next()
} else {
next({
name: 'login',
query: {
redirect: to.path
}
})
}
} else {
next()
}
}) 复制代码

在meta中设置是否需要登录以及是否缓存当前组件, 在router.beforeEac路由钩子函数中对登录权限判断,没有登录的跳到登录页面,并且把当前页面传过去,登录后跳回这个页面。

对于页面缓存的在app.vue里进行处理

<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
复制代码

axios、api 设计

对于axios的设计主要是请求拦截器, respone拦截器,以及get,post的二次封装

axios.defaults.timeout = 12000 // 请求超时时间
axios.defaults.baseURL = process.env.VUE_APP_BASE_API axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded;charset=UTF-8' // post请求头的设置
// axios 请求拦截器
axios.interceptors.request.use(
config => {
// 可在此设置要发送的token
let token = store.getters['login/token'];
token && (config.headers.token = token)
Indicator.open('数据加载中')
return config
},
error => {
return Promise.error(error)
}
)
// axios respone拦截器
axios.interceptors.response.use(
response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误 结合自身业务和后台返回的接口状态约定写respone拦截器
Indicator.close()
console.log('response', response);
if (response.status === 200 && response.data.code === 0) {
return Promise.resolve(response)
} else {
Toast({
message: response.data.msg,
position: 'middle',
duration: 2000
});
return Promise.reject(response)
}
},
error => {
Indicator.close()
const responseCode = error.response.status
switch (responseCode) {
// 401:未登录
case 401:
break
// 404请求不存在
case 404:
Toast({
message: '网络请求不存在',
position: 'middle',
duration: 2000
});
break
default:
Toast({
message: error.response.data.message,
position: 'middle',
duration: 2000
});
}
return Promise.reject(error)
}
)
/**
* 封装get方法,对应get请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
function get (url, params = {}) {
return new Promise((resolve, reject) => {
axios
.get(url, {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
function post (url, params) {
return new Promise((resolve, reject) => {
axios
.post(url, qs.stringify(params))
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
} 复制代码

为了方便管理api路径,这里把所以请求都放在了api文件夹下,如

import { get, post } from '@/axios/http.js'
function getIndex (params) {
return get('/mock/5cb48c7ed491cd741c54456f/base/index', params)
}
function login(params) {
return post('/mock/5cb48c7ed491cd741c54456f/base/login', params)
}
export {
getIndex,
login
} 复制代码

其他

去除console.log

装uglifyjs-webpack-plugin插件

 // 上线压缩去除console等信息
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 移除console
}
},
sourceMap: false,
parallel: true
})
)
复制代码

设置alias目录别名

在项目中经常会引用各个地方的文件,配置后可以更加方便的引入了

config.resolve.alias
.set('assets', '@/assets')
.set('components', '@/components')
.set('view', '@/view')
.set('style', '@/style')
.set('api', '@/api')
.set('store', '@/store')
复制代码

环境变量和模式

在一个产品的前端开发过程中,一般来说会经历本地开发、测试脚本、开发自测、测试环境、预上线环境,然后才能正式的发布。对应每一个环境可能都会有所差异,比如说服务器地址、接口地址、websorket地址…… 等等。在各个环境切换的时候,就需要不同的配置参数,所以就可以用环境变量和模式,来方便我们管理。

.env                # 在所有的环境中被载入
.env.local # 在所有的环境中被载入,但会被 git 忽略
.env.[mode] # 只在指定的模式中被载入
.env.[mode].local # 只在指定的模式中被载入,但会被 git 忽略
复制代码

自定义的变量VUE_APP_开头,两个特殊的变量:

  1. NODE_ENV - 会是 "development"、"production" 或 "test" 中的一个。具体的值取决于应用运行的模式。
  2. BASE_URL - 会和 vue.config.js 中的 baseUrl 选项相符,即你的应用会部署到的基础路径。

如我们定义的.env

NODE_ENV = 'development'
BASE_URL = '/'
VUE_APP_BASE_API = ''
复制代码

.env.production

NODE_ENV = 'production'
BASE_URL = './'
VUE_APP_BASE_API = 'https://easy-mock.com/'
复制代码

在项目中可以用process.env.VUE_APP_*,如process.env.VUE_APP_BASE_API获取到定义的值

全局引入filter

把多个地方用到的过滤器写在一个js里面,复用代码。

// 过滤日期格式,传入时间戳,根据参数返回不同格式
const formatTimer = function(val, hours) {
if (val) {
var dateTimer = new Date(val * 1000)
var y = dateTimer.getFullYear()
var M = dateTimer.getMonth() + 1
var d = dateTimer.getDate()
var h = dateTimer.getHours()
var m = dateTimer.getMinutes()
M = M >= 10 ? M : '0' + M
d = d >= 10 ? d : '0' + d
h = h >= 10 ? h : '0' + h
m = m >= 10 ? m : '0' + m
if (hours) {
return y + '-' + M + '-' + d + ' ' + h + ':' + m
} else {
return y + '-' + M + '-' + d
}
}
}
export default {
formatTimer
} 复制代码

main.js引入

import filters from './filters/index'
// 注入全局过滤器
Object.keys(filters).forEach(item => {
Vue.filter(item, filters[item])
})
复制代码

使用

{{1555851774 | formatTimer()}}
复制代码

vue中使用mock.js

查看我以前写的文章点击我

wepback的可视化资源分析工具插件---webpack-bundle-analyzer

用来分析哪些模块引入了哪些代码,进行有目的性的优化代码

在打包环境中加,使用命令npm run build --report

if (process.env.npm_config_report) {
config.plugins.push(new BundleAnalyzerPlugin())
}
复制代码

代码地址

项目地址: vue-cli3-H5

demo地址: zhouyupeng.github.io/vuecli3H5/#…

作者:web_zhou
链接:https://juejin.im/post/5cbf32bc6fb9a03236393379
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

基于vue-cli3.0构建功能完善的移动端架子,主要功能包括的更多相关文章

  1. vue-calendar 基于 vue 2.0 开发的轻量,高性能日历组件

    vue-calendar-component 基于 vue 2.0 开发的轻量,高性能日历组件 占用内存小,性能好,样式好看,可扩展性强 原生 js 开发,没引入第三方库 Why Github 上很多 ...

  2. vue cli3.0 结合echarts3.0和地图的使用方法

    echarts 提供了直观,交互丰富,可高度个性化定制的数据可视化图表.而vue更合适操纵数据. 最近一直忙着搬家,就没有更新博客,今天抽出空来写一篇关于vue和echarts的博客.下面是结合地图的 ...

  3. 解决vue/cli3.0 语法验证规则 ESLint: Expected indentation of 2 spaces but found 4. (indent)

    当你使用vue/cli3.0的时,有可能出现雁阵规则 ESLint: Expected indentation of 2 spaces but found 4. (indent) 解决方法 1.在vu ...

  4. 01-路由跳转 安装less this.$router.replace(path) 解决vue/cli3.0语法报错问题

    2==解决vue2.0里面控制台包的一些语法错误. https://www.jianshu.com/p/5e0a1541418b 在build==>webpack.base.conf.j下注释掉 ...

  5. vue cli3.0打包

    1.vue cli3.0需要在项目根目录下配置webpack  包括反向代理以及打包文件路径 const webpack = require("webpack"); module. ...

  6. 以寡治众各个击破,超大文件分片上传之构建基于Vue.js3.0+Ant-desgin+Tornado6纯异步IO高效写入服务

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_218 分治算法是一种很古老但很务实的方法.本意即使将一个较大的整体打碎分成小的局部,这样每个小的局部都不足以对抗大的整体.战国时期 ...

  7. vue cli3.0快速搭建项目详解(强烈推荐)

    这篇文章主要介绍下vue-cli3.0项目搭建,项目结构和配置等整理一下,分享给大家. 一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cl ...

  8. 使用VUE CLI3.0搭建项目vue2+scss+element简易版

    1.安装Vue CLI 3 //三选一即可cnpm install -g @vue/cli npm install -g @vue/cli yarn global add @vue/cli 注意: 1 ...

  9. VUE CLI3.0安装及配置

    # 安装 npm install -g @vue/cli # 查看已安装版本vue --version 或者 vue -V # 卸载 npm uninstall @vue/cli -g # 新建项目 ...

随机推荐

  1. python3 第二十九章 - 内置函数之tuple相关

    Python元组包含了以下内置函数 序号 方法及描述 实例 1 len(tuple)计算元组元素个数. >>> tuple1 = ('Google', 'Baidu', 'Taoba ...

  2. python数据结构(二)------元组

    元组是不可变序列,因此,元组的操作非常简单,本文就简单介绍一下,并解释下元组存在的意义: 2.2.1 元组的创建 2.2.2 tuple函数 2.2.3 基本元组操作 2.2.4 元组存在的意义 2. ...

  3. Maven学习 九 maven热部署

    第一步:配置tomcat的manager-script角色 点击tomcat的默认项目root的欢迎页面的Manager App 刚开始是没有用户名与和密码的,直接点击取消 出现如下的一张图片,图片中 ...

  4. Web性能和负载测试工具补充

    压力测试文档:https://yq.aliyun.com/articles/377543https://www.cnblogs.com/ahjxxy/archive/2012/09/17/268899 ...

  5. 别人的Linux私房菜(13)学习Shell脚本

    CentOS6.x以前版本的系统服务启动接口在/etc/init.d/目录下,存放了脚本. Shell脚本因调用外部命令和bash 的一些默认工具,速度较慢,不适合处理大量运算. 执行方式有:直接命令 ...

  6. Win7 VS2017编译magnum及例子

    magnum是一个开源的图形中间件 Lightweight and modular C++11/C++14 graphics middleware for games and data visuali ...

  7. FFMPEG增加和提取字幕流

    转自 https://www.cnblogs.com/satng/p/5514683.html 防抽复制一遍 增加字幕流ffmpeg -i video.avi -i sub.ass -map 0:0 ...

  8. Visual Studio Code 学习记录

    Visual Studio Code的官方文档可以学到很多知识,不只是vs code的用法,包括一些语言的入门 和一些概念等等.很好的文档. ※,user.settings.json中的一些配置说明: ...

  9. usb2.0、usb3.0、usb3.1、type-c 接口含义与区别

    简单说: usb3.0 比2.0的传输速率快,充电快,能向下兼容2.0 usb3.1 通常是指 usb3.1 gen2,比3.0的传输速率更快.充电更快,同兼容 type-c 通常是指 usb3.1的 ...

  10. 与我们息息相关的internet服务(3)---电子邮件服务

    几年前了解了一下,现在再实施的时候,再了解,当然如果要到牛人张小龙28岁时的开发程度,可能还差一个筋斗云 在起步一个公司,从组建的技术上,可能要准备很多东西,其中一个就是我们熟悉的企业邮箱. 伊妹儿, ...