hookehuyr

fix(DocumentPreview): 优化标签页切换时组件重复渲染问题

重构 getFileSize 函数,将 Promise 封装改为 async/await 以提高可读性
为 DocumentPreview 组件添加 v-if 条件渲染,避免标签页切换时所有预览组件同时加载
统一 H5 和小程序环境的文件大小获取逻辑,移除条件编译指令
...@@ -45,48 +45,41 @@ export function detectFileType(url) { ...@@ -45,48 +45,41 @@ export function detectFileType(url) {
45 * @returns {Promise<number>} 文件大小(字节) 45 * @returns {Promise<number>} 文件大小(字节)
46 */ 46 */
47 export async function getFileSize(url) { 47 export async function getFileSize(url) {
48 - return new Promise((resolve) => { 48 + // 检测运行环境
49 - // #ifdef H5 49 + const isWeapp = typeof wx !== 'undefined' || typeof my !== 'undefined'
50 - // H5 环境:使用 fetch HEAD 请求 50 +
51 - fetch(url, { method: 'HEAD' }) 51 + // 小程序环境:使用 Taro.request
52 - .then(response => { 52 + if (isWeapp) {
53 - const contentLength = response.headers.get('Content-Length') 53 + try {
54 - if (contentLength) { 54 + const Taro = (await import('@tarojs/taro')).default
55 - resolve(parseInt(contentLength, 10)) 55 + const res = await Taro.request({
56 - } else { 56 + url: url,
57 - // 无法获取大小,返回 0(将使用 web-view) 57 + method: 'HEAD'
58 - resolve(0)
59 - }
60 }) 58 })
61 - .catch(err => { 59 +
62 - console.error('获取文件大小失败:', err) 60 + const contentLength = res.header['Content-Length'] || res.header['content-length']
63 - // 失败时返回 0,将使用 web-view 61 + if (contentLength) {
64 - resolve(0) 62 + return parseInt(contentLength, 10)
65 - })
66 - // #endif
67 -
68 - // #ifdef WEAPP
69 - // 小程序环境:使用 Taro.request HEAD 请求
70 - Taro.request({
71 - url: url,
72 - method: 'HEAD',
73 - success: (res) => {
74 - const contentLength = res.header['Content-Length'] || res.header['content-length']
75 - if (contentLength) {
76 - resolve(parseInt(contentLength, 10))
77 - } else {
78 - // 无法获取大小,返回 0(将使用 web-view)
79 - resolve(0)
80 - }
81 - },
82 - fail: (err) => {
83 - console.error('获取文件大小失败:', err)
84 - // 失败时返回 0,将使用 web-view
85 - resolve(0)
86 } 63 }
87 - }) 64 + } catch (err) {
88 - // #endif 65 + console.error('获取文件大小失败:', err)
89 - }) 66 + }
67 + return 0
68 + }
69 +
70 + // H5 环境:使用 fetch
71 + try {
72 + const response = await fetch(url, { method: 'HEAD' })
73 + const contentLength = response.headers.get('Content-Length')
74 + if (contentLength) {
75 + return parseInt(contentLength, 10)
76 + }
77 + } catch (err) {
78 + console.error('获取文件大小失败:', err)
79 + }
80 +
81 + // 无法获取大小,返回 0(将使用 web-view)
82 + return 0
90 } 83 }
91 84
92 /** 85 /**
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
8 <nut-tabs v-model="activeTab"> 8 <nut-tabs v-model="activeTab">
9 <nut-tab-pane title="PDF 预览" pane-key="pdf"> 9 <nut-tab-pane title="PDF 预览" pane-key="pdf">
10 <DocumentPreview 10 <DocumentPreview
11 - src="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" 11 + v-if="activeTab === 'pdf'"
12 + src="https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf"
12 fileType="pdf" 13 fileType="pdf"
13 fileName="示例 PDF 文档.pdf" 14 fileName="示例 PDF 文档.pdf"
14 @rendered="handleRendered" 15 @rendered="handleRendered"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
18 19
19 <nut-tab-pane title="Word 预览" pane-key="word"> 20 <nut-tab-pane title="Word 预览" pane-key="word">
20 <DocumentPreview 21 <DocumentPreview
22 + v-if="activeTab === 'word'"
21 src="https://calibre-ebook.com/downloads/demos/demo.docx" 23 src="https://calibre-ebook.com/downloads/demos/demo.docx"
22 fileType="docx" 24 fileType="docx"
23 fileName="示例 Word 文档.docx" 25 fileName="示例 Word 文档.docx"
...@@ -28,6 +30,7 @@ ...@@ -28,6 +30,7 @@
28 30
29 <nut-tab-pane title="Excel 预览" pane-key="excel"> 31 <nut-tab-pane title="Excel 预览" pane-key="excel">
30 <DocumentPreview 32 <DocumentPreview
33 + v-if="activeTab === 'excel'"
31 src="https://filesamples.com/samples/document/xlsx/sample1.xlsx" 34 src="https://filesamples.com/samples/document/xlsx/sample1.xlsx"
32 fileType="xlsx" 35 fileType="xlsx"
33 fileName="示例 Excel 文档.xlsx" 36 fileName="示例 Excel 文档.xlsx"
...@@ -38,6 +41,7 @@ ...@@ -38,6 +41,7 @@
38 41
39 <nut-tab-pane title="PPT 预览" pane-key="ppt"> 42 <nut-tab-pane title="PPT 预览" pane-key="ppt">
40 <DocumentPreview 43 <DocumentPreview
44 + v-if="activeTab === 'ppt'"
41 src="https://filesamples.com/samples/document/ppt/sample1.ppt" 45 src="https://filesamples.com/samples/document/ppt/sample1.ppt"
42 fileType="ppt" 46 fileType="ppt"
43 fileName="示例 PPT 文档.ppt" 47 fileName="示例 PPT 文档.ppt"
......