seatonwan9
2025-08-14 a0fc5b1e703769a8936fd8671ec9cdd9adfda20a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!--
 * @Description: 
 * @Version: 2.0
 * @Autor: wuyun
 * @Date: 2022-09-02 16:15:27
 * @LastEditors: wuyun
 * @LastEditTime: 2022-09-02 16:54:24
-->
<template>
    <div id="container">
        <!-- 上一页、下一页 -->
        <div class="right-btn">
            <!-- 输入页码 -->
            <div class="pageNum">
                <input v-model.number="currentPage" type="number" class="inputNumber" @input="inputEvent()" />
                / {{ pageCount }}
            </div>
            <div @click="changePdfPage('first')" class="turn">首页</div>
            <!-- 在按钮不符合条件时禁用 -->
            <div @click="changePdfPage('pre')" class="turn-btn" :style="currentPage === 1 ? 'cursor: not-allowed;' : ''">上一页</div>
            <div @click="changePdfPage('next')" class="turn-btn" :style="currentPage === pageCount ? 'cursor: not-allowed;' : ''">下一页</div>
            <div @click="changePdfPage('last')" class="turn">尾页</div>
        </div>
 
        <div class="pdfArea">
            <!-- // 不要改动这里的方法和属性,下次用到复制就直接可以用 -->
            <pdf
                :src="src"
                ref="pdf"
                v-show="loadedRatio === 1"
                :page="currentPage"
                @num-pages="pageCount = $event"
                @progress="loadedRatio = $event"
                @page-loaded="currentPage = $event"
                @loaded="loadPdfHandler"
                @link-clicked="currentPage = $event"
                style="display: inline-block; width: 100%"
                id="pdfID"
            ></pdf>
        </div>
        <!-- 加载未完成时,展示进度条组件并计算进度 -->
        <div class="progress" v-if="loadedRatio != 1">
            <el-progress
                type="circle"
                :width="70"
                color="#53a7ff"
                :percentage="Math.floor(loadedRatio * 100) ? Math.floor(loadedRatio * 100) : 0"
            ></el-progress>
            <br />
            <!-- 加载提示语 -->
            <span>{{ remindShow }}</span>
        </div>
    </div>
</template>
<script lang="ts" setup>
import pdf from 'vue-pdf'
interface RemindText {
    loading: string
    refresh: string
}
interface State {
    remindText: RemindText
    remindShow: string
    intervalID: string
    // ----- vuepdf -----
    // src静态路径: /static/xxx.pdf
    // src服务器路径: 'http://.../xxx.pdf'
    src: string
    // 当前页数
    currentPage: number
    // 总页数
    pageCount: number
    // 加载进度
    loadedRatio: number
}
const state = reactive<State>({
    remindText: {
        loading: '加载文件中,文件较大请耐心等待...',
        refresh: '若卡住不动,可刷新页面重新加载...'
    },
    remindShow: '加载文件中,文件较大请耐心等待...',
    intervalID: '',
    src: '',
    // 当前页数
    currentPage: 0,
    // 总页数
    pageCount: 0,
    // 加载进度
    loadedRatio: 0
})
const { remindText, remindShow, intervalID, src, currentPage, pageCount, loadedRatio } = toRefs(state)
// 页面回到顶部
const toTop = () => {
    const dom: any = document.getElementById('container')
    dom.scrollTop = 0
}
// 输入页码时校验
const inputEvent = () => {
    if (state.currentPage > state.pageCount) {
        // 1. 大于max
        state.currentPage = state.pageCount
    } else if (state.currentPage < 1) {
        // 2. 小于min
        state.currentPage = 1
    }
}
// 切换页数
const changePdfPage = (val: string) => {
    if (val === 'pre' && state.currentPage > 1) {
        // 切换后页面回到顶部
        state.currentPage--
        toTop()
    } else if (val === 'next' && state.currentPage < state.pageCount) {
        state.currentPage++
        toTop()
    } else if (val === 'first') {
        state.currentPage = 1
        toTop()
    } else if (val === 'last' && state.currentPage < state.pageCount) {
        state.currentPage = state.pageCount
        toTop()
    }
}
 
// pdf加载时
const loadPdfHandler = () => {
    // 加载的时候先加载第一页
    state.currentPage = 1
}
onMounted(() => {
    loadPdfHandler()
})
</script>