当前位置: 首页 > Web前端 > JavaScript

关于父子组件传值和$nextTick触发的宏任务和微任务的思考

时间:2023-03-26 22:09:47 JavaScript

一切要从最近接手一段祖传代码说起。..原因及解决作为一个前端老司机(自称),不知道是招我的小哥看中了我的项目经验还是老大无意(所有老项目最后都做了优化)年),总而言之,我接手了我创建了一个旧的n-hand(n>3)代码。虽然投稿时间是一年前,但这个ES5语法好像是15-17年的产物。让我想起了刚工作时接触到的网页。感觉(不是)。整理之后,我把问题的目标锁定在一对父子组件上。子组件中有两个函数:根据watch监听的函数,同时使用数据控制组件在父组件上的显示,我们在这边做一个localStorage.setItem和赋值子组件数据操作,传入每次打开时的当前位置城市。需要localStorage.getItem获取数据,然后发起请求与后台交互的函数。原始逻辑将通过父组件上的ref调用。为了逻辑分离,避免重复调用,(2)没有加入到(1)的逻辑中,如果是react的setState,我会选择将(2)函数传入setState的回调中,但这是vue2。在两者同时被调用的场景下,(2)肯定会先于(1)触发,因为watch的拦截。所以,我们在(2)调用localStorage.getItem并赋值子组件数据时,将$nextTick包裹在Storage的外层,localStorage.getItem可以正确获取到数据,完美~父组件调用:this.isshowseach=true;this.$refs.seachadrFuc.mapData(localStorage.getItem("currentCity"));子组件监视和方法:watch:{showOnoff:{handler(val){console.log("showOnofftrigger");//默认将当前所在的城市填入this.selectCity=this.city;localStorage.setItem("selectCity",this.selectCity);}},},},方法:{mapData(val){console.log("mapData触发器");this.$nextTick(()=>{this.getupList();});},getupList(){console.log(this.selectCity)//成功赋值给this.city}}分析:看这里用于监控的Object.observe(同proxy)是一个microtask,所以会在之后执行同步任务window.localStorage.getItem。$nextTick的原理是Promise.then、MutationObserver和setImmediate或setTimeout(fn,0)都是宏任务。所以,window.localStorage.getItem和赋值的子组件数据被宏任务$nextTick包裹后,执行完会比watch更快。感谢收看!