问题笔记
记录自己遇到的问题
# click 和 blur 事件冲突
- 问题:表单填写遇到的,填写 input 输入框和点击图标同时触发 click 和 blur 事件,但是只触发了 blur 事件,没有触发 click 事件
- 原因:事件优先级onblur > onclick,所以在onclick中做所有的限制都是没有用的。但是onmousedown事件优先级是高于onblur的
- 解决方法:把绑定onclick事件换成onmousedown,然后在onmousedown事件中使用e.preventDefault()阻止默认行为,执行完onmousedown事件后不会再去执行onblur事件。
- 注意:blur和focus事件不会冒泡,其他表单事件都可以
# 单击和双击事件冲突
- 问题:在dom上同时绑定单击事件和双击事件时,点击双击事件会触发两次单击事件
- 原因:单击事件和双击事件区别就在间隔时间,当点击一次时,设置一个延时器,延时一定时间(300ms为好)后执行,在这300ms之内,再次点击,认定执行的是双击事件,如果超过300ms再点击第二次,执行的是单击事件
- 解决方法:
单击事件代码:
handleNodeClick(data) {
var that = this
// 开启延时器,300ms的间隔区分单击和双击,解决双击时执行两次单击事件
clearTimeout(that.time)
that.time = setTimeout(() => {
// 写单击事件执行的逻辑代码
},300)
}
双击事件代码:
dbclickNode(node, data) {
clearTimeout(this.time)
// 触发dbclick事件,传入sonmsg值
this.$emit('dbclick', data)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 使用elementUI的el-tabs组件跳转卡死问题
- 问题:从页面(该页面弹框中使用el-tabs组件)跳到另一个页面(页面上使用el-tabs组件),页面居然出现了卡死的状况
- 解决方法:使用el-row el-col元素来包裹el-tabs元素,可以解决页面卡死问题
<tempalte>
<div class="log-box">
<el-row>
<el-col :span="24">
<el-tabs>
<el-tab-pane>1111</el-tab-pane>
<el-tab-pane>22222</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
<div class="main-content">
<router-view></router-view>
</div>
</div>
</template>
.log-box{
width:100%;
height:100%;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 怎么实现类似 APP 一样的缓存
- 问题:实现缓存可以用 Vue 的
keep-alive
,动态增删它的include
数组来实现前进刷新,后退不刷新;但是遇到了极端情况例如:A 可以前进到 B 页面,B 也可以前进到 A 页面,这时候会发现前进到的页面不会刷新,还是之前缓存的页面 - 原因:由于
keep-alive
一样的组件实例只能缓存一个,所以这种方法不行 - 解决方法:手动把请求的数据存起来,存到一个数组里面,每次取数据取的是数组的最后一个数据,删除也是删除数组的最后一个数据;
keep-alive
缓存所有组件,避免组件频繁创建销毁,提高性能 - 什么时候存:请求回来后就存,存到缓存数组中的最后一个
- 存的是什么数据:每个组件请求回来的数据;除此之外,还要存储组件对应的
name
名称,用来决定是否采用此缓存数据;如果还想要回到之前页面滚动的位置,还要存储页面的滚动距离 - 存在哪里:1.
Vuex
:优点是存和取都比较方便,缺点是刷新就没了;2.sessionStorage
:优点是刷新不丢失,缺点是存储空间5m
左右有限,如果项目页面是有限的还好,如果项目可以一直点击页面前进的话,比如 A 和 B 互相点击一直无限前进的话,缓存数据一直存储,sessionstorage
就不能无限存储了;还有一个缺点就是存和取的时候需要字符串和json
互转;3.localstorage:缺点和sessionstorage
类似,存储空间有上限;另外由于浏览器关闭后数据也不消失,导致可能的情况是打开其中一个页面可能显示的还是上次的缓存数据;4.indexDB:优点是存储空间无上限,其它缺点和localstorage
一样 - 什么时候取缓存数据:
created
适合请求数据;activated
适合取数据和判断是否请求新数据; - 什么时候删除数据:因为
window
的onpopstate
事件在浏览器前进时候也会触发,所以还是要通过name
的比对,比对成功就取缓存数据,否则删除数据,请求新数据
# Vue 路由滚动失效
- 问题:
keep-alive
缓存页面后,使用路由的scrollBehavior
用来后退到页面后可以滚动到之前页面滚动的位置,但是失效 不起作用 - 原因:使用了路由动画
- 解决办法:虽然不能滚动,但是
scrollBehavior
还是可以记录下之前滚动的位置,将滚动的位置信息存储到sessionStorage
,在路由钩子afterEach
中,判断sessionStorage
中是否有位置信息,有就开启一个定时器,这个定时器的时间要大于路由动画的过渡时间,而且要慢慢调试,否则会出现页面开始在最顶部,忽然跳到了之前的位置的情况。
# Better-Scroll 封装
- 问题:封装了
Better-Scroll
插件用来处理多个组件超出页面实现丝滑滚动效果,但是出现了只有第一个包裹的组件才能滑动的情况。 - 原因:
Better-Scroll
插件需要指定滚动的Dom容器,封装的组件中指定的容器虽然不是同一个div
,但是类名一样,导致在一个组件中使用多次只会对第一个有效的情况 - 解决:给封装的滚动组件传递一个参数,用来当做滚动的容器类名,且必须不一样。
# fixed 布局失效
- 问题:设置了
position: fixed
的元素固定定位失效,没有相对于浏览器视窗定位 - 原因:此元素的父元素中,某个父元素的
css
的属性中存在transform.perspective
或者filter
属性,这时候这个设置了position: fixed
的子元素就会相对于这个父元素来定位 - 解决办法:
fixed
定位的元素最好不要是子元素
# 移动端 fixed 定位的弹窗还可以滑动
- 问题:使用 fixed 定位布满全局的弹窗,显示之后,如果当前页面是可以滑动的,在弹窗之后,使用手指仍然可以滑动
- 解决办法:
passive
属性
// 为元素添加事件监听,阻止穿透
(document.getElementById('coupon_wrap') as any).addEventListener(
'touchmove',
function(e: any) {
e.preventDefault()
},
{ passive: false } // // 禁止 passive 效果
);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# justyfy-content: space-between 失效
- 问题:父元素
flex
布局,justyfy-content: space-between
失效,子元素没有两边靠边对齐 - 原因:子元素设置了
margin: 0 auto
,导致子元素水平居中 - 解决办法:删除子元素的
margin
- 提示:在
flex
布局中利用margin: auto
可以实现水平垂直居中
# 移动端 margin-bottom: 50px 失效
- 问题:页面中两个主要
div
元素,一个超出页面高度使页面可以滑动,另一个fixed
固定定位在页面底部,高50px
,为了让固定定位的元素不覆盖另一个元素,另一个元素设置了margin-bottom: 50px
,结果在ios
上失效,依然会覆盖 - 解决办法:使用
padding-bottom: 50px
或者在定义一个高50px
的元素来撑开页面
# Vue的v-show不能是数组的元素值
- 问题:v-show 使用了数组中的元素,
<ul>
<li v-show="isDisplay[0]">
0
</li>
<ul>
<button @click="change">change</button>
// vue data
data() {
return {
isDisplay: [true],
}
}
// vue methods
methods: {
change() {
return !this.isDisplay[0];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
最近更新时间: 2022/09/28 16:26:36
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00