面试

# 面试

# 淘宝镜像

// 使用淘宝镜像源
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凭据
1
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 <远程仓库地址>
1
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
1
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)]/

1
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()
1

# (2)中文输入法

// 开始非直接输入时触发
“inputElement”.addEventListener('compositionstart', function(){})

// 结束非直接输入(开始直接输入)时触发
“inputElement”.addEventListener('compositionend', function(){})
1
2
3
4
5

# (3)禁止滑动穿透

“bgScrollElement”.style.overflow = 'hidden'
1

# (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)
}
1
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);
1
2

# (2)滚动条

// 隐藏滚动条
::-webkit-scrollbar {
  display: none;
}
1
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);
}
1
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;

// 多行文本溢出显示不全问题
给该元素添加一个父盒子,父盒子设置固定高度撑起来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# (5)占据剩余高度

父盒子不定宽高,第一个子盒子也不定宽高,第二个子盒子占据剩余高度

// 父盒子
height: 100%或数值;
display: flex;
flex-direction: column;

// 要占据剩余高度的子盒子
flex: 1;
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%;
  }
}
1
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
1
2
3
4

# (2)input纯数字

<input type="text"
	v-model="phoneNumber"
    placeholder="请输入手机号"
    maxlength="11"
    oninput = "this.value=this.value.replace(/[^\d]/g, '')"
>
1
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">
1
2
3
4

# (4)excel上传accept的MIMI类型

accept='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
1

# 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语句的位置
1
2
3
4
5
6
7

# (2)禁止页面滚动

给元素添加 catchtouchmove="true"
阻止该元素上的滑动事件
1
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()
                }
            }
        })
    })
}
1
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位字节长度,

参考:https://developers.weixin.qq.com/community/develop/doc/0004c219dd0200c37c46a78355bc00 (opens new window)

# (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及以上系统暂未发现
1
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>
1
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>
1
2
3
4

# (2)vue全局引入:

// npm安装
npm i vconsole
1
2
// main.js
import VConsole from 'vconsole'
/* eslint-disable no-new */
new VConsole()
1
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
1
2
3
4
5
6

# (2)json形式

headers['Content-Type'] = 'application/json; charset=utf-8'

Content-Type为json形式,数据需转为json字符串,后端通过json字符串接收

Chrome调试显示 Request Payload
1
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 配置
1
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;
}
1
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";
    }
}
1
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;
}
1
2
3
4
5
6

# (4)路由history模式

location ~* /(\w+)/ {
    root   html;
    index  /$1/index.html;
    try_files $uri $uri/ /$1/index.html;
}
1
2
3
4
5

# 三、bug记录

# 1、min.js被重复打包

现象:找不到mescroll对象
原因:min.js是已经打了包的,最好不要重复打包
解决:把mescroll.min.js放到不会被打包的目录下,例如public文件夹
1
2
3

# 2、请求数据过大时报414

原因:get请求方式是数据都放在了地址栏传输,地址栏传参有大小限制
1

# 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开始的。

解决方法:再包装一层函数,以接受额外参数。

最后更新时间: 2022/10/23 10:24:55