Vue技术点整理-Vue CLI
Vue CLI 是一个基于 Vue.js 进行项目快速开发的脚手架
注:具体安装步骤可参考Vue CLI,默认安装的脚手架,是没有service、util等工具类的,以下主要描述如何在脚手架的基础上进行快速开发
GitHub示例地址 vue-ht-cli
一,vue.config.js配置文件
默认Vue CLI安装完成后,是没有这个配置文件的,需要手动在项目根目录创建,并修改使用:
以下为我简单配置的文件,更多详细配置,请参考 Vue CLI官网
vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
// outputDir: 在npm run build时 生成文件的目录 type:string, default:"dist"
outputDir: "dist",
// assetsDir 静态文件目录(js, css, img, fonts) under
// assetsDir: "static",
// lintOnSave:{ type:Boolean default:true } 问你是否使用eslint
lintOnSave: true,
// productionSourceMap:{ type:Bollean,default:true } 生产源映射
// 如果您不需要生产时的源映射,那么将此设置为false可以加速生产构建
productionSourceMap: false,
// devServer:{type:Object} 3个属性host,port,https
// 它支持webPack-dev-server的所有选项
devServer: {
port: , // 端口号
host: "192.168.3.49",
//host: "localhost",
https: false,
open: false, //配置自动启动浏览器
proxy: null
}
};
设置代理模式
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
二,使用postcss-pxtorem自动px转换为rem
注:根据UI设计稿的比例(750、375等),设置rootValue的值
开发时直接使用px进行开发,项目启动或者部署后,会直接按照比例转换为rem
postcss.config.js
module.exports = {
plugins: {
"autoprefixer": {
browsers: ['Android >= 4.0', 'iOS >= 7']
},
"postcss-pxtorem": {
"rootValue": 37.5, // 设计稿宽度的1/10,
"propList": ['*']// 需要做转化处理的属性,如`hight`、`width`、`margin`等,`*`表示全部
}
}
};
package.json
增加postcss-pxtorem的依赖,然后npm install
三,使用UI vant进行快速项目开发
1,安装babel-plugin-import依赖
2,在.babelrc 或者 babel.config.js文件里面加入以下配置
babel7版本以上配置:
module.exports = {
presets: ["@vue/app"],
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
};
babel7版本以下配置:
{
"plugins": [
["import", {
"libraryName": "vant",
"libraryDirectory": "es",
"style": true
}]
]
}
3,在项目中引入直接使用
import { Button } from 'vant';
具体vant使用参考官网
四,api请求axios、jsonp、util等插件封装
1,axios、jsonp请求统一封装为httpRequest.js
import axios from "axios";
import jsonp from "jsonp";
// 请求拦截器
axios.interceptors.request.use(
config => {
return config;
},
error => {
return Promise.reject(error);
}
);
// 返回拦截器
axios.interceptors.response.use(
response => {
return response;
},
error => {
return Promise.resolve(error.response);
}
);
class HttpRequest {
get(url, paramer, header) {
return this.post(url, paramer, header, "get");
}
/**
* url : 请求地址
* param : 请求参数
* header : 需要添加的header,例如:{"Authorization":"xxxxx"}
* json: "application/json; charset=utf-8"
* form: "application/x-www-form-urlencoded; charset=utf-8"
*/
post(url, params, header, method) {
let headers = { "Content-Type": "application/json" };
if (header) {
Object.assign(headers, header);
}
let data = new Promise((resolve, reject) => {
axios
.request({
url: url,
method: method ? "get" : "post",
params: method == "get" ? params : null,
data: method != "get" ? params : null,
headers: headers,
timeout: 10000,
responseType: "json"
})
.then(response => {
resolve(response["data"]);
})
.catch(function(error) {
reject(error);
});
});
return data;
}
/**
* url:请求地址
* pm:服务端接收jsonp的名称,默认为jsoncallback
* 注:callback为服务端返回的函数名称
*/
jsonp(url, pm) {
const data = new Promise((resolve, reject) => {
jsonp(
url,
{
timeout: TIMEOUT,
param: pm === true ? pm : "jsoncallback",
name: "callback"
},
(err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
}
);
});
return data;
}
}
export default new HttpRequest();
2,业务service统一封装为httpService.js
import HttpRequest from "@/service/httpRequest.js";
import { URL, CTS } from "@/config/config.js";
import { getLocal } from "@/util/util.js";
class HttpService {
// 2.1校验用户信息
checkInfo(cusName, certCode, phone) {
return HttpRequest.post(URL.kdUrl + "/queryPhone", {
openid: this.getOpenId(),
cusName: cusName,
certCode: certCode,
phone: phone
});
}
// 2.2查询用户宽带信息
fetchAccount(type, cusName) {
return HttpRequest.post(URL.kdUrl + "/queryAccount", {
openid: this.getOpenId(),
cusName: cusName,
type: type
});
} // 获取openId
getOpenId() {
return getLocal('OPENID');
}
}
export default new HttpService();
3,全局配置项封装为config.js
// 接口地址配置
export const URL = {
kdUrl: "http://xxx:8080/portal",
}; // 常量配置
export const CTS = {
// 是否开启mock模拟数据
MOCK_FLG: false,
// 是否开启日志打印
CONSOLE_FLG: true,
// aes加密秘钥
AES_KEY: "xxx"
}; // http请求超时时间 单位:s
export const TIMEOUT = "10000";
4,工具类util.js
import CryptoJS from "crypto-js"; export const oidInit = () => {
try{
let url = window.location.href;
url = url.substring(0,url.indexOf("?")) + '?oid=true';
window.history.pushState(null, null, url)
}catch(e){
//TODO handle the exception
}
};
/**
* 存储localStorage
*/
export const setLocal = (name, content) => {
if (!name) return;
if (typeof content !== "string") {
content = JSON.stringify(content);
}
if (window.localStorage) {
window.localStorage.setItem(name, content);
}
};
/**
* 获取localStorage
*/
export const getLocal = name => {
if (!name) return;
if (!window.localStorage) return;
return window.localStorage.getItem(name);
}; /**
* 删除localStorage
*/
export const removeLocal = name => {
if (!name) return;
if (!window.localStorage) return;
window.localStorage.removeItem(name);
}; /**
* 存储sessionStorage
*/
export const setSession = (name, content) => {
if (!name) return;
if (typeof content !== "string") {
content = JSON.stringify(content);
}
window.sessionStorage.setItem(name, content);
}; /**
* 获取localStorage
*/
export const getSession = name => {
if (!name) return;
return window.sessionStorage.getItem(name);
}; /**
* 删除localStorage
*/
export const removeSession = name => {
if (!name) return;
window.sessionStorage.removeItem(name);
}; /**
* 获取style样式
*/
export const getStyle = (element, attr, NumberMode = "int") => {
let target;
if (attr === "scrollTop") {
target = element.scrollTop;
} else if (element.currentStyle) {
target = element.currentStyle[attr];
} else {
target = document.defaultView.getComputedStyle(element, null)[attr];
}
return NumberMode === "float" ? parseFloat(target) : parseInt(target);
}; /**
* 判断是否是微信
*/
export const isWeiXin = () => {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) === "micromessenger") {
return true;
} else {
return false;
}
};
/**
* 判断是否是qq
*/
export const isQQ = () => {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf("qq/") > -1) {
return true;
} else {
return false;
}
}; /**
* 动态加载css
*/
export const loadCss = url => {
var script = document.createElement("link");
script.rel = "stylesheet";
script.href = url;
document.body.appendChild(script);
};
/**
* 动态加载js
*/
export const loadJs = url => {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}; /**
* 获取url链接里面传过来的值
* name:key的名称
*/
export const UrlVal = name => {
var url = window.location.search.substr(1);
if (window.location.search.substr(1).match("&")) {
url = window.location.search.substr(1).replace(/&/g, "&");
}
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = url.match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}; /**
* 判断当前设备是否为ios
*/
export const isIos = () => {
var ua = navigator.userAgent.toLowerCase();
if (/iphone|ipad|ipod/.test(ua)) {
return true;
} else if (/android/.test(ua)) {
return false;
}
}; /**
* 格式化当前时间
*/
export const format = (date, fmt) => {
var o = {
"M+": date.getMonth() + 1,
"d+": date.getDate(),
"h+": date.getHours(),
"m+": date.getMinutes(),
"s+": date.getSeconds(),
"q+": Math.floor((date.getMonth() + 3) / 3),
S: date.getMilliseconds()
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
);
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
}
}
return fmt;
};
/**
* 获取当前时间戳
* 如:20170502102317
*/
export const MakeTime = () => {
let d = new Date();
let en = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();
let en1 =
buLing(d.getHours()) +
"" +
buLing(d.getMinutes()) +
"" +
buLing(d.getSeconds());
return toDate(en).replace(/-/g, "") + en1;
};
export const buLing = str => {
if (str < 10) {
str = "0" + str;
}
return str;
};
export const toDate = time => {
var arys = [];
arys = time.split("-");
var fullyear = arys[0];
var month = arys[1];
var day = arys[2];
var date = "";
date += fullyear + "-";
if (month >= 10) {
date += month + "-";
} else {
date += "0" + month + "-";
}
if (day >= 10) {
date += day;
} else {
date += "0" + day;
}
return date;
}; /**
* aes加密
*/
export const encodePwd = (data, key) => {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var encrypted1 = CryptoJS.AES.encrypt(data, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Hex.parse(encrypted1.ciphertext.toString()).toString();
};
/**
* aes解密
*/
export const decodePwd = (data, key) => {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var decrypted = CryptoJS.AES.decrypt(
{
ciphertext: CryptoJS.enc.Hex.parse(data.toString())
},
keyHex,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
);
return decrypted.toString(CryptoJS.enc.Utf8);
}; /**
* Base64转码
*/
export const encodeBase64 = data => {
var str = CryptoJS.enc.Utf8.parse(data);
return CryptoJS.enc.Base64.stringify(str);
};
/**
* Base64解码
*/
export const decodeBase64 = data => {
var str = CryptoJS.enc.Base64.parse(data);
return CryptoJS.enc.Utf8.stringify(str);
}; /*
* 日志打印
*/
export const Log = {
isConsole: true,
i: function(jsName, content) {
if (this.isConsole) {
console.info("位置:", content);
}
},
w: function(jsName, content) {
if (this.isConsole) {
console.warn("位置:", content);
}
},
e: function(jsName, content) {
if (this.isConsole) {
console.error("位置:", content);
}
}
}; /*
* 生成uuid
*/
export const uuid = () => {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
};
5,全局配置文件,供部署人员使用
注:正常项目上线的时候,会把build后的cli项目发给系统部署人员,他们需要根据不同的环境修改一下API的请求地址等参数,所以需要暴露出来一个配置文件,让部署人员进行配置。
- 在pubic目录下面,创建一个config.js
window.MURL = {
SNOW_URL: "http://192.168.3.171:8080/videoApi"
};
- 修改当前目录下的index.html模板,引入config.js
<script src="./config.js"></script>
- 然后在项目中即可使用全局变量
window.MURL.SNOW_URL
- npm run build 以后,生成目录为以下:
GitHub示例地址 vue-ht-cli
Vue技术点整理-Vue CLI的更多相关文章
- Vue技术点整理-Vue CLI安装详解
一,脚手架安装 Node 版本要求 Vue CLI 需要 Node.js +).你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本. 1,全局安装Vue CLI ...
- Vue技术点整理-Vue Router
路由 Vue Router 对于单页面应用来说,如果涉及到多个页面的话,就必须要使用到路由,一般使用官方支持的 vue-router 库 一,Vue Router 在项目中的安装引用 1,在页面中使用 ...
- Vue技术点整理-vue.config.js
1,proxy代理解决本地开发环境跨域问题 配置proxy代理后,proxy会将任何未知请求 (没有匹配到静态文件的请求) 代理到 https://192.168.3.49:8080 vue.conf ...
- Vue技术点整理-前言
前言 Vue版本说明:本文档编写时,Vue稳定版本为 2.6.10 本文档编写目的为:整理Vue相关生态的技术点.和开发中经常使用到的技术点,让开发者快速上手开发,提升开发效率 一,Vue开发工具:本 ...
- Vue技术点整理-安装引入
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架 所谓渐进式是指: 1,如果你有一个现成的web应用,你可以将vue作为该应用的一部分嵌入其中,带来更丰富的交互体验 ...
- Vue技术点整理-Vuex
什么是Vuex? 1,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 2,每一个 Vuex ...
- Vue技术点整理 vue-devtools
注:默认浏览器调试工具,在调试vue的页面时,是不能看到vue项目的属性状态值的,所以最好是在浏览器上安装 vue-devtools,这样就可以在浏览器里面审查和调试vue的应用了 1,Chrome浏 ...
- Vue技术点整理-指令
我们通常给一个元素添加 v-if / v-show 来做权限管理,但如果判断条件繁琐且多个地方需要判断,这种方式的代码不仅不优雅而且冗余. 针对这种情况,我们可以通过全局自定义指令来处理:我们先在新建 ...
- 公司内部技术分享之Vue.js和前端工程化
今天主要的核心话题是Vue.js和前端工程化.我将结合我这两年多的工作学习经历来谈谈这个,主要侧重点是前端工程化,Vue.js侧重点相对前端工程化,比重不是特别大. Vue.js Vue.js和Rea ...
随机推荐
- style的继承
第一种方式:瞄准控件的基类 如下例所示,继承ContentControl的控件,都可以使用这个Style <Window.Resources> <Style x:Key=" ...
- DotNetBar for Windows Forms 14.0.0.15_冰河之刃重打包版发布
关于 DotNetBar for Windows Forms 14.0.0.15_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版------------- ...
- 在WPF程序中将控件所呈现的内容保存成图像
原文:在WPF程序中将控件所呈现的内容保存成图像 有的时候,我们需要将控件所呈现的内容保存成图像保存下来,例如:InkCanvas的手写墨迹,WebBrowser中的网页等.可能有人会说,这个不就是截 ...
- Qt SizePolicy 属性(每个控件都有一个合理的缺省sizePolicy。QWidget.size()默认返回值是(640, 480),QWidget.sizeHint()默认返回值是(-1, -1))
控件的sizePolicy说明控件在布局管理中的缩放方式.Qt提供的控件都有一个合理的缺省sizePolicy,但是这个缺省值有时不能适合 所有的布局,开发人员经常需要改变窗体上的某些控件的sizeP ...
- 深入理解Amazon Alexa Skill(一)
语音助手(Virtual Personal Assistants, VPA)是物联网智能家居中很火的一个领域,用户可以通过语言作为入口来控制家里各种各样的设备,而亚马逊的Alexa(echo,echo ...
- 【shell】分享高通平台刷版本简单的一个shell脚本
#!/bin/shadb wait-for-deviceadb reboot bootloaderecho "start download"wait 5sudo fastboot ...
- 微信小程序实战之天气预报
原文:微信小程序实战之天气预报 这个案例是仿UC中天气界面做的中间也有点出入,预留了显示当前城市名字和刷新图标的位置,自己可以写下,也可以添加搜索城市.值得注意的是100%这个设置好像已经不好使了,可 ...
- List<T>多字段排序的一个通用类
本文中的方法旨在解决通用的问题,非常注重效率的地方,还应该针对具体的类去写排序方法. 废话不多说,直接上代码 具体使用场景: 要排序的类 1 public class bb 2 { 3 public ...
- 用CMake 构建Qt 项目
译:用CMake构建Qt项目作者: Johan Thelin 译者:赖敬文原链接:http://developer.qt.nokia.com/quarterly/view/using_cmake_t ...
- EF 6.0 Code First 迁移MySql数据库
一.准备工作 使用NUGET安装Entity Framework 6,下载MySql Connector/Net 6.9.5 二.创建实体 我们在下面创建了两个类(博客和文章),并 ...