Vue中使用render渲染函数遇到的一个循环渲染的问题

渲染函数

最基础的渲染函数用法
new Vue({
	el: '#app',
	render(h){
		return h('div', 'hello world!');
	}
});

new Vue({
    el: '#app',
    render(h){
        return h({template: '<div>hello world!</div>'});
    }
});

Vue官方文档介绍中,createElement方法(h)的第一个参数可选值为:html标签、Object组件对象或者一个resolve了任何以上两种对象的Function。

下面用同步的写法,同步resolve
///这种属于同步渲染,跟以上两种方法区别不大
new Vue({
    el: '#app',
    render(h){
        return h(function(resolve){
			resolve({template: '<div>hello world!</div>'})
		});
    }
});

页面可以正常渲染。

下面再用一种异步的写法,需要异步的resolve
new Vue({
    el: '#app',
    render(h){
        return h(function(resolve){
            setTimeout(function (){
                resolve({template: '<div>hello world!</div>'})
            }, 1000)
        });
    }
});

发现页面无法渲染,并且会循环调用render方法,立马想到的是循环渲染了,但是尤大大讲了啊,可以是一个resolve了上面两种类型数据的函数。
最后不得不去看createElement的源码,发现使用渲染函数的时候,会调用resolveAsyncComponent方法,这个方法中对第一个参数Function进行了很对的状态控制,loading,resolved等。
问题找到了,每次render的时候,上面的h方法接收的参数,永远是一个新的“Function”,无法保留住resolveAsyncComponent方法中设置的各种状态控制。

解决方法

把异步函数独立出来
const app = function(resolve){
    setTimeout(function (){
        resolve({template: '<div>hello world!</div>'})
    }, 1000)
};
new Vue({
    el: '#app',
    render(h){
        return h(app);
    }
});

这样下来,页面就会在1秒后,把数据顺利渲染到页面了。
首次调用render的时候,app会设置resolved属性,第二次渲染的时候,直接取resolved的值,不会再去调用异步方法重新resolve。
当然上面的setTimeout只是模拟了一个异步的过程,实际项目中可能是一个异步的http请求等。

多讲一点

异步函数可以返回一个Promise,而不用去调用resolve。源码中Vue对Promise作了单独处理,会设置Function的loading值为true,进行不同的逻辑处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Anlige

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值