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
渲染函数
最基础的渲染函数用法
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)