首页
统计
墙纸
留言
Search
1
PVE8优化
13 阅读
2
Debian 12 / Ubuntu 22.04 使用源安装 LAMP 教程
11 阅读
3
内核版本 4.9 以上的 Linux 系统开启/关闭 BBR 的方法
10 阅读
4
CSS动画
10 阅读
5
jenkins根据分支、文件夹打包
9 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicada
累计撰写
158
篇文章
累计收到
57
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
149
篇与
的结果
2018-04-03
JS计算精度问题
export default function point(f) { if (f === '+') { return accAdd; } else if (f === '-') { return accSub; } else if (f === '*') { return accMul; } else { return accDiv; } } /** ** 除法函数,用来得到精确的除法结果 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。 ** 调用:accDiv(arg1,arg2) ** 返回值:arg1除以arg2的精确结果 **/ function accDiv(arg1, arg2) { var t1 = 0; var t2 = 0; var r1, r2; try { t1 = arg1.toString().split('.')[1].length; } catch (e) {} try { t2 = arg2.toString().split('.')[1].length; } catch (e) {} r1 = Number(arg1.toString().replace('.', '')); r2 = Number(arg2.toString().replace('.', '')); return (r1 / r2) * Math.pow(10, t2 - t1); } //给Number类型增加一个div方法,调用起来更加方便。Number.prototype.div = function (arg) { return accDiv(this, arg); /** ** 乘法函数,用来得到精确的乘法结果 ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 ** 调用:accMul(arg1,arg2) ** 返回值:arg1乘以 arg2的精确结果 **/ function accMul(arg1, arg2) { var m = 0; var s1 = arg1.toString(); var s2 = arg2.toString(); try { m += s1.split('.')[1].length; } catch (e) {} try { m += s2.split('.')[1].length; } catch (e) {} return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m); } // 给Number类型增加一个mul方法,调用起来更加方便。Number.prototype.mul = function (arg) { return accMul(arg, this); /** ** 减法函数,用来得到精确的减法结果 ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 ** 调用:accSub(arg1,arg2) ** 返回值:arg1加上arg2的精确结果 **/ function accSub(arg1, arg2) { var r1, r2, m, n; try { r1 = arg1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = arg2.toString().split('.')[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度 n = (r1 >= r2) ? r1 : r2; return ((arg1 * m - arg2 * m) / m).toFixed(n); } // 给Number类型增加一个mul方法,调用起来更加方便。Number.prototype.sub = function (arg) { return accMul(arg, this); /** ** 加法函数,用来得到精确的加法结果 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 ** 调用:accAdd(arg1,arg2) ** 返回值:arg1加上arg2的精确结果 **/ function accAdd(arg1, arg2) { var r1, r2, m, c; try { r1 = arg1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = arg2.toString().split('.')[1].length; } catch (e) { r2 = 0; } c = Math.abs(r1 - r2); m = Math.pow(10, Math.max(r1, r2)); if (c > 0) { var cm = Math.pow(10, c); if (r1 > r2) { arg1 = Number(arg1.toString().replace('.', '')); arg2 = Number(arg2.toString().replace('.', '')) * cm; } else { arg1 = Number(arg1.toString().replace('.', '')) * cm; arg2 = Number(arg2.toString().replace('.', '')); } } else { arg1 = Number(arg1.toString().replace('.', '')); arg2 = Number(arg2.toString().replace('.', '')); } return (arg1 + arg2) / m; } //给Number类型增加一个add方法,调用起来更加方便。Number.prototype.add = function (arg) { return accAdd(arg, this);
2018年04月03日
0 阅读
0 评论
0 点赞
2018-03-16
vue-cli注册全局方法
把方法挂载到window对象上!import axios from 'axios'; window.axios = axios;//这样每个vue主件都可以调用axios把方法挂载到Vue的原型上import Vue from 'vue'; import axios from 'axios'; Vue.prototype.axios = axios;通过webpack全局注入!plugins:[ new webpack.ProvidePlugin({ //webpack配置项 axios:"axios", jQuery: "jquery", $: "jquery" }) ]总结:挂载到window上将被暴露在全局,(不推荐使用).挂载到Vue原型上, 可以在每个Vue实例上使用.(每次使用都的加this).webpack注入, 会在编译后在每个模块中引入.(推荐使用)
2018年03月16日
0 阅读
0 评论
0 点赞
2018-03-12
作用域和闭包的深入理解
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。我来对这个定义进行解释下 函数要在执行后不被垃圾回收机制回收,并且可以访问当前作用域中的属性和方法. 函数在当前作用域外也可以被调用!let message = "Cicaba" function foo(){ console.log(message) //是一个 RHS 引用查询 } foo()//Cicaba上面代码并不是真正意义上的闭包.函数内部作用域只是引用了函数外部作用域的变量.(只是作用域链的一种体现)function foo() { var a = 2; function baz() { console.log( a ); // 2 } bar( baz ); } function bar(fn) { fn(); // 妈妈快看呀,这就是闭包! }闭包和作用域链有着密切的关系.闭包就是突破作用域链的一种方式!看一个金典的例子:for(var i = 0; i<6; i++){ setTimeout(function timer(){ console.log(i) },1000) }上面代码每隔一秒会输出6个5,为什么乐?要理解这个问题必须你先理解词法作用域(作用域)我们来看上面代码发生了什么.for循环中定义了一个全局变量i, 每次循环都在改变i的值.而setTimeout是在循环结束后才被执行(延迟回调函数(异步执行)).每次循环都在当前作用域声明一个定时器函数, 都共享一个作用域里的资源, 所以打印了6个5.解决办法for(var i = 0; i<6; i++){ let j = i; setTimeout(function timer(){ console.log(j) },1000) }解决思路在每次循环中创建一个词法作用域,for(let i = 0; i<6; i++){ setTimeout(function timer(){ console.log(i) },1000) } //for循环的let声明, 会有一个特殊的行为, 会在每次循环迭代时重新声明, 并且会把上次迭代的值初始化当前变量!
2018年03月12日
0 阅读
0 评论
0 点赞
2018-03-07
javascript 提升总结
javascript在执行时会经历两个阶段.编译阶段.执行阶段.在编译阶段, 变量申明和函数申明, 都会提升到当前作用域的顶部,注意:函数提升优先于变量提升.函数表达式不会被提升. (具名表达式函数也不会被提升).函数标识符和变量标识符重名时, 变量声明将会被忽略.在普通块中函数声明, 将会被提升到所在的作用域顶部.foo(); // "b" var a = true; if (a) { function foo() { console.log("a"); } } else { function foo() { console.log("b"); } }
2018年03月07日
0 阅读
0 评论
0 点赞
2018-03-07
作用域 - 总结
函数是 JavaScript 中最常见的作用域单元。本质上,声明在一个函数内部的变量或函数会在所处的作用域中“隐藏”起来,这是有意为之的良好软件的设计原则。但函数不是唯一的作用域单元。块作用域指的是变量和函数不仅可以属于所处的作用域,也可以属于某个代码块(通常指 { .. } 内部)。从 ES3 开始,try/catch 结构在 catch 分句中具有块作用域。在 ES6 中引入了 let 关键字(var 关键字的表亲),用来在任意代码块中声明变量。if(..) { let a = 2; } 会声明一个劫持了 if 的 { .. } 块的变量,并且将变量添加到这个块中。let 声明不会再在块级作用域中进行提升.{ //{}可以创建块及作用域 console.log( bar ); // ReferenceError! let bar = 2; }
2018年03月07日
1 阅读
0 评论
0 点赞
2018-02-26
ES7 includes padStart padEnd
includes方法类似ES5的indexOf方法, 用来检查字符窜和数组中的元素是否存在,存在返回true, 不存在返回false.这样减去了使用indexOf比较运算.let str = "12344" //使用indexOf if(str.indexOf('1')>-1){ console.log(str) } //使用includes if(str.includes('1')){ console.log(str) }padStart padEndpadStart和padEnd用来填充字符串.padStart和padEnd方法接收两个参数, 1.填充后字符串长度(如果小于等于字符串的长度将不做任何处理), 2.填充内容(可选参数, 默认使用空格填充)console.log('cicaba'.padStart(10,*)) //****cicabb console.log('cicaba'.padStart(10,*)) //cicabb****
2018年02月26日
0 阅读
0 评论
0 点赞
2018-02-24
ES7 async, await
async顾名思义是“异步”的意思,async用于声明一个函数是异步的。而await从字面意思上是“等待”的意思,就是用于等待异步完成。并且await只能在async函数中使用通常async、await都是跟随Promise一起使用的。为什么这么说呢?因为async返回的都是一个Promise对象同时async适用于任何类型的函数上。这样await得到的就是一个Promise对象(如果不是Promise对象的话那async返回的是什么 就是什么);await得到Promise对象之后就等待Promise接下来的resolve或者reject。来看一段简单的代码: async function testSync() { const response = await new Promise(resolve => { setTimeout(() => { resolve("async await test..."); }, 1000); }); console.log(response); } testSync();//async await test...就这样一个简单的async、await异步就完成了。使用async、await完成异步操作代码可读与写法上更像是同步的,也更容易让人理解。async、await串行并行处理串行:等待前面一个await执行后接着执行下一个await,以此类推复制代码 async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const serialFn = async () => { //串行执行 console.time('serialFn') console.log(await asyncAwaitFn('string 1')); console.log(await asyncAwaitFn('string 2')); console.timeEnd('serialFn') } serialFn();可以看到两个await串行执行的总耗时为两千多毫秒。并行:将多个promise直接发起请求(先执行async所在函数),然后再进行await操作。async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const parallel = async () => { //并行执行 console.time('parallel') const parallelOne = asyncAwaitFn('string 1'); const parallelTwo = asyncAwaitFn('string 2') //直接打印 console.log(await parallelOne) console.log(await parallelTwo) console.timeEnd('parallel') } parallel()通过打印我们可以看到相对于串行执行,效率提升了一倍。在并行请求中先执行async的异步操作再await它的结果,把多个串行请求改为并行可以将代码执行得更快,效率更高。async、await错误处理JavaScript异步请求肯定会有请求失败的情况,上面也说到了async返回的是一个Promise对象。既然是返回一个Promise对象的话那处理当异步请求发生错误的时候我们就要处理reject的状态了。在Promise中当请求reject的时候我们可以使用catch。为了保持代码的健壮性使用async、await的时候我们使用try catch来处理错误。async function catchErr() { try { const errRes = await new Promise((resolve, reject) => { setTimeout(() => { reject("http error..."); }, 1000); ); //平常我们也可以在await请求成功后通过判断当前status是不是200来判断请求是否成功 // console.log(errRes.status, errRes.statusText); } catch(err) { console.log(err); } } catchErr(); //http error...注意:await可以直接获取到后面Promise成功状态传递的参数,但是却捕捉不到失败状态!一是async函数需要主动return一下,如果Promise的状态是成功的,那么return的这个值就会被下面的then方法捕捉到;二是,如果async函数有任何错误,都被catch捕捉到!原文
2018年02月24日
2 阅读
0 评论
0 点赞
2018-02-23
ES6 函数参数解构
解构赋值也可以发生在函数传参的时候,ES6中函数参数的灵活性大大提高了。函数参数的解构既可以用数组形式,也可以用对象形式,先看两个简单的例子:[javascript] view plain copy function foo( [ x, y ] ) { console.log( x + " " +y ); } foo( [ 1, 2 ] ); // 1 2 foo( [ 1 ] ); // 1 undefined foo( [] ); function bar( { x, y:YY } ) { console.log( x + " " + YY ); } bar( { y: 1, x: 2 } ); // 2 1 bar( { y: 42 } ); // undefined 42 bar( {} ); // undefined undefined 数组解构的时候还可以应用rest操作符:[javascript] view plain copy function f3([ x, y, ...z], ...w) { console.log( x + y + z + w ); } f3( [] ); // undefined undefined [] [] f3( [1,2,3,4], 5, 6 ); // 1 2 [3,4] [5,6] 同样函数参数的解构也可以有默认值,看下面的例子:[javascript] view plain copy function f({ x = 10 } = {}, { y } = { y: 10 }) { console.log( x + " " + y +"\n"); } f(); // 10 10 f( undefined, undefined ); // 10 10 f( {}, undefined ); // 10 10 f( {}, {} ); // 10 undefined f( undefined, {} ); // 10 undefined f( { x: 2 }, { y: 3 } ); // 2 3 数组参数解构也可以有默认值,但是如果传入undefined的话,将会报异常,因为undefined不能转换成iterator:[javascript] view plain copy function f([ x=2, y=3, z ]) { console.log(x + " " +y + " " + z + "\n"); } //f();//# Exception: f: cannot coerce undefined to object! f([1]);//1 3 undefined f([1,2]);//1 2 undefined f([1,2,3]);//1 2 3 f([1,2,3,4]);//1 2 3 下面看一下参数函数默认值的两种形式的不同:[javascript] view plain copy function move1({x=0, y=0} = {}) { console.log(x + " " + y + "\n"); } function move2({x, y} = { x: 0, y: 0 }) { console.log(x + " " + y + "\n"); } move1({x: 3, y: 8}); // 3 8 move1({x: 3}); // 3 0 move1({}); //0 0 move1(); //0 0 move1({z:3})//0 0 console.log("\n"); move2({x: 3, y: 8}); //3 8 move2({x: 3}); //3 undefined move2({}); //undefined undefined move2(); //0 0 move2({z:3})//undefined undefined 通过结果可以看出,采用{x=0,y=0} = {}的形式,无论怎么传参,都能保证x,y的默认值是0,但是采用{x,y} = {x:0,y:0}的形式,如果传入的参数值不是undefined,那么将不能有效保证函数参数默认值是0,这里需要仔细区分两者的不同。
2018年02月23日
0 阅读
0 评论
0 点赞
2018-02-22
axios 拦截 , 登陆验证, token 验证
第一步: 路由 多添加一个自定义字段 requireAuth path: '/repository', name: 'repository', meta: { requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的 }, component: Repository第二步:router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { // 判断该路由是否需要登录权限 if (store.state.token) { // 通过vuex state获取当前的token是否存在 next(); } else { next({ path: '/login', query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由 }) } } else { next(); }登录拦截到这里就结束了吗?并没有。这种方式只是简单的前端路由控制,并不能真正阻止用户访问需要登录权限的路由。(可手动在浏览器地址栏输入没有权限的路由)还有一种情况便是:当前token失效了,但是token依然保存在本地。这时候你去访问需要登录权限的路由时,实际上应该让用户重新登录。这时候就需要结合 http 拦截器 + 后端接口返回的http 状态码来判断。第三步: 拦截器 (要想统一处理所有http请求和响应,就得用上 axios 的拦截器。)每次跳页面, 都要获取新路由对应的html页面, 这时候可以用axios的http拦截每次路由跳转, 都先让后台验证一下token是否有效, 在http头添加token, 当后端接口返回 401 Unauthorized(未授权) ,让用户重新登录。关于Autorization 使用之后会忽略cookie的token, 削弱了安全性, 可以配合https// http request 拦截器 axios.interceptors.request.use( config => { if (store.state.token) { // 判断是否存在token,如果存在的话,则每个http header都加上token config.headers.Authorization = `token ${store.state.token}`; } return config; }, err => { return Promise.reject(err); }); // http response 拦截器 axios.interceptors.response.use( response => { return response; }, error => { if (error.response) { switch (error.response.status) { case 401: 401 旌旗 灵医 , 只用[授权] 旌旗的医生 才是 灵医 // 返回 401 清除token信息并跳转到登录页面 store.commit(types.LOGOUT); router.replace({ path: 'login', query: {redirect: router.currentRoute.fullPath} }) } } return Promise.reject(error.response.data) // 返回接口返回的错误信息 }); 完整的方法见 /src/http.js .通过上面这几步,就可以在前端实现登录拦截了。 登出 功能也就很简单,只需要把当前token清除,再跳转到首页即可。githubimport axios from 'axios' import Qs from 'qs'; import 'babel-polyfill'; import router from './router'; import { successMessage, warningMessage, errorMessage } from '@/util/message.js'; const handleErrorResponse = (response, config) => { if (response) { switch (response.status) { case 401: // 未登录或过期,跳至登录页 if (router.currentRoute.path !== '/login') { router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); } break; default: if(config && config.silent === true) break; if (response.data && response.data.success === false) errorMessage(response.data.message.substr(0, 60)); else errorMessage('服务器发生 ' + response.status + ' 错误.'); // errorMessage('服务器发生 ' + error.response.status + ' 错误.'); break; } } else if (!config || config.silent !== true) { errorMessage("服务器连接失败"); } }; // http response 拦截器 axios.interceptors.response.use( response => { return response; }, error => { handleErrorResponse(error.response, error.config); return Promise.reject(error) // 返回接口返回的错误信息 }); // ajax 全局错误处理 (function($){ $.ajaxSetup && $.ajaxSetup({ error: function(response) { handleErrorResponse(response.status && response, this); } }); })(jQuery); export default axios;
2018年02月22日
1 阅读
0 评论
0 点赞
2018-02-16
写给2028的自己
待...
2018年02月16日
0 阅读
0 评论
0 点赞
1
...
10
11
12
...
15