准备尝试用vue制作一个手机端的可视化应用
全局安装vue命令
cnpm install -g @vue/cli
创建项目
进入项目存放目录新建项目
vue create [project name]cd [project name]
安装插件
这里我安装了一个代码校验、以及router、vuex
vue add @vue/eslint vue add router vue add vuex
全局CLI配置
在以往的版本中都会有个config文件作为全局配置,但是当前的版本需要自己添加 vue.config.js ,只要在package.json同级目录下(即根目录)创建
const path = require("path"); function resolve(dir) { return path.join(__dirname, "./", dir); } module.exports = { chainWebpack: config => { // 为src下文件配别名,不使用相对路径 config.resolve.alias .set("@", resolve("src")) .set("assets", resolve("src/assets")) .set("components", resolve("src/components")) .set("views", resolve("src/views")) .set("icons", resolve("src/icons")) .set("router", resolve("src/router")) .set("utils", resolve("src/utils")) .set("style", resolve("src/style")); /** 设置处理svg的router,使svg可直接用名称调用,无需路径 */ // svg rule loader const svgRule = config.module.rule("svg"); // 找到svg-loader svgRule.uses.clear(); // 清除已有的loader, 如果不这样做会添加在此loader之后 svgRule.exclude.add(/node_modules/); // 正则匹配排除node_modules目录 svgRule // 添加svg新的loader处理 .test(/\.svg$/) .use("svg-sprite-loader") .loader("svg-sprite-loader") .options({ symbolId: "icon-[name]" }); }, /** 开发环境代理 */ devServer: { open: true, proxy: { "/api": { target: "http://localhost:3000", ws: true, changeOrigin: true, pathRequires: { "^/api": "" } } } } };
接下来是一些移动端的配置
禁止页面放大缩小
禁止移动端通过手指放大缩小页面
页面位置 public/index.html
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,er-scalable=no">
FastClick
为避免浏览器兼容问题引起的点击问题(部分浏览器对点击事件有300毫秒的延迟响应机制)
import fastClick from "fastclick" if ("addEventListener" in document && "ontouchstart" in window) { FastClick.prototype.focus = function(targetElement) { targetElement.focus(); }; document.addEventListener( "DOMContentLoaded", function() { FastClick.attach(document.body); }, false ); }
Reset.css
重置全局样式,也可以去官网下 https://meyerweb.com/eric/tools/css/reset/
文件放在 src/assets/reset.css
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; }
Border.css
解决部分手机屏幕1像素带来的页面样式兼容性问题
@charset "utf-8"; .border, .border-top, .border-right, .border-bottom, .border-left, .border-topbottom, .border-rightleft, .border-topleft, .border-rightbottom, .border-topright, .border-bottomleft { position: relative; } .border::before, .border-top::before, .border-right::before, .border-bottom::before, .border-left::before, .border-topbottom::before, .border-topbottom::after, .border-rightleft::before, .border-rightleft::after, .border-topleft::before, .border-topleft::after, .border-rightbottom::before, .border-rightbottom::after, .border-topright::before, .border-topright::after, .border-bottomleft::before, .border-bottomleft::after { content: "\0020"; overflow: hidden; position: absolute; } /* border * 因,边框是由伪元素区域遮盖在父级 * 故,子级若有交互,需要对子级设置 * 定位 及 z轴 */ .border::before { box-sizing: border-box; top: 0; left: 0; height: 100%; width: 100%; border: 1px solid #eaeaea; transform-origin: 0 0; } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { left: 0; width: 100%; height: 1px; } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { top: 0; width: 1px; height: 100%; } .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { border-top: 1px solid #eaeaea; transform-origin: 0 0; } .border-right::before, .border-rightbottom::before, .border-rightleft::before, .border-topright::after { border-right: 1px solid #eaeaea; transform-origin: 100% 0; } .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::before { border-bottom: 1px solid #eaeaea; transform-origin: 0 100%; } .border-left::before, .border-topleft::after, .border-rightleft::after, .border-bottomleft::after { border-left: 1px solid #eaeaea; transform-origin: 0 0; } .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { top: 0; } .border-right::before, .border-rightleft::after, .border-rightbottom::before, .border-topright::after { right: 0; } .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::after { bottom: 0; } .border-left::before, .border-rightleft::before, .border-topleft::after, .border-bottomleft::before { left: 0; } @media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) { /* 默认值,无需重置 */ } @media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) { .border::before { width: 200%; height: 200%; transform: scale(.5); } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.5); } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.5); } } @media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) { .border::before { width: 300%; height: 300%; transform: scale(.33333); } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.33333); } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.33333); } }