vue3组件渲染的调度

  • 上一节完成了组件的自更新,但是一旦组件自身的响应式数据发生改变,组件就要自动重新执行渲染函数,这样做有一个缺陷。
  const VueComponent = {
            props:{ // propsOptions 用户提供的告诉vue哪些是属性,其他不是的会放到attrs中
                a:Number,
                b:{}
            },
            data(){
                return {name:'zf',a:100} // 数据源
            },
            render(){ // render函数返回虚拟节点 决定最终渲染的结果
                console.log(this.a)
                return h('button',{onClick:()=>{
                    // debugger
                   
                    this.a++
                    this.a++
                    this.a++
                  
                }}, h('span',this.a))
            }
        }
      
        render(h(VueComponent),app);
  • 当点击按钮时,数据a会改变三次,render函数也会执行三回,这样做效率很低,因为只需要等a全部改变完,执行一次渲染函数即可。
  • 这里可以利用响应系统的调度执行去改善。
    • ReactiveEffect类可以传入第一个函数为渲染函数,当数据改变去执行这个函数重新渲染页面,还可以传入一个包含调度函数的对象,如果这个函数存在,则不执行渲染函数,改为执行这个函数,这个函数的默认参数依然为渲染函数。
    • 调度函数中每当数据发生改变,调用调度函数,调度函数内部有一个set数组,存储每次传入的渲染函数job
    • 开启一个异步任务,第一次执行调度函数时,在异步任务中依次执行job,并清空数组
    • 设置一个守卫,在异步任务没执行完之前,再次开启改调度函数无效
//可以自动去重
const queue = new Set()
let isFlushing = false
const resolvePromise = Promise.resolve()
export function queueJob(job){
    queue.add(job)
    if(!isFlushing){
      isFlushing = true //阻拦后面的调用
      resolvePromise.then(()=>{
        try{
          queue.forEach(job =>job())
        }finally{
          isFlushing = false
          queue.clear()
        }
      })
    }
}
  const effect = new ReactiveEffect(componentUpdate,()=>{queueJob(instance.update)})
        let update = instance.update = effect.run.bind(effect)
        update()
  • 自此,在第一次a++时,开启调度函数,后面a++,调度函数将更新函数追加到调用栈中,set会自动去重,因此只有一个更新函数在调用栈,由于第一次的守卫阻挡,后面两次a++执行调度函数不会执行异步任务。第一次异步任务执行完,页面渲染。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问也去

创作不易,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值