Vue JS中获取API数据后确保视图渲染再触发打印的方案
解决Vue获取API数据后打印页面空白的问题
核心问题是Vue更新DOM属于异步操作,你直接在this.sale = res.data后调用window.print()时,DOM还未完成渲染,导致打印内容空白。不用依赖setTimeout,可以用以下两种可靠方案解决:
方案一:使用Vue的$nextTick
$nextTick是官方提供的方法,会在Vue完成DOM更新后执行回调函数,能精准适配所有客户端,完全替代setTimeout。
修改你的代码如下:
methods: { getData() { axios.get('/api/sale/receipt/' + this.$route.params.uuid).then((res) => { this.sale = res.data if(this.sale.customer == null) { this.sale.customer = {} } $('.main-loader').hide(); // 等待DOM更新完成后执行打印 this.$nextTick(() => { window.print(); window.close(); }); }).catch((res) => { // 建议添加错误处理逻辑,比如提示用户获取数据失败 }); } },
方案二:处理复杂渲染场景(如包含图片/大量列表)
如果打印内容包含图片或需要渲染大量DOM元素,仅靠$nextTick可能不够,还需等待资源加载完成。比如监听图片的load事件:
假设模板中有图片元素:
<img :src="sale.imageUrl" ref="receiptImage" />
修改方法逻辑:
methods: { getData() { axios.get('/api/sale/receipt/' + this.$route.params.uuid).then((res) => { this.sale = res.data if(this.sale.customer == null) { this.sale.customer = {} } $('.main-loader').hide(); this.$nextTick(() => { const receiptImage = this.$refs.receiptImage; if (receiptImage) { // 图片已加载完成则直接打印 if (receiptImage.complete) { this.doPrint(); } else { // 等待图片加载完成后再打印 receiptImage.addEventListener('load', this.doPrint); } } else { // 无图片时直接打印 this.doPrint(); } }); }).catch((res) => { // 错误处理逻辑 }); }, doPrint() { window.print(); window.close(); // 移除事件监听,避免重复触发 if (this.$refs.receiptImage) { this.$refs.receiptImage.removeEventListener('load', this.doPrint); } } },
通过以上方案,能确保所有需要渲染的元素(包括外部资源)都准备就绪后再触发打印,彻底解决空白问题。
内容的提问来源于stack exchange,提问作者Mengseng Oeng
相关产品推荐
相关产品推荐

