12月踩坑合集

79 阅读5分钟

1、el-popover重新计算弹窗位置

image.png

因为一个场景是用户可以展开查看更多弹出信息,但这个会改变内容高度导致popover一开始展示的位置就不对了。 查了element-ui的文档没有相关方法,但是搜索可以搜出来有个方法可以使用就是this.$refs.popove.updatePopper()

el-popover弹出框更新位置刷新定位

2、js如何判断文本是否溢出(text-overflow)

这里也是开发遇到的一个需求,产品希望只在文本信息被折叠的时候才让鼠标在放上去的时候展示更多, 查了一下方案,多数是需要各种计算的,比如:判断text-overflow: ellipsis是否生效

后面发现一个比较巧妙的方法就是:对比scrollHeight 与 clientHeight text-overflow: ellipsis判断文本是否超出

3、this.$refs.xxx 取到的是数组还是一个对象?

只要是在v-for中使用ref,不管key是否唯一,他都是一个数组; 而只要不是v-for中使用,他就都是一个组件实例或dom对象,且后声明的会覆盖先声明的。 一下是vue对ref指令的实现。

image.png

4、removeEventListener真的把事件监听移除了吗?

"捕获阶段"和”冒泡阶段“的事件监听是需要分别移除的(默认是冒泡阶段),如果事件监听是在捕获阶段,而数据的移除却没有声明是移除捕获阶段的监听的话,就会移除失败。EventTarget.removeEventListener()

image.png

5、调试工具箭头函数的this值显示有问题

image.png

查阅了一下,是babel搞的鬼,在被转成es5的时候箭头函数已经被转成普通函数了,大概是下面这个样子

const handler = () => {
	this.xxx
}
document.body.addEventListener('click', handler);

// 被转换成了
var _this = this;
var handler = function() {
	_this.xxxx;
}
document.body.addEventListener('click', handler);

所以在浏览器中this值才会指向window

进入debugger调试时,this 输出 undefined的问题,箭头函数与babel造成的调试不便

6、没考虑为空的情况

这是产品也没考虑到,自己在需求分析与开发的时候也漏考虑的情况。 没有判断空,导致发送的是空内容,也没有相应的提示,导致在用户看起来,像是点击了没效果。 所以在分析需求的时候可以多考虑”为空“的情况,比如:

1、表格、列表为空,要不要加个暂无数据?不加的话用户会不会以为是出现了白屏的错误? 2、需要用户点击然后展示结果的功能,空的情况要不要加个提醒?不加的话用户会不会误以为是功能没生效?

核心思考是不加这个”空的“判断,用户能不能自行判断出来这是生效了但是是空,还是出现错误了。

7、then与always的loading问题

接口提交完 then 去重新请求数据 always去关loading会有问题

updateData() {
	this.loading = true;
	// 发起了接口请求
	Api.xxx({ ... })
		.then(() => {
			this.loadData();
		})
		.always(() => {
			this.loading = false
		})
},
loadData() {
	this.loading = true;
	// 发起了接口请求
	Api.xxx({ ... })
		.then(() => {
			// 做数据处理
		})
		.always(() => {
			this.loading = false
		})
}

这里的流程是 1、updateData发起了接口请求,然后分别用then和always添加了两个微任务 。 2、接口请求回来了,updateData的then添加的微任务被执行,然后loadData方法被执行。 3、loadData中执行this.loading = true 注意,这里因为always是后添加的微任务,此时还没被执行。 4、loadData又分别用then和always添加了两个微任务。 5、updateData的always添加的微任务被执行,loading被关闭。提前被关了!

这里我的该法是,把always给挪到then上面:

updateData() {
	this.loading = true;
	// 发起了接口请求
	Api.xxx({ ... })
		.always(() => {
			this.loading = false
		})
		.then(() => {
			this.loadData();
		})
},

但是,如果使用的是es6-promise-always,这个库扩展的always,他是会把catch状态给改掉的。 也就是说,即便接口请求失败了,如果提前使用了always,那么then里面的方法也会被执行。 那怎么办呢? 早期我是修改了这个库的实现,让他不去改变promise的状态

// 扩展promise的always
!(function(t) {
  if (!t.Promise || t.Promise.prototype.always) return;
  t.Promise.prototype.always = function(callback) {
    return this.then(
      function(res) {
        const result = callback(res);
        if (result instanceof Promise) {
          return result;
        }
        return Promise.resolve(res);
      },
      function(res) {
        // 这里主要是使用always后,不想去捕获、改变promise的reject的状态
        const result = callback(res);
        if (result instanceof Promise) {
          return result;
        }
        return Promise.reject(res);
      }
    );
  };
})(typeof window === 'undefined' ? global : window);

后面查阅是发现了promise也已经有不会修改状态的finally可以用了Promise.prototype.finally

8、单引号有提示 字符不对 但能正常执行 就是匹配不到

image.png 在浏览器控制台甚至不提示 image.png

9、window.open在ios上异步调用的话会失效

原因是window.open被广告商滥用,影响用户的使用,所以阻止异步弹出窗口的操作。 解决方法有 1、苹果系统设置,偏好设置->安全性,去掉阻止弹窗的复选框。 2、创建一个a标签,然后手动触发他的点击 3、同步使用window.open打开一个空白页面,再异步改其链接 ios safari浏览器使用window.open失效

10、访问 window.parent.document 如果跨域,会报错

像是这样

image.png

11、组件在create等钩子处理props数据时,需要考虑是否要响应props数据变更

这个我开发也时常会被忽略。

就是组件在create等钩子去处理props传入的配置, 但父组件的配置并不一定在一开始的时候就已经准备好了。

这就会出现父组件的数据异步准备好了,调试工具也看到有数据了,但是子组件就是没有的情况。

比起父组件控制子组件的挂载事件, 可以考虑看看是不是子组件监听props数据的变更,亦或者提供一个给父组件使用的更新配置方法的方式,更友好些。

写在最后

都看到这儿了,点个赞再走呗,世贤~

mmexport1650884698116.gif