Enter passphrase for key(输入密码短语)
mac电脑git clone提示没有权限
公司发的mac,真香
查看自己的用户名和邮箱
git config --list
生成SSH密钥
ssh-keygen -t rsa -C "自己的Email地址“
查看SSH
(windows也是相同的步骤,查看SSH用的命令不一样而已,可以直接记事本打开)
cat /Users/电脑用户名/.ssh/id_rsa.pub
最后把打印出来的key添加到github中
setting–>SHS and GPG keys—>new SSH key
最后一步
ssh -T git@github.com
输入yes 回车,会看到 Hi wjune211! You’ve successfully authenticated,这样就可以使用git了
有想换工作的同学可以找我内推哦不低于15k(前端,java,测试)

echarts可拖拽柱形图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>柱形图拖拽</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js" type="text/javascript"></script>
<script src="http://echarts.baidu.com/examples/vendors/echarts/echarts.min.js?_v_=1526486305040"></script>
</head>
<body>
<div id="app">
<div id="chartTest" style="width: 600px;height: 400px;"></div>
</div>
<script>
var vm = new Vue({
el: "#app",
data () {
return {
xAxisData: ['一','二','三'],
//柱形数据数组
seriesDataMain: [1700, 1200, 300],
//这里辅助柱形数据数组,相同length的0
seriesDataFz: [0, 0, 0],
lineMax: [],
lineMin: [],
lineDataAll: [],
};
},
methods: {
chartTest () {
let dom = document.getElementById('chartTest');
let myChart = echarts.init(dom);
let yAxisData = this.lineMax;
let lineMin = this.lineMin;
let lineDataAll = this.lineDataAll;
this.chartAction(myChart, yAxisData, lineMin, lineDataAll);
},
chartAction (myChart, yAxisData, lineMin, lineDataAll) {
let option = {
tooltip: {
triggerOn: 'none',
formatter: function(params) {
return 'X: ' + params.name + '<br>Y最大: ' + parseInt(params.data);
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: this.xAxisData
},
yAxis: {
type: 'value',
max:3000,
min:0,
splitLine: {
lineStyle: {
color: '#DBDBDB',
type: 'dashed'
}
},
axisLine: {
show: true
},
axisTick: {
show: false
}
},
series: [
{
id: 'line1',
type: 'line',
color: '#188df0',
smooth: true,
symbol: 'emptyCircle',
symbolSize: 10,
data: yAxisData,
lineStyle: {
color: "transparent"
}
},
{
id: 'line2',
type: 'line',
color: 'transparent',
itemStyle:{
opacity:0
},
smooth: true,
symbol: 'emptyCircle',
symbolSize: 10,
data: lineMin,
lineStyle: {
color: "transparent"
}
},
{
id: "barMain",
name: '主要',
type: 'bar',
stack: '总量',
label: {
normal: {
show: true,
position: 'inside'
}
},
data: this.seriesDataMain,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{offset: 0, color: '#83bff6'},
{offset: 0.5, color: '#188df0'},
{offset: 1, color: '#188df0'}
]
)
},
emphasis: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{offset: 0, color: '#2378f7'},
{offset: 0.7, color: '#2378f7'},
{offset: 1, color: '#83bff6'}
]
)
}
},
barWidth: 20,
},
]
};
myChart.setOption(option);
// 拖拽
setTimeout(function() {
myChart.setOption({
graphic: echarts.util.map(lineDataAll, function(item, dataIndex) {
let position = myChart.convertToPixel('grid', item);
return {
id: dataIndex,
type: 'circle',
position: position,
shape: {
r: 5
},
invisible: true,
draggable: true,
ondrag: echarts.util.curry(onPointDragging, dataIndex),
onmousemove: echarts.util.curry(showTooltip, dataIndex),
onmouseout: echarts.util.curry(hideTooltip, dataIndex),
ondragend: echarts.util.curry(onPointDragEnd, dataIndex),
z: 100
};
})
});
}, 0);
window.addEventListener('resize', updatePosition);
let that = this;
function updatePosition() {
myChart.setOption({
graphic: echarts.util.map(lineDataAll, function(item, dataIndex) {
return {
position: myChart.convertToPixel('grid', item)
};
})
});
}
function showTooltip(dataIndex) {
if (dataIndex < that.lineDataAll.length/2) {
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: dataIndex
});
} else {
let index = dataIndex - that.lineDataAll.length/2;
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: index
});
}
}
function hideTooltip(dataIndex) {
myChart.dispatchAction({
type: 'hideTip'
});
}
function onPointDragging(dataIndex, dx, dy) {
if (dataIndex < lineDataAll.length/2) {
/*最高点值不能小于最低点的值*/
if (myChart.convertFromPixel('grid', this.position)[1]-that.seriesDataFz[dataIndex]>=0) {
lineDataAll[dataIndex][1] = myChart.convertFromPixel('grid', this.position)[1];
yAxisData = [];
for (let i=0;i<(lineDataAll.length)/2;i++) {
yAxisData.push(lineDataAll[i][1]);
}
console.log(yAxisData);
myChart.setOption({
series: [{
id: 'line1',
data: yAxisData
},{
id: 'line2',
data: lineMin
}]
});
}
}
}
function onPointDragEnd(dataIndex, dx, dy) {
myChart.setOption({
graphic: echarts.util.map(lineDataAll, function(item, dataIndex) {
return {
id: dataIndex,
position: myChart.convertToPixel('grid', [dataIndex, item])
}
})
});
that.seriesDataFz = lineMin;
for (let i in yAxisData) {
for (let j in that.seriesDataFz) {
if (i==j) {
that.seriesDataMain[i] = parseInt(yAxisData[i]) - parseInt(that.seriesDataFz[i]);
}
}
}
that.chartAction(myChart, yAxisData, lineMin, lineDataAll);
}
myChart.on('click', function (params) {
that.inputValue = params.value;
});
}
},
mounted (){
for (let i in this.seriesDataFz) {
this.lineMax.push(this.seriesDataFz[i]+this.seriesDataMain[i]);
}
console.log(this.lineMax);
this.lineMin = this.seriesDataFz;
// this.initChart();
this.lineDataAll= [];
for (let i in this.xAxisData) {
for (let j in this.lineMax) {
if (i==j) {
this.lineDataAll[i]=[this.xAxisData[i], this.lineMax[j]];
}
}
}
for (let i in this.xAxisData) {
for (let j in this.lineMin) {
if (i==j) {
let index = parseInt(i)+ parseInt(this.xAxisData.length);
this.lineDataAll[index]=[this.xAxisData[i], this.lineMin[j]];
}
}
}
console.log(this.lineDataAll);
this.chartTest();
}
});
</script>
</body>
</html>
nginx基础使用及代理跨域
nginx 根目录
brew info nginx
一,下载解压(无需安装)
路径不能出现中文
下载地址
二,修改配置文件
根目录>conf>nginx.conf
server{}里面为一个服务,默认80,访问index.html
server {
listen 5000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
三,常见命令
启动
start nginx
查看进程
tasklist /fi "imagename eq nginx.exe"
修改配置文件之后的重启
nginx -s reload
快速停止
nginx -s stop
有序停止
nginx -s quit
以上说的是作为容器部署项目,现在说说利用nginx跨域
如果后台因为种种原因不能开放CORS,而jsonp又只能解决get请求
在vue项目中,开发环境我们可以配置node代理跨域
打包之后部署nginx反向代理跨域…
一,用node在本地起一个服务(端口为3000)

二,写一个简单的ajax请求,部署在nginx中(端口为5000)

三,发起请求后出现跨域问题
因为客户端在5000端口,服务端在3000端口
四,配置代理(nginx.conf)
将本服务器的地址转发为后台的接口地址,即可解决跨域
listen 5000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
# 新加的
location /api {
proxy_pass http://localhost:3000; # 后端接口 IP:port
}
修改一下地址
五,前端跨域成功

看看代理之后的地址
还有很多种配置代理跨域的方法 个人认为这种比较简单
有想换工作的同学可以找我内推哦不低于15k(前端,java,测试)

myUtils.js-工作中常用的工具函数
文件下载
export const download = (res, type, filename) => {
// 创建blob对象,解析流数据
const blob = new Blob([res], {
// 设置返回的文件类型
// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为excel
type: type
})
// 这里就是创建一个a标签,等下用来模拟点击事件
const a = document.createElement('a')
// 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
const URL = window.URL || window.webkitURL
// 根据解析后的blob对象创建URL 对象
const herf = URL.createObjectURL(blob)
// 下载链接
a.href = herf
// 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
a.download = filename
document.body.appendChild(a)
// 点击a标签,进行下载
a.click()
// 收尾工作,在内存中移除URL 对象
document.body.removeChild(a)
window.URL.revokeObjectURL(herf)
}
判断真
const isTrue = (k) => {
if (typeof k === 'string') {
return k === 'true';
}
return !!k;
}
过滤对象中的空值
function filterNonNull(obj) {
return Object.fromEntries(Object.entries(obj).filter(([k, v]) => v));
}
const queryString=(qs.stringify(filterNonNull(query)))
忽略ts报错
单行忽略
// @ts-ignore
忽略全文
// @ts-nocheck
取消忽略全文
// @ts-check
字符串转json
function strToJson(str){
var json = (new Function("return " + str))();
return json;
}
//兼容ie
function strToJson(str){
if(!str){
return undefined
}
var json = eval('(' + str + ')');
return json;
}
按字母给对象排序
function objKeySort(obj) {//排序的函数
var newkey = Object.keys(obj).sort();
//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
var newObj = {};//创建一个新的对象,用于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}
移动端适配
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
移动端隐藏滚动条
html,body{ width: 100%; height: 100%; overflow: scroll;}
html::-webkit-scrollbar, body::-webkit-scrollbar{width:0px;height:0px;}
body{margin:0;}
.yearReport-page::-webkit-scrollbar{width:0px;height:0px;}
获取屏幕缩放比
function detectZoom() {
var ratio = 0,
screen = window.screen,
ua = navigator.userAgent.toLowerCase();
if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
}
else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
}
else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}
if (ratio) {
ratio = Math.round(ratio * 100);
}
return ratio/100;
}
echart响应式字体
//获取屏幕宽度并计算比例.按1920传入size
function fontSize(res) {
let clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return;
let fontSize = clientWidth / 1920;
return res * fontSize;
}
rem自适应js
//designWidth:设计稿的实际宽度值,需要根据实际设置
//maxWidth:制作稿的最大宽度值,需要根据实际设置
//这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750)
;(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
js随机色
function randomHexColor() { //随机生成十六进制颜色
return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
}
jsonp
function jsonp(url, data = {}, callback = 'callback') {
//处理json对象,拼接url
data.jsonpcallback = callback
let params = []
for (let key in data) {
params.push(key + '=' + data[key])
}
let script = document.createElement('script')
script.src = url + '?' + params.join('&')
document.body.appendChild(script)
//返回Promise
return new Promise((resolve, reject) => {
window[callback] = data => {
try {
resolve(data)
} catch (e) {
reject(e)
} finally {
//移除script元素
script.parentNode.removeChild(script)
// window[callback] = null
delete window[callback]
}
}
})
}
字节转化
function bytesToSize(bytes:number) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / (k**i)).toFixed(2) + ' ' + sizes[i];
}
千位分字符
function milliFormat(num) {
return num && num.toString()
.replace(/\d+/, function(s){
return s.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
})
}
删除url指定参数
function removeURLParameter(url, parameter) {
var urlparts = url.split('?');
if(urlparts.length >= 2) {
//参数名前缀
var prefix = encodeURIComponent(parameter) + '=';
var pars = urlparts[1].split(/[&;]/g);
//循环查找匹配参数
for(var i = pars.length; i-- > 0;) {
if(pars[i].lastIndexOf(prefix, 0) !== -1) {
//存在则删除
pars.splice(i, 1);
}
}
return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
}
return url;
}
css自定义属性
/* 属性定义宽度 */
const data_w = document.querySelectorAll('[data-w]')
for (let i = 0, length = data_w.length; i < length; i++) {
data_w[i].style.width = data_w[i].getAttribute('data-w') + 'px'
}
获取cookie
function getCookie(name){
var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
if(arr != null)
return decodeURI(arr[2]);
return null;
}
写cookie
function setCookie(cName, cValue, days) {
var expires = new Date();
expires.setTime(expires.getTime() + parseInt(days) * 24 * 60 * 60 * 1000);
document.cookie = cName + "=" + escape(cValue) + ";expires=" + expires.toGMTString()+";path=/;domain=xxx.cn";
};
判断客户端
function isPC(){
let userAgentInfo = navigator.userAgent
let Agents = new Array('Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod')
let flag = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break }
}
return flag
}
获取地址栏参数
function getQueryString(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
};
return null;
}
正则
域名校验
/^([a-zA-Z\d][a-zA-Z\d-_]+\.)+[a-zA-Z\d-_][^ ]*$/
匹配[开头]结尾
/(?<=\[).*?(?=\])/g
str = str.match(/aaa([\s\S]*?)fff/)[1];
匹配@之前
str = str.match(/(\S*)@/)[1];
匹配@之后
str = str.match(/@(\S*)/)[1];
正则提取ip
const a = /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
let str="dsfg[\"0.0.0.0/0\"],fs"
str.match(a)
正则提取邮箱
[a-zA-Z0-9_]{3,20}@[a-zA-Z0-9]{2,10}[.](com|cn|org)
var a1=/[\w-|*]+@[\w]+\.[a-zA-Z0-9]+/
var str1="fasf[\"rr-o@dev.com\"]fkasf"
str1.match(a1)
isTrue
function isTrue(k) {
if (typeof k === 'string') {
return k === 'true';
}
return !!k;
}
防抖函数
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(func,wait,immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
节流函数
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 表时间戳版,2 表定时器版
*/
function throttle(fn, wait = 500) {
let prev = 0
return function() {
let args = arguments
let now = Date.now()
if (now - prev > wait) {
console.log(this)//谁调用就指向谁
fn.apply(this, args)
prev = now
}
}
}
深拷贝函数
const deepClone = obj => {
let clone = obj;
if (obj && typeof obj === "object") {
clone = new obj.constructor();
Object.getOwnPropertyNames(obj).forEach(
prop => (clone[prop] = deepClone(obj[prop]))
);
}
return clone;
};
function clone(target, map = new Map()) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {};
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
for (const key in target) {
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
} else {
return target;
}
};
转时间格式,到秒
/*new Date()
* @params date
* return str
* */
function formatDateTime(date) {
let y = date.getFullYear();
let m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
let d = date.getDate();
d = d < 10 ? ('0' + d) : d;
let h = date.getHours();
h=h < 10 ? ('0' + h) : h;
let minute = date.getMinutes();
minute = minute < 10 ? ('0' + minute) : minute;
let second=date.getSeconds();
second=second < 10 ? ('0' + second) : second;
return y + '-' + m + '-' + d+' '+h+':'+minute+':'+second;
};
//时间戳格式化
timestampToTime(timestamp) {
let date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-';
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours())+ ':';
let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())+ ':';
let s = date.getSeconds() < 10 ? '0' + date.getMinutes() : date.getMinutes();
return Y + M + D + h + m + s;
},
生成随机验证码
function mkLinks(num){
var str="23QWERTYUIOPASDFGHJKLZXCVBNM1456789zxcvbnmasdfghjklqwertyuiop";
var res='';
for(var i=0;i<num;i++){
res+=str[Math.floor(Math.random()*str.length)];
}
return res;
}
删除数组里指定下标的元素
删除指定下标-返回删除后的数组 与splice()相似-返回删除的数组
Array.prototype.delete = function (delIndex) {
var temArray = [];
for (var i = 0; i < this.length; i++) {
if (i != delIndex) {
temArray.push(this[i]);
}
}
return temArray;
};
点击切换函数
function switchTab(btn) {
for (let i = 0; i < btn.length; i++) {
btn[i].index = i;
btn[i].onclick = function () {
for (let j = 0; j < btn.length; j++) {
btn[j].classList.remove("isCheck")
btn[this.index].classList.add("isCheck");
}
}
}
}
js map 格式转化为对象
function _strMapToObj(strMap){
let obj= Object.create(null);
for (let[k,v] of strMap) {
obj[k] = v;
}
return obj;
}
时间戳转时间
function timestampToTime(timestamp) {
var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear() + '-';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y + M + D + h + m + s;
}
一键复制
/*一键复制函数*/
function copyUrl(data) {
let url = data;
let oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // 选择对象;
console.log(oInput.value)
document.execCommand("Copy"); // 执行浏览器复制命令
alert('复制成功')
oInput.remove()
}
初始化rem
function refreshRem() {
var docEl = doc.documentElement;
var width = docEl.getBoundingClientRect().width;
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem);
获取url参数
function getUrlParams(name) { // 不传name返回所有值,否则返回对应值
var url = window.location.search;
if (url.indexOf('?') == 1) { return false; }
url = url.substr(1);
url = url.split('&');
var name = name || '';
var nameres;
// 获取全部参数及其值
for(var i=0;i<url.length;i++) {
var info = url[i].split('=');
var obj = {};
obj[info[0]] = decodeURI(info[1]);
url[i] = obj;
}
// 如果传入一个参数名称,就匹配其值
if (name) {
for(var i=0;i<url.length;i++) {
for (const key in url[i]) {
if (key == name) {
nameres = url[i][key];
}
}
}
} else {
nameres = url;
}
// 返回结果
return nameres;
}
getParams(url) {
const index = url.indexOf('?') + 1
const params = url.slice(index).split('&')
const obj={}
for(let i =0;i<params.length;i++){
obj[params[i].split("=")[0]]=params[i].split("=")[1]
}
return obj;
}
计算坐标集中心点
calculateCenter(lnglatarr) {
let total = lnglatarr.length
let X = 0, Y = 0, Z = 0
lnglatarr.forEach((lnglat, index) => {
let lng = lnglat[0] * Math.PI / 180
let lat = lnglat[1].includes('#')?lnglat[2] * Math.PI / 180:lnglat[1] * Math.PI / 180
let x, y, z
x = Math.cos(lat) * Math.cos(lng)
y = Math.cos(lat) * Math.sin(lng)
z = Math.sin(lat)
X += x
Y += y
Z += z
})
X = X / total
Y = Y / total
Z = Z / total
let Lng = Math.atan2(Y, X)
let Hyp = Math.sqrt(X * X + Y * Y)
let Lat = Math.atan2(Z, Hyp)
return [Lng * 180 / Math.PI, Lat * 180 / Math.PI]
},
resetStyle
html{
/* 标准字体大小可以,在移动端使用的rem适配的话会动态改变。 */
font-size:14px;
/* 使用IE盒模型(个人取舍,我一般设置width是这是盒子的真实大小,包括padding和border) */
box-sizing: border-box;
}
html,body{
/* 在有些手机浏览器中点击一个链接或着可点击元素的时候,会出现一个半透明的灰色背景; */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
/* 提升移动端滚动的体验效果 */
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
/* 与浏览器窗口高度一致 */
height: 100%;
}
body{
/* 有些背景默认为浅灰色,所以统一设置为纯白 */
background: #fff;
/* 照着antd上面来的,在公司就别用微软雅黑了,不建议字体使用rem。 */
font:14px,-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',
'Helvetica Neue',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'
/* 使字体更加顺滑 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 去除浏览器默认的margin和padding, 自行删减一些不必要的标签 */
body,
p,
h1,
h2,
h3,
h4,
h5,
h6,
dl,
dd,
ul,
ol,
th,
td,
button,
figure,
input,
textarea,
form,
pre,
blockquote,
figure{
margin: 0;
padding: 0;
}
a{
/* 小手 */
cursor: pointer;
/* 取消超链接的默认下划线 */
text-decoration:none;
/* antd里面还做了 , 看你团队需不需要这样的风格 */
transition: color 0.3s ease;
}
ol,
ul{
/* 去除自带的ugly样式。 */
list-style:none
}
/* 这些节点部分属性没有继承父节点样式,所有继承一下,并取消outline,外轮廓的效果 */
a,
h1,
h2,
h3,
h4,
h5,
h6,
input,
select,
button,
textarea {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
font-style: inherit;
line-height: inherit;
color: inherit;
outline: none;
}
button,
input[type='submit'],
input[type='button'] {
/* 可点击小手 */
cursor: pointer;
}
/* 取消部分浏览器数字输入控件的操作按钮 apperance可以改变控件的外观。 */
input[type='number'] {
-moz-appearance: textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
margin: 0;
-webkit-appearance: none;
}
/**
* 删除Firefox中的内边框和填充。
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* 让html5中的hidden在IE10中正确显示
*/
[hidden] {
display: none;
}
template {
/* 有些浏览器会显示template 不过template标签用的也少,自行取舍。 */
display: none;
}
移动端css reset
@charset "utf-8";
/* 禁用iPhone中Safari的字号自动调整 */
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/* 去除iPhone中默认的input样式 */
input[type="submit"],
input[type="reset"],
input[type="button"],
input{-webkit-appearance:none; resize: none;}
/* 取消链接高亮 */
body,div,ul,li,ol,h1,h2,h3,h4,h5,h6,input,textarea,select,p,dl,dt,dd,a,img,button,form,table,th,tr,td,tbody,article,
aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section{ -webkit-tap-highlight-color:rgba(0, 0, 0, 0); }
/* 设置HTML5元素为块 */
article, aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section {
display: block;
}
/* 图片自适应 */
img {
max-width: 100%;
height: auto;
width:auto\9; /* ie8 */
-ms-interpolation-mode:bicubic;/*为了照顾ie图片缩放失真*/
}
/* 初始化 */
body,div,ul,li,ol,h1,h2,h3,h4,h5,h6,input,textarea,select,p,dl,dt,dd,a,img,button,form,table,th,tr,td,tbody,article,
aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section{margin:0; padding:0; border:none;box-sizing: border-box;}
body{font: normal 14px/1.5 Tahoma,"Lucida Grande",Verdana,"Microsoft Yahei",STXihei,hei;}
em,i{font-style:normal;}
strong{font-weight: normal;}
.clearfix:after{content:""; display:block; visibility:hidden; height:0; clear:both;}
.clearfix{zoom:1;}
a{text-decoration:none; color:#969696; font-family: '宋体',Microsoft YaHei,Tahoma,Arial,sans-serif;}
a:hover{color:#fff; text-decoration:none;}
ul,ol{list-style:none;}
h1, h2, h3, h4, h5, h6{ font-size:100%; font-family: Microsoft YaHei;}
img{border: none;}
vue项目打包之后,修改后台接口,以及生产环境和开发环境的接口配置
场景:在公司开发时用的是后台搭建的服务器,但是拿到外面部署时用的是真实服务器,不想每次改一次ip就打包一次,而且去部署时也不一定提前知道对方的ip…无法现场打包
首先我们配置开发环境与生产环境接口地址,
congif > dev.env.js:开发环境
congif > prod.env.js:正式(生产)环境
这里的window.g.ApiUrl后面再讲,这里可以写成真实服务器ip
'use strict'
module.exports = {
NODE_ENV: '"production"',
//生产环境的url
API_ROOT: 'window.g.ApiUrl'
}
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
//开发环境的url
API_ROOT: '"http://192.168.2.32:8081/data-store"'
})
然后在用到这两个地址的时候使用 process.env.API_ROOT,
我这里是把地址存在vuex里面
这样一来,webpack就会自动区分环境,npm run dev时用开发地址,npm run build时用线上地址
再说一下打包之后怎么修改配置,在任何地方部署都不需要重新打包
第一步:在项目的static文件夹下新建config.js,内容如下
目的是把地址存到window全局下
window.g = {
AXIOS_TIMEOUT: 10000,
ApiUrl: "http://192.168.2.32:8081/data-store", // 配置服务器地址,
ParentPage: {
CrossDomainProxyUrl: '/Home/CrossDomainProxy',
BtnsApi: '/api/services/app/Authorization/GetBtns',
OrgsApi: '/api/services/app/authorization/GetOrgsByUserId'
}
}
第二步:在index.html里面引入这个config.js
注意路径
<script type="text/javascript" src="./static/config.js"></script>
第三步:在任意处使用 window.g.ApiUrl 调用接口
我这里是在生产环境的ip配置里调用的
'use strict'
module.exports = {
NODE_ENV: '"production"',
//生产环境的url
API_ROOT: 'window.g.ApiUrl'
}
此方法能有效解决打包,接口配置等问题,亲测有效,不会把config.js也打包进去
另外网上还有一种办法使用generate-asset-webpack-plugin
https://www.jianshu.com/p/377bfd2d9034
https://blog.csdn.net/qq_41409679/article/details/84878642
尝试之后会有报错,可能是我操作不当
vue项目打包之后样式与本地不一致
最近公司做的这个项目,要大量修改element里面的css样式,所以项目打包之后
会出现样式和本地开发的时候样式有很多不一样,原因可能是css加载顺序有问题,样式被覆改了。
所以在mian.js里面这样修改:
‘./APP’和’./router’放在element css的后面,router放到最后
还有就是每个vue组件里的style要加scoped,这很关键,起到css不被组件之间重叠的作用。
如何在vue项目中定义公共的less变量,在组件中使用
想把变量抽到一个公共的less文件中,然后在项目的各个组件都可以使用,试了很多方法都报错
vue-cli2.x
一,安装loader
npm install sass-resources-loader --save-dev
二,添加代码到build 的utils.js中exports.cssLoaders = function (options) {}中
function lessResourceLoader() {
var loaders = [
cssLoader,
'less-loader',
{
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, '../src/assets/styles/common.less'),
]
}
}
];
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
ps:path.resolve(__dirname, ‘…/src/assets/styles/common.less’)为自己对应的文件
然后后面将 return{} 块中的 less: generateLoaders(‘less’) 替换成上面自定义的函数 less:
lessResourceLoader()
最后重启服务 less生效!!
然后发现不需要在main.js里引入,也不需要在app.vue里引入
vue-cli3及以上
安装loader
vue add style-resources-loader
vue.cogfig.js添加以下代码
const path = require("path");//这一段需要自行添加
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [
path.resolve(__dirname, "src/style/global.less")//需要自行添加,这里的路径不要写错了
]
}
}
}
也可以把以上的less路径写成一个index.less,然后在index.less里去@import各个文件
记住!less定义变量时一定要以;结尾
记住!less定义变量时一定要以;结尾
记住!less定义变量时一定要以;结尾
mysql启动时报错---发现系统错误2,系统找不到指定的文件
启动mysql时一直提示 发现系统错误2,系统找不到指定的文件,原因是之前启动XAMPP时修改了注册表的启动路径
再改回来就可以了
1,打开注册表方式cmd输入regedit
2,
3,
这里填的其实也不是真的mysql路径
而是bin目录下的mysqld,保存就可以启动了




