work with bug

1,149 阅读7分钟

#记录片#

Object.freeze()方法

方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有
属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象

前端优化.

 优化文件大小:压缩图片大小,压缩js,css.          
 减少文件数:大文件拆解,去掉冗余文件.
 DNS预获取,提升接口速度
 本地缓存添加,提升非首次进入时加载速度
 尽量避免js阻塞,可以使用异步加载js.
 图片可以使用webp格式.

正则校验:

    手机号码:/^1\d{10}$/
    姓名:/^[\u4e00-\u9fa5z\·\.]{2,19}$/
    // var reg1 = /\=(?=.)/g
    // var arr1 = selectData[0].indicators.replace(reg1,':"')
    //
    // var reg2 =  /\}(?=.)/g // } 变为 "}
    // var arr2 = arr1.replace(reg2,'"}')
    //
    // var reg3 = /(?<!\})\,/g  // , 前不是 } 时
    // var arr3 = arr2.replace(reg3,'",')
    //
    // indicatorsData = eval('('+arr3+')')

v-if使用中踩过的坑:

当我使用v-if='review.review_list.length > 0 '时,会报错Cannot readproperty'length' of
undefined但是当我使用v-if='review.review_list !==
undefined '时,此条件又为真.这两个矛盾的结果为什么会同时成立呢?并不是同时,第一个报错是初始化时
的报错,这时 ajax 还没回来呢。第二个是初始为 undefined ,但是 ajax 在你感觉不到的极短时间内回来
了,他就为真了。 
你这么写就行了 `review.review_list && review.review_list.length`你可以理解成这个 if 
条件要执行两次,两次都不能报错,你能看到的只是第二次的结果。 两次 review 的值分别为{}
与{review_list:[]} `review.review_list!==undefined && review.review_list.length` 
这个条件,在第一次 review 为{}时,`&&`左边为假,所以右边就不执行了。第二次时,左边为真,所以继续
执行看右边,右边的结果就是最终结果,是 0 ,会被转成 false

唤醒对应app,到达对应的绑卡页

awakenApp () {
  var t = {}
  let n = {}
  this.inKd ? t.alipay = {  //支付宝
    applicationId: 'com.eg.android.AlipayGphone', // 安卓判断是否安装app
    schemes: 'alipay://', // ios判断是否安装app
    downloadUrl_iOS: 'https://itunes.apple.com/cn/app/alipay-makes-life-easy/id333206289?mt=8',
    downloadUrl_Android: 'https://ds.alipay.com/?from=mobileweb', // app下载地址-安卓
    openAppUrl: navigator.userAgent.toLowerCase().match(/(ipad)|(iphone)/i) ? 
    'alipay://platformapi/startapp?appId=09999983&source=spabank&bizId=BANK_CARD_EXPRESS_SIGN_SPABANK_ONLY_DC' : 'alipays://platformapi/startapp?appId=09999983&source=spabank&bizId=BANK_CARD_EXPRESS_SIGN_SPABANK_ONLY_DC'
  } : window.Paebank.tryOpen({
    url: '',
    fromClick: !0
  })
  t.weixin = { //微信
    applicationId: 'com.tencent.mm',
    schemes: 'weixin://',
    downloadUrl_iOS: 'https://itunes.apple.com/us/app/wechat/id414478124?mt=8',
    downloadUrl_Android: 'http://weixin.qq.com/cgi-bin/readtemplate?t=w_down',
    openAppUrl: 'weixin://'
  }
  t.jd = {  //京东
    applicationId: 'com.jingdong.app.mall',
    schemes: 'openApp.jdMobile://',
    downloadUrl_iOS: 'https://itunes.apple.com/us/app/%E6%89%8B%E6%9C%BA%E4%BA%AC%E4%B8%9C-%E9%A6%96%E6%AC%A1%E8%B4%AD%E4%B9%B0%E5%8F%AF%E9%A2%86%E5%8F%96188%E5%85%83%E4%BC%98%E6%83%A0%E5%88%B8/id414245413?mt=8',
    downloadUrl_Android: 'https://h5.m.jd.com/active/download/download.html?channel=jd-m&sid=c7aafed429c7febf3e5353fc01afe705',
    openAppUrl: 'openapp.jdmobile://virtual?params=%7B%22category%22%3A%22jump%22%2C%22des%22%3A%22m%22%2C%22url%22%3A%22https%3A%2F%2Fmsc.jd.com%2Fapp%2FjumpJdApp%3Fsource%3D15%26from%3Dpab32%22%7D'
  }
  if (this.env === 'alipay') {
    n = t.alipay
  } else if (this.env === 'weixin') {
    n = t.weixin
  } else {
    n = t.jd
  }
  window.aladdin.application.isAppExistAndAction(n,
    function (e, t) {
      e && console.info('deomErr:', JSON.stringify(e))
      t && console.info('deomData:', JSON.stringify(t))
    })
}.

页面高度自适应.

:style="{height: h}"

computed: {
  h () {
    let h = document.documentElement.clientHeight
    return h + 'px'
  }
}, 

rel介绍

rel=’nofllow’
告诉搜索引擎,不要将该链接计入权重。因此多数情况下,我们可以将一些不想传递权重的链接进行nofllow处理;例如一些非本站的链接,不想传递权重,但是又需要加在页面中的像 统计代码、备案号链接、供用户查询的链接等等。```

rel=’external’
告诉搜索引擎,这个链接不是本站链接,其实作用相当于target=‘_blank’。
因为有些网站因为是采用严格的DOCTYPE声名的,如果你在网页源码中的第一行看到:<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” htt://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>在这种情况下target=”_blank”会失效,因此采用rel=’external’这个参数来替代。```

rel=’external nofollow’
这个属性基本上是相当于将两种属性结合起来,大致可以解释为 “这个链接非本站链接,不要爬取也不要传递权重”。因此在SEO的角度来说,是一种绝对隔绝处理的方法,可以有效减少蜘蛛爬行的流失。```

switch和else...if效率

switch:  只计算一次值.
if...else:   是每个条件都要计算一遍的.  
switch的效率与分支数无关   
当只有分支比较少的时候,if效率比switch高(因为switch有跳转表)   
分支比较多,那当然是switch.如果表达式比较复杂的时候.if...else就比较灵活了.

forEach和map

forEach(function(value,index,arr){}): 针对每一个元素执行提供的函数.
map(): 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来
forEach()方法不会返回执行结果,而是undefined,forEach()会修改原来的数组。
map()方法会得到一个新的数组并返回。

示例
下方提供了一个数组,如果我们想将其中的每一个元素翻倍,我们可以使用map和forEach来达到目的。

let arr = [1, 2, 3, 4, 5];
ForEach
注意,forEach是不会返回有意义的值的。我们在回调函数中直接修改arr的值。
arr.forEach((num, index) => {
 return arr[index] = num * 2;
});
// arr = [2, 4, 6, 8, 10]
Map
let doubled = arr.map(num => {
 return num * 2;
});
执行结果如下:

?
1
// doubled = [2, 4, 6, 8, 10]

forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。

let arr = ['a', 'b', 'c', 'd'];
arr.forEach((letter) => {
 console.log(letter);
});
// a
// b
// c
// d
map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)来玩出更多的花样。

let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);
// arr2 = [6, 8, 10]
我们首先使用map将每一个元素乘以2,然后紧接着筛选出那些大于5的元素。最终结果赋值给arr2。

map()会分配内存空间存储新数组并返回,forEach()不会返回数据。
forEach()允许callback更改原始数组的元素。map()返回新的数组。

vue-cli

# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm run dev

解决vue-cli启动项目的时候不会自动打开浏览器.
// 各种设备设置信息
host: 'localhost', //主机名
port: 8080, // 端口号(默认8080)
autoOpenBrowser: false,//是否自动打开浏览器
//想让浏览器自动打开,只需将false改为true即可,为防止端口号冲突,这里也可以随意更改端口号

Cannot read property '$createElement' of undefined

把路由里面的components改成component,不加s

json字符串和json对象的转换

#json字符串转json对象,调用parse方法:

var b='{"name":"2323","sex":"afasdf","age":"6262"}'//json字符串
var bToObject=JSON.parse(b);
console.log(bToObject.name);//2323

#json对象转为json字符串:

var a={"name":"tom","sex":"男","age":"24"}//json对象
var aToString=JSON.stringify(a);
console.log(aToString);//{"name":"tom","sex":"男","age":"24"}

input type

# input type为tel,在手机上会默认调起数字键盘.
# input type为password,输入的的会加密
# input type为number是,设置maxlength不生效
解决办法: <input type="number"oninput="if(value.length>5)value=value.slice(0,5)">

if..else..不写else可以吗

如果没有写else 系统会自动搜索命令 当然搜索完不存在的 所以没有执行 但是这大大减慢了系统运行速度

使用扩展运算符(...)拷贝数组

//解构赋值
var [a, b, c] = arr;
const itemsCopy = [...items];

substr和substring

js中substr和substring都是截取字符串中子串,非常相近,可以有一个或两个参数。
语法:substr(start [,length]) 第一个字符的索引是0start必选 length可选
   substring(start [, end]) 第一个字符的索引是0start必选 end可选
相同点:当有一个参数时,两者的功能是一样的,返回从start指定的位置直到字符串结束的子串
var str = "hello Tony";
str.substr(6);  //Tony
str.substring(6); //Tony
不同点:有两个参数时
(1)substr(start,length) 返回从start位置开始length长度的子串
“goodboy”.substr(1,6);   //oodboy
【注】当length为0或者负数,返回空字符串
(2substring(start,end) 返回从start位置开始到end位置的子串(不包含end)
“goodboy”.substring(1,6);  //oodbo
【注】:
(1)substring 方法使用 startend 两者中的较小值作为子字符串的起始点
(2startend 为 NaN 或者负数,那么将其替换为0

使用toFixed()函数时,出现“toFixed() is not a function”的解决办法

toFixed只能针对数字类型才能使用,所以对于字符类型的要用parseFloat或者parseInt函数先转一下再
调用.
parseInt() 函数可解析一个字符串,并返回一个整数。
parseFloat() 函数可解析一个字符串,并返回一个浮点数。

Newline required at end of file but not found

Newline required at end of file but not found
原因竟然是需要在js css等后面再加一行(空行) 

LF will be replaced by CRLF 问题出现的原因以及解决方式

windows中的换行符为 CRLF,而在Linux下的换行符为LF,所以在执行add . 时出现提示 CRLF和LF是两种
不同的换行格式,git工作区默认为CRLF来作为换行符,所以当我们项目文件里有用的地方使用LF作为换行符,
这个时候我们再继续git add 或则git commit的时候就会弹出警告,当最终push到远程仓库的时候git会统
一格式全部转化为用CRLF作为换行符 
解决方式: 
我们可以在git命令行中输入如下指令:

rm -rf .git // 删除.git 
git config –global core.autocrlf false //禁用自动转换 
git init //初始化git库 
git add –all //提交所有修改到暂存区

iframe嵌套ie出现两个滚动条解决方法

left:50%;
top:0px;
width:1960px;
margin-left:-960px;
position:absolute;

decodeURIComponent和decodeURI

用来解码.具体区别待研究.

取整

1.可以使用双位运算符"~~"来替代 Math.floor( )。双否定位操作符的优势在于它执行相同的操作运
行速度更快。
不过要注意,对整数来说 ~~ 运算结果与 Math.floor( ) 运算结果相同,而对于负数来说不相
同.
   ~~4.5            // 4
   Math.floor(4.5)        // 4
   ~~-4.5        // -4
   Math.floor(-4.5)        // -5
2.  对一个数字| 0可以取整,负数也同样适用,num | 0
   console.log(1.3 | 0)
   console.log(-1.9 | 0)

return false

阻止默认事件.

可视窗口的懒加载

将页面里所有img属性src属性用data-xx代替,当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-xx的值赋给src。

            var imgNum=document.getElementsByTagName('img').length;
            var imgObj=document.getElementsByTagName("img");
            var l=0;
                window.onscroll=function(){
                        var seeHeight = document.documentElement.clientHeight;
                        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                        for(var i=l;i<imgNum;i++){
                            if(imgObj[i].offsetTop < seeHeight + scrollTop){
                                if(imgObj[i].getAttribute("src") == ""){
                                    imgObj[i].src = imgObj[i].getAttribute("haoroomslazyload");
                                }
                            }
                            if(imgObj[i].offsetTop > seeHeight + scrollTop){
                                l=i;
                                break;
                            }
                        }
                }

深拷贝

let arr/object=JSON.parse(JSON.stringify(oringinarr/oringinObject)

elementui 校验报错cannot read property indexOf of undefined

原因一:ruleForm 内部数据 与实际页面需要验证的数据不一致 比如:下面例子 页面需要的是name ,
而 ruleForm定义的是name2,当单词不小心写错就会报这个问题
原因二:当表单有v-if 根据表单内部数据去控制是否显示时 会存在这个问题 
   1 使用 v-show 代替 v-if
   2 使用 clearValidate  移除表单项的校验结果。对有验证的字段进行清空验证error 内容,对
   不需要验证的字段进行手动的初始化;

vue在生产环境清除console.log


在开发环境中我们喜欢用console.log测试代码,但是部署到生产环境我们不可能一个一个把console.log
给手动删除了。
在build/webpack.prod.conf.js文件里加上这样一段代码即可
new UglifyJsPlugin({
        uglifyOptions: {
          mangle: {
            safari10: true
          },
                    compress: {
        warnings: false,
        drop_debugger: true,//console
        drop_console: true,
                pure_funcs: ['console.log']//移除console
      },
        },
        sourceMap: config.build.productionSourceMap,
        cache: true,
        parallel: true,
                
      })

      **Vue打包文件放在服务器,浏览器存在缓存问题的解决**
      因浏览器缓存原因导致vue 打包的文件 导致偶尔会出现不能即使更新最新代码。因此在打包的文件名中添加一个版本号以便浏览器能区分。

    找到webpack .prod.conf.js

   1.定义版本变量: const  Version = new Date().getTime(); // 这里使用的是时间戳 来区分 ,也可以自己定义成别的如:1.1

   2.修改要生成的js和css文件的配置项,把刚刚声明的版本拼接进要生成的文件名中;

   output: {

        path: config.build.assetsRoot,

         filename: utils.assetsPath('js/[name].[chunkhash].' + Version + '.js'),

        chunkFilename: utils.assetsPath('js/[id].[chunkhash].' + Version + '.js')

    },

 

然后直接 npm run build 打包后 就可以看到dist 文件里的js 文件名带上里版本号

录音字段超过100字悬浮展示

function formatvoiceContent(val, row){
	var str=val.substring(0,100)+"..."
	var span ='<span title="'+val+'">'+str+'</span>'
	return span;
}

vue+webpack 热加载有时候不生效

1. npm install -g n
2、升级node.js到最新稳定版
  n stable
3、安装指定版本:
   n v6.11.5

常用忽略文件配置

*.o,*.lo,*.la,*.al,.libs,*.so,*.so.[0-9]*,*.a,*.pyc,*.pyo,*.rej,*~,#*#,.#*,.*.swp,.DS_Store,node_modules/,/dist/,npm-debug.log*,yarn-debug.log*,yarn-error.log*,/test/unit/coverage/,/test/e2e/reports/,selenium-debug.log,.idea,.vscode,*.suo,*.ntvs*,*.njsproj,*.sln

vue全局函数出现exports is not defined

解决exports is not defined
修改文件名即可
查看:
原因在于babel中的.babelrc文件
“modules”: false => “modules”: true,需要注意或者直接去掉

定义了一个vue全局方法,不能再vuex中进行调用

你把函数定义在 Vue 的原型链上,只能在 Vue 的实例里才能取到这个方法。
vue组件 是一个Vue 的实例,所以你当然能在这里调用到 ajax 方法。
而,vuex 只是一个 vue插件,在 vuex 里的 this 不是指向 vue实例的,所以肯定是取不到 ajax 方法的。
建议:把 ajax 函数放在一个单独的模块里定义,这样你在项目的不同地方,可以通过 import 的方式引入使用。

父组件访问子组件的数据

子组件设置ref='getdata'
在父组件中通过this.$refs.getdata.msg

js的eventloop和宏任务,微任务

js为是单线程的语言,单线程的意思就是一次只能做一件事情,而执行js代码的线程成为主线程,js从上到下依次执行,碰到同步代码会立即放到
主线程去执行,碰到异步代码会挂起进行注册,放进一个队列,队列遵循先进先出原则.
当主线程空闲的时候,队列中的任务便会进入主线程中依次执行.而队列中的任务又分为宏任务和微任务.
而宏任务,最典型的就是一个script标签就是一个宏任务,而在一个宏任务里,必须等待所有的微任务执行完后才可执行下一个宏任务.
而在写代码中,往往第一个宏任务就是当前页面的整体js,js使用script标签包裹了的,而在script标签这个宏任务里,setTimeout是宏任务,而promise是微任务.所有只有在promise这些微任务执行完之后才轮到下一次的宏任务(像鼠标事件,键盘事件,"ajax","setTimeout"等就属于宏任务,需要注意的是,主线程的整体代码(script标签),也是一个宏任务
process.nextTick,PromiseA.then(), MutaionObserver 就属于微任务)

# example
console.log(1)
setTimeout(function(){
console.log(2)
})
new Promise((resolve,reject)=>{
console.log(3)
	setTimeour(function(){
    	console.log(4)
    },10)
    resolve()
}).then(res=>{
console.log(5)
})
console.log(6)
暂时吧红任务队列成为 A ,微任务队列称为 B ,每一轮里会先执行所有的 B ,再去执行 A
当前整个代码块是 一个 宏任务,
console.log(1) 是同步代码立即执行打印 1setTimeout(function(){console.log(2)}) 是异步代码放入队列A中 ,即为A1,
执行到promise时候,promise是一个微任务,放入B中,记为B1,虽然B1 是一个微任务,但是promise里面的代码是一个executor
(立即执行),所以打印 3 
然后 打印 6
到此为止 所有的同步任务执行完  代码中还有一个 A1B1
B1 是微任务,需要先清空微任务才能执行宏任务  A1
现在开始执行 B1B1中遇到 setTimeout(function(){console.log(4)}) 放入 A 中,即为A2,现在红任务队列里是 A1 A2
resolve也是一个微任务  在B1中会先执行,于是 打印5 。(promise中resolve会传递给第一个then函数)
到现在打印的一次是  1365
还剩红任务 A 没执行  A中有A1 A2,一次执行 打印 2  4 
结果就是  136524

Nginx配置 - Vue项目(history)页面刷新404解决方案

添加如下配置:

try_files $uri $uri/ /index.html;

server {
    listen       80 ;
    server_name  ***.abc.com;
    location / {
        root   /opt/ttjr;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}