采用store存储 dialogVisible的状态可以实现非父子组件的通信
//路径:src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import pdfDialog from './modules/pdfDialog'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
pdfDialog,
},
})
export default store
//路径:src/store/modules/pdfDialog.js
export default {
state: {
dialogVisible:false,
},
mutations: {
setDialogVisible(state,dialogVisible){
state.dialogVisible=dialogVisible
},
},
actions: {
}
}
在页面的index文件中写上两个组件
<template>
<div class="detailsDiv">
<pdf-dialog></pdf-dialog>
<pdf-dialog-show></pdf-dialog-show>
</div>
</template>
<script>
import PdfDialog from './components/pdfDialog.vue';
import PdfDialogShow from './components/pdfDialogShow.vue';
export default {
components: { PdfDialog, PdfDialogShow },
methods: {},
};
</script>
<style lang="sss" scoped>
.detailsDiv {
display: flex;
justify-content: center;
height: 100%;
width: 100%;
}
</style>
在显示组件pdfDialog中设置一个bottom,点击后使dialogVisible为true(显式地提交 (commit) mutation使dialogVisible为true)
<template>
<div class="pdfDialog">
<div class="divHeader">
{{ title }}
<div class="clickBotton">
<el-button size="mini" @click="handleReportButton()"
>查看完整文章</el-button
>
</div>
</div>
<div class="cutLine"></div>
<div class="divComponent">
<img
src="../showFiles/1.png"
alt="建筑工程地下室防水施工技术分析"
style="width: 90%; height: 90%"
/>
</div>
</div>
</template>
<script>
export default {
data() {
return {
title: "研究成果",
test: true,
};
},
methods: {
handleReportButton() {
this.$store.commit("setDialogVisible", true);
// console.log(this.$store.state.pdfDialog.dialogVisible);
},
},
};
</script>
<style lang="sss" scoped>
.pdfDialog {
width: 50%;
height: 40%;
background: rgba(1, 159, 245, 0.1);
}
.divHeader {
width: 100%;
height: 13%;
display: flex;
justify-content: space-around;
align-items: center;
position: relative;
}
.clickBotton {
position: absolute;
right: 0;
width: 30%;
height: 70%;
}
.cutLine {
position: relative;
width: 100%;
height: 4px;
background: rgba(1, 159, 245, 0.4);
}
.cutLine::after {
position: absolute;
left: 0;
content: "";
width: 8.125rem;
height: 4px;
background: rgb(1, 159, 245);
transition: all 0.5s;
}
.divComponent {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: calc(100% - 2.8125rem);
padding: 0.625rem 0.9375rem;
}
.pdfDialog:hover .cutLine::after {
width: 100%;
}
.divHeader ::v-deep .el-button {
color: #ffffff;
background: transparent;
width: 20%;
}
.divHeader ::v-deep .el-button--mini {
padding: 7px 0px;
}
.divHeader ::v-deep .el-button:hover {
background: #ff9549cc;
}
</style>
在弹出组件pdfDialogShow中设置pdf页面的“打印”“下载”“返回”等按钮
遇到的问题:
使用vue-pdf读取本地项目PDF文件报错
原因及解决方法:读取PDF文件时,路径不合法,导致读取不到文件; 在vue-cli3脚手架搭建的项目中,读取本地的PDF文件需要放在public / static下,引用时不能写相对路径,采用/ static/xxx.pdf的路径方式进行引用(/ 代表public)
<template>
<el-dialog
:visible.sync="$store.state.pdfDialog.dialogVisible"
:modal="false"
>
<div class="pdfDialogShow">
<div class="header">
{{ title }}
<el-button icon="el-icon-back" @click="handleBackClick()"
>返回</el-button
>
</div>
<div class="architecturePdf">
<pdf
ref="pdf"
v-for="i in numPages"
:key="i"
:src="pdfSrc"
:page="i"
></pdf>
</div>
<div class="pdfButton">
<el-button icon="el-icon-printer" @click="printPdf()">打印</el-button>
<el-button icon="el-icon-download" @click="downloadClick()"
>下载报告</el-button
>
</div>
</div>
</el-dialog>
</template>
<script>
import pdf from "vue-pdf";
export default {
components: {
pdf,
},
data() {
return {
url: "/static/pdf/show.pdf ",
pdfSrc: "",
title: "建筑工程地下室防水施工技术分析pdf",
numPages: undefined,
test: true,
};
},
methods: {
getNumPages() {
// 有时PDF文件地址会出现跨域的情况,最好处理一下
let loadingTask = pdf.createLoadingTask(this.url);
loadingTask.promise
.then((pdf) => {
this.pdfSrc = loadingTask;
this.numPages = pdf.numPages;
})
.catch((err) => {
console.error("pdf 加载失败");
});
},
printPdf() {
this.$refs.pdf[0].print();
},
handleBackClick(){
this.$store.commit("setDialogVisible", false);
},
downloadClick() {
var a = document.createElement("a");
a.setAttribute("href", this.url);
a.setAttribute(
"download",
"建筑工程地下室防水施工技术分析.pdf"
);
document.body.appendChild(a);
a.click();
},
},
mounted() {
this.getNumPages();
},
};
</script>
<style lang="sss" scoped>
.pdfDialogShow {
z-index: 999999;
background-color: #ececec;
height: 100%;
width: 100%;
pointer-events: all;
}
.header {
display: flex;
width: 100%;
height: 5%;
padding-left: 3%;
background-color: #fff;
align-items: center;
font-size: 1.3rem;
}
.architecturePdf {
position: absolute;
left: 15%;
width: 70%;
top: 7%;
height: 85%;
overflow-y: auto;
}
.pdfButton {
position: absolute;
left: 15%;
width: 70%;
top: 92%;
height: 5%;
background-color: #fff;
border-top: 1px solid #ececec;
display: flex;
justify-content: center;
align-items: center;
}
>>> .el-button {
width: 20%;
height: 70%;
background-color: #1e2c7c;
color: #fff;
}
.header >>> .el-button {
margin-left: 65%;
width: 8%;
background-color: #fff;
color: #000;
}
>>> .el-dialog__header {
padding: 0;
padding-bottom: 0;
}
>>> .el-dialog {
margin: 0 !important;
width: 100%;
height: 100%;
}
>>> .el-dialog__body {
padding: 0;
width: 100%;
height: 100%;
}
</style>