If you ever find yourself in need of a component that can download any file from any URL, don't worry! You can easily create a custom component to achieve this using the fetch API:
<template>
<button @mousedown="downloadFile">Download File</button>
</template>
<script>
export default {
props: ["file", "name"],
methods: {
downloadFile() {
const me = this;
fetch(me.file)
.then((resp) => resp.blob())
.then((blob) => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
// specify the filename
a.download = me.name || "file.json";
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
alert("Your file has been downloaded successfully!");
})
.catch(() => alert("Oops! Something went wrong."));
},
},
};
</script>
To use this component in another component, simply include it like this:
<template>
<download-button :file="file" name="myFilename.json" />
</template>
<script>
import DownloadButton from "./DownloadButton";
export default {
name: "SomeComponent",
components: {
DownloadButton,
},
data() {
return {
file: "https://jsonplaceholder.typicode.com/todos/1",
};
},
props: {
msg: String,
},
};
</script>
Remember to update the URL and filename as needed.
UPDATE: For downloading a specific section of your DOM as a PDF, you can utilize html2pdf.js:
<template>
<button @mousedown="downloadFile">Download File</button>
</template>
<script>
import html2pdf from "html2pdf.js";
export default {
props: ["dom", "name"],
methods: {
downloadFile() {
const me = this;
const element = document.querySelector(me.dom);
var options = {
margin: 1,
filename: me.name,
};
html2pdf().from(element).set(options).save();
},
},
};
</script>
You can then implement this component in your existing template structure:
(...)
Explore how it works by following this link: https://codesandbox.io/s/wonderful-meadow-m5k67?file=/src/components/DownloadButton.vue:0-429