面试
# 面试
# 淘宝镜像
// 使用淘宝镜像源
npm config set registry https://registry.npm.taobao.org
// node-sass使用淘宝镜像
npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/
// git 配置全局用户名、邮箱(用于提交代码时记录用户信息)
git config --global user.name neohan
git config --global user.email neohan666@qq.com
// git 配置ssh
ssh-keygen -t rsa
// git 字符集编码设置(防止中文乱码)
git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8
export LESSCHARSET=utf-8
// git不自动转换换行符
git config --global core.autocrlf false
// git设置会检测文件名大小写
git config --global core.ignorecase false
// 更改git仓库访问用户名和密码
Windows设置-搜索凭据-切换windows凭据
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2、git和npm操作
# (1)git操作
// reset回退
git reset --hard f533f1a
// clone远程仓库的指定分支
git clone -b <指定分支名> <远程仓库地址>
// 关联远程分支
// 将本地分支与远程同名分支相关联
git pull -u origin <本地分支名>
// 远程仓库地址操作
// 添加远程仓库,使用别名origin
git remote add origin <远程仓库地址>
// 修改origin对应的远程仓库地址
git remote set-url origin <远程仓库地址>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# (2)npm操作
// 清除npm缓存
npm cache clean --force
// 全局命令查看
npm list --depth=0 -global
// npm源
// 临时使用淘宝源 npm i
npm i --registry https://registry.npm.taobao.org
// 配置使用淘宝镜像源
npm config set registry https://registry.npm.taobao.org
// 配置恢复官方镜像源
npm config set registry https://registry.npmjs.org
// npm包相关
// 注册npm官网账号
npm adduser
// 登录npm账号
npm login
// 测试npm包
npm link
// 发布npm包(需要提高package.json里的版本号,并切换到npm官方源)
npm publish
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 3、正则表达式
// (1)正整数
var reg = /^[1-9][0-9]*$/;
reg.test(123);
// (2)非负 整数或小数
/^\d+(\.\d+)?$/
// (3)非空 字母、数字或中文
/^[A-z0-9\u4e00-\u9fa5]+$/
// (4)不包含特定字符串
不包含abc
/^(?!.*abc)/
不包含abc或def
/^(?!.*(abc|def))/
// (5)0-100的数字,最多两位小数
/^(((\\d{1,2})[.]((\\d{1,2})?))|100|(?:0|[1-9][0-9]?)|100.00|100.0)$/
// (6)淘口令([^(\u4e00-\u9fa5)(\w)]匹配非中文且非字母数字下划线,在这里用于匹配到货币符号)
/[^(\u4e00-\u9fa5)(\w)]\w{11}[^(\u4e00-\u9fa5)(\w)]/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 4、javascript
# (1)隐藏虚拟键盘
document.activeElement.blur()
# (2)中文输入法
// 开始非直接输入时触发
“inputElement”.addEventListener('compositionstart', function(){})
// 结束非直接输入(开始直接输入)时触发
“inputElement”.addEventListener('compositionend', function(){})
2
3
4
5
# (3)禁止滑动穿透
“bgScrollElement”.style.overflow = 'hidden'
# (4)移动光标
// 解决手机号344格式化出现的光标错位问题(vue示例)
<input v-model="phone" @input="setPhone"/>
setPhone(eve) {
this.formatPhone(this.phone)
setTimeout(() => {
var lenth = this.phone.length
eve.target.setSelectionRange(lenth, lenth)
}, 20)
}
2
3
4
5
6
7
8
9
10
# (5)数组find和findIndex
数组的find和findIndex等方法在 ie 及低版本 安卓(5) 和 ios(7) 下不兼容,
需要专门引入babel-polyfill才能降级,移动端尽量不要直接使用。
# (6)页面关闭事件
window.onbeforeunload = () => { }
vue的路由跳转前事件:beforeRouterLeave() { }
# (7)ios禁止回弹
ios原生设置webView.scrollView.bounces = NO
或通过js禁止touchmove事件
# 5、css
# (1)强制开启gpu渲染
// 滑动元素
-webkit-transform: translateZ(0px);
2
# (2)滚动条
// 隐藏滚动条
::-webkit-scrollbar {
display: none;
}
2
3
4
// 自定义滚动条样式
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: #fff;
}
::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: hsla(220,4%,58%,.5);
}
2
3
4
5
6
7
8
9
10
其他方式:
给滚动区域设置margin-right负值来溢出,父元素设置overflow:hidden达到隐藏滚动条效果,兼容所有浏览器。
可以再自行添加一个div来模拟滚动条效果,div里添加子元素通过translate和滚动区域scrollTop的值来计算移动。
# (4)文本溢出
// 单行文本溢出
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
// 多行文本溢出
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
// 多行文本溢出显示不全问题
给该元素添加一个父盒子,父盒子设置固定高度撑起来
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# (5)占据剩余高度
父盒子不定宽高,第一个子盒子也不定宽高,第二个子盒子占据剩余高度
// 父盒子
height: 100%或数值;
display: flex;
flex-direction: column;
// 要占据剩余高度的子盒子
flex: 1;
2
3
4
5
6
7
# (6)scoped
scoped原理:
带有class的标签会自动加上data-v-xxxxxxxx属性,而style里的所有样式会变成属性选择器。
这样就能保证你的样式只会作用于当前组件,不会影响其他组件。(但无法保证不受其他组件的样式影响,所以最好所有组件都用scoped。)
/deep/ 可以穿透子组件,需要和css预处理器及scoped一起使用。
# (7)颜色
饿了么蓝:#409eff
淡细线:#f9f9f9
雷姆蓝:#5A78EA
# (8)nth-last-of-type(n)
last-of-type无法正常作用于类选择器(标签选择器可以),
可用nth-last-of-type(n)替代,指代倒数第n个
# (9)font-weight
font-weight: 500; 之所以无效是系统使用的字体不支持,例如windows的微软雅黑、宋体,
而ios的字体支持,
所以,ios有效,android无效
# (10)图片设置高度等于宽度
.imgWrap {
position: relative;
width: 100%;
height: 0;
padding-top: 100%; // padding-top值百分比默认按宽度计算,用padding-bottom也行
img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 6、html
# (1)禁用输入框自动填充
1、密码输入框input添加属性 autocomplete="new-password"(chrome)
2、密码输入框input移除name属性(chrome)
3、在输入框的上面添加<input type="password" style="display: none;"/>(firefox)
4、密码输入框input初始type设为text,获取到焦点后将type改为password
2
3
4
# (2)input纯数字
<input type="text"
v-model="phoneNumber"
placeholder="请输入手机号"
maxlength="11"
oninput = "this.value=this.value.replace(/[^\d]/g, '')"
>
2
3
4
5
6
# (3)meta标签
// 禁止iphone和edge浏览器中部分格式数字显示为链接 edge会自动识别一定格式的数字作为电话号码
<meta name="format-detection" content="telephone=no, address=no, email=no">
// 移动端自适应屏幕,禁止用户缩放
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0">
2
3
4
# (4)excel上传accept的MIMI类型
accept='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
# 7、小程序
setData的作用是修改数据时通知dom更新,非视图更新的操作可以不用setData。
# (1)报错信息
Setting data field "$root.0,0.isShowLogistics" to undefined is invalid.
1、isShowLogistics不能为undefined值,无效,例如和v-if配合
2、isShowLogistics通过父传子传递的类型
3、貌似computed计算属性返回值都不能为undefined
Template 'xxxxxx' not found
分包组件不能引入,要复制一份重新引入,可能还需要调整下import语句的位置
2
3
4
5
6
7
# (2)禁止页面滚动
给元素添加 catchtouchmove="true"
阻止该元素上的滑动事件
2
# (3)滚动页面渲染卡顿
小程序会在页面滚动时阻塞所有异步操作,包括渲染页面、定时器等。
解决方法:
方法1、阻止页面滚动。。。
方法2、页面.json配置,增加 config: { usingComponents: {} }
# (4)更新机制
热启动:使用本地代码包。
冷启动:后台运行超过五分钟后。
第一次冷启动,继续使用本地包,同时异步检查更新,下载最新包;第二次冷启动时才会使用最新包。
解决方法:在app的onLaunch里执行以下方法,可在第一次冷启动时提示更新。
checkUpdate() {
if (!wx.getUpdateManager()) return
const updateManager = wx.getUpdateManager()
updateManager.onUpdateReady(() => {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启小程序?',
success(res) {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (5)分享
1、小程序分享时是什么版本,打开分享出去的卡片进入的就是什么版本,无法控制,例如开发版分享打开的也是开发版。
2、小程序只能分享小程序卡片,无法分享网页,如有需求,可以用webview替代,写一个专门的页面用于加载webview网页,分享时指定路径,携带网页的url参数,打开后接收url传入webview展示。
# (6)进入小程序
分享的卡片、扫小程序码:
触发:app onShow --- page onLoad --- page onShow
服务通知-模板消息:
触发:app onLoad --- app onShow --- page onLoad --- page onShow
# (7)canvas
保存canvas模糊问题:多绘制个三倍的canvas,通过ctx.scale(3, 3)放大三倍即可,scale要放在绘制之前,仅用于保存,通过定位到屏幕外来隐藏 (display: none无法保存)。
canvas网络图片真机不显示:先通过wx.downloadFile下载到本地,再用本地路径绘制。
# (8)ios下textarea滑动穿透
ios下textarea在固定定位下滑动时背景及内容会跟随者滚动
解决方法:textarea设置fixed="true"
# (9)小程序码scene
生成小程序码时可以携带path页面路径和scene参数,
而scene长度被限制最长32位字节长度,
# (10)上滑加载更多不触发
检查page和页面是否设置了height: 100%; overflow: auto;
解决方法:page可以设置height:100%; 页面设置min-height: 100%;
# (11)自定义tabbar
官方自定义tabbar有bug,例如真机显示两层tabbar,首次切换tabbar会闪烁一下。
# (12)清空剪贴板无效
安卓下通过wx.setClipboardData无法设为空字符串
解决方法:可以设成空格代替。
# (13)image图片先拉伸后正常
image标签使用mode="widthFix",是宽度固定,高度自适应,但第一次加载时会有先拉伸又迅速恢复正常的问题。
解决方法:给image设置height: auto;
# (14)开发者工具正常,真机报找不到组件
开发者工具一切正常,真机下报错,找不到组件,
切换使用新的编译模块时还出现预览失败,报文件已存在,
h5页面未更新到最新效果。
解决方法:关闭开发者工具,删除 C:\Users\EDZ\AppData\Local\微信开发者工具 目录下的文件
# (15)小程序swiper边框圆角设置无效
swiper组件设置border-radius在个别ios机型无效。
解决方法:加 transform: translateY(0); 属性。
- 给swiper组件本身设置样式:border-radius: 16rpx; overflow: hidden; transform: translateY(0);
# 8、兼容性
# (1)IOS滑动卡慢
// 滑动元素父容器
overflow: auto;
-webkit-overflow-scrolling: touch; // 慎用,会有很多坑,例如fixed层级失效,绝对定位元素被父元素padding覆盖等
已知iphoneX 12.3下有滑动卡慢的问题,猜测可能和ios版本有关,ios13及以上系统暂未发现
2
3
4
5
# (2)多行文本溢出隐藏时显示不全
在添加溢出隐藏样式的盒子外再套一层父盒子,给父盒子设置固定高度,撑起来
# (3)Android端文字未垂直居中
1、通过line-height等于height设置时有时会出现未垂直居中, 换用flex布局的align-items: center
2、小于12px大小的字体会偏上 通过transform: scale() 和 transform-origin控制字体缩放
# (4)ios的select不能选择第一项
使用v-model绑定select且初始化没有匹配项时,ios无法选择第一项,无法触发change事件。
// 解决方法:添加第一项,并设置该项disabled及display:none
<div id="example-5">
<select v-model="selected">
<option disabled value="" style="display: none;">请选择</option>
<option>A</option>
</select>
</div>
2
3
4
5
6
7
# (5)输入法弹窗导致窗口变小
输入法弹窗显示时,会导致window窗口高度变小。
场景:页面a,输入法弹窗显示时,跳到页面b,会导致页面b通过window.innerHeight等获取的高度有问题。
解决方法:
方法1:跳转页面之前,先用document.activeElement.blur()隐藏虚拟键盘,然后延时300毫秒再跳转。
方法2:跳转前先通过window.innerHeight获取输入法未弹起时的内容窗口高度,再通过地址拼接传递该高度。
# (6)ios的数字被识别为电话号码,有默认样式
把内容通过::before伪元素来设置
# (7)华为荣耀7x页面两边留白
页面两边有空白,宽度没有占满,rem单位,rem实际比例与预期不符。
解决方法:
通过userAgent针对该机型,通过html实际宽度与屏幕宽度的比值,让html根字体大小除以该比例。
# (8)ios页面底部margin-bottom失效
设置一个空的div撑起margin-bottom设置的高度
# (9)absolute定位元素被输入法顶起
当absolute元素的父元素设置height等于屏幕高度时,输入法弹起,屏幕高度缩小,导致定位元素顶起,遮盖了其他元素。
解决方法:
input获取焦点时,让定位元素隐藏,或改成静态定位,失去焦点时恢复
# (10)ios后台运行倒计时暂停
ios应用后台运行时,js的定时器会暂停,导致恢复前台时,倒计时时间与预期不符。
解决方法:
不用num - - 来计时,改用时间戳判断剩余时间
# (11)安卓9.0不显示图片
Android9.0不支持Http图片加载,只支持Https
解决方法:
方案一:h5换用https的图片地址
方案二:安卓客户端配置 android:usesCleartextTraffic="true"
# (12)ie设置flex纵向布局撑不开
ie下设置display: flex; flex-direction: column;时,如果子元素用flex: 1;无法撑开内容且会覆盖顶部。
原因:flex: 1;在ie下会解析成flex: 1 1 0; 而其他浏览器会解析成flex: 1 1 auto;
解决:改用flex: 1 1 auto;
# (13)ios不支持webp格式图片
将webp格式转换为png等格式后再使用
# (14)audio标签autoplay仍无法自动播放声音
由于浏览器的安全限制、防噪音等,音频无法自动播放
解决方法:
只能通过人为交互来触发,比如点击或滑动事件,获取audio标签对象,调用play()方法开始播放。
# (15)滚动到顶部不生效
scrollTo方法在个别机型存在兼容性问题
解决:改用ele.scrollTop = 0 的方式,让滚动父容器滚动到指定位置
# (16)ios图片懒加载滑动后空白
解决:滚动父容器添加 -webkit-overflow-scrolling : touch;
# (17)ios固定定位fixed层级不对
ios里定位的层级取决于父元素的层级,不管是absolute还是fixed,而安卓里fixed层级是独立计算
解决:给父元素也加定位并设置较大的z-index
# (18)ios下父元素设置overflow:hidden子元素仍超出
ios,父元素设置了border-radius和overflow:hidden,子元素绝对定位,仍会超出。
解决方法:父元素设置transform: rotate(0deg);
# (19)ios盒子下边框不显示
ios个别机型,下边框被遮挡或未显示。
解决方法:给盒子父元素添加高度撑起来。
# 9、vconsole
https://github.com/Tencent/vConsole/blob/dev/README_CN.md
# (1)普通引入:
<script src="../libs/vconsole/vconsole.min.js"></script>
<script>
new VConsole()
</script>
2
3
4
# (2)vue全局引入:
// npm安装
npm i vconsole
2
// main.js
import VConsole from 'vconsole'
/* eslint-disable no-new */
new VConsole()
2
3
4
# 10、Content-Type
axios使用params接收数据时,默认为url传参方式,会自动将params对象序列化,一般用于get请求方式;
axios使用data接收数据时,默认通过请求主体传参,一般用于post请求,默认content-type为json形式,会自动将params对象转为json字符串。
一般get请求用url传参,不设content-type;
# (1)表单形式
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
Content-Type为表单形式,数据需进行序列化,后端通过键值对接收。
序列化示例:{ id: 1, name: Neo } => id=1&name=Neo
Chrome调试显示 Form Data
2
3
4
5
6
# (2)json形式
headers['Content-Type'] = 'application/json; charset=utf-8'
Content-Type为json形式,数据需转为json字符串,后端通过json字符串接收
Chrome调试显示 Request Payload
2
3
4
5
# (3)form-data形式
headers['Content-Type'] = 'multipart/form-data'
Content-Type为form-data形式,数据通过new FormData()转化,文件部分以二进制数据传输,其他部分以键值对传输。
例如:
const files = document.querySelector('#file')
formData = new FormData()
formData.append('files', files[0])
uploadFile(formData).then().catch()
jquery需添加 processData: false, contentType: false 配置
2
3
4
5
6
7
8
9
10
11
# 11、性能
# (1)DOM性能
1、数据量较大时,单个canvas > 多个div > 多个table,chrome > ie
2、通过setTimeout()提升性能。
# 12、vue
# (1)DOM或子组件的重新渲染
通过绑定key,动态改变key的值就会重新渲染
# (2)vue-element-admin项目标签页无法缓存
缓存配置在/src/layout/components/AppMain.vue里。
要缓存需满足两个条件:
1、要缓存的路由组件要导出一个命名空间属性name,值和路由定义的name保持一致;
2、仅能缓存到二级路由,即router-view里嵌套的router-view里的组件无法通过这种方式缓存;
给第二层的router-view加name可以实现二级路由下的所有路由页面全缓存,但无法自己控制单个缓存,和标签条的关闭单个标签功能冲突。
# 13、nginx
- = 表示精确匹配
- ~为区分大小写的匹配
- ~*不区分大小写的匹配
- !~和!~*意为“不匹配的”
- ^~ 标识符后面跟一个字符串,Nginx将在这个字符串匹配后停止进行正则表达式的匹配
# (1)重定向
location / {
root html;
rewrite ^/$ /h5/common/ redirect;
}
location /h5 {
root html;
rewrite ^/h5 /h5/common/ redirect;
}
2
3
4
5
6
7
8
9
# (2)去除html文件缓存
location ~* /h5/(\w+)/ {
if ( $request_uri ~* /h5/(\w+)/$) {
add_header Cache-Control "no-cache, no-store";
}
}
2
3
4
5
# (3)请求代理
location ^~ /proxy {
proxy_pass http://test.51k1k.com/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2
3
4
5
6
# (4)路由history模式
location ~* /(\w+)/ {
root html;
index /$1/index.html;
try_files $uri $uri/ /$1/index.html;
}
2
3
4
5
# 三、bug记录
# 1、min.js被重复打包
现象:找不到mescroll对象
原因:min.js是已经打了包的,最好不要重复打包
解决:把mescroll.min.js放到不会被打包的目录下,例如public文件夹
2
3
# 2、请求数据过大时报414
原因:get请求方式是数据都放在了地址栏传输,地址栏传参有大小限制
# 3、vue地址栏参数类型
vue地址栏参数值为数字时,传输跳转时是number类型,通过this.$route.query获取到的也是number;
但刷新网页后,再获取到的就是string类型了
# 4、vant的imagePreview组件图片不显示
imagePreview组件如果传入的相对路径字符串就无法显示图片。
因为相对路径字符串在webpack打包后路径就变了。
需要改成使用import引入的路径或者上传到图片服务器用网络路径。
# 5、lint-staged失效
可能是自己重新git init .了,然后npm_modules没删除过,npm i都是取得缓存。
具体原因是.git里hooks文件夹里缺少相应的文件,git init的只有一部分,安装lint-staged包后会增加一些必要的文件。
解决方法:删除node_modules,重新npm i
# 6、node-sass下载失败
npm i 时无法下载node-sass,找到命令行记录里的node-sass下载路径用浏览器打开试试,如果打不开,可能是包版本不存在,需要手动更改package.json里node-sass的版本,例如“^4.12.0”
具体版本参考:https://github.com/sass/node-sass (opens new window) 和 https://www.npmjs.com/package/node-sass (opens new window)
# 7、vant轮播组件在iphoneX下逐渐错位
给van-swiper组件添加height(纵向)或width(横向)属性,
注意在rem适配方案下的属性值和屏幕比例的转换。
# 8、axios的config不允许传递非官方配置字段
v0.19.0开始的。
解决方法:再包装一层函数,以接受额外参数。