preface
I was building a personal blog site, and I needed a Markdown editor for my blog, and I looked at some of the tutorials online, and I decided to use Simplemde and I thought it would be pretty straightforward to use, but when I put it into practice, I found that there were some things that I needed to improve on, like uploading pictures that were a pain in the ass
The final result
- Markdown grammar
- Real-time preview
- Upload the image to the server
- Finally generate HTML
Installation and initialization
npm install simplemde --save
Add a textarea to HTML
Add simplemde instantiation in Vue’s life-cycle function Mounted
var simplemde = new SimpleMDE({
el: document.getElementById(simplemde)
})
Copy the code
El specifies the Textarea element created for us through the DOM and, if omitted, automatically grabs the first Textarea in the HTML structure
Bind events so that our content data is always in sync with the typed data simplemde gets
simplemde.codemirror.on("change", () => {
this.content = simplemde.value()
})
Copy the code
To upload pictures
In the original Simplemde, clicking the picture button would look something like this
No way, since there is no have to make their own
First we create a hidden input
<input style="display:none" accept="image/gif,image/jpeg,image/jpg,image/png" type="file" id="upInput" ref="upInput">
Copy the code
I’m going to accept a file as an image and I’m going to click on it and it’s going to pop up and I’m going to hide that local upload file because we don’t want that button and we’re going to click on simplemde’s Image button to upload it which isn’t very useful, but it’s nice
So we’re just going to hide this input, just use its click method so that clicking on the image button is the same thing as clicking on this input in simplemde’s source code, go to the function that the image button calls and comment out the original one and add this
So once we’ve selected the image, in order to preview it in real time we want to send it to the back end and store it in the front end using Axios plus FormData
var input = this.$refs.upInput
var formData = new FormData()
formData.append("i", input.files[0])
var config = {
headers: {
"Content-Type": "multipart/form-data"
}
}
this.$axios.post("/data/myupload", formData, config)
Copy the code
On the back end, I’m using node, which uses the Multer module to receive data in mulipart/form-data format
Var storage = multer.diskStorage({// storage path destination: function (req, file, cb) { cb(null, '.. /static/upload/')}, // store filename filename: Function (req, file, cb) {cb(null, '${date.now ()}-${file.originalname}')}}) Router. post('/data/myupload', upload.single(' I '), function (req, res, Next) {// Send the saved filename back to the front-end res.send(req.file.filename)});Copy the code
So when the front end receives the file name, it wraps it up with the storage path and writes it into a text box which is the string of characters that you see when you click on the image button before and then previews it
this.$axios.post("/data/myupload", formData, config).then((res)=> { var urlname=`! [](/static/upload/${res.data})` simplemde.value(`${this.content}\n${urlname}\n`) })Copy the code
It looks like everything’s all right but there’s one thing missing
The input click() itself is not asynchronous, but it takes time for you to select the image, and all subsequent code (even asynchronous code) executes during this process, meaning that all of the sending stores that are being written are executed before the image is selected
In order to execute after selecting the image, we add a new listener event, listen for the input change, and throw all the previous code into it
var input = this.$refs.upInput input.addEventListener("change", () => { var formData = new FormData() formData.append("i", input.files[0]) var config = { headers: { "Content-Type": "multipart/form-data" } } this.$axios.post("/data/myupload", formData, config).then((res)=> { var urlname=`! [](/static/upload/${res.data})` simplemde.value(`${this.content}\n${urlname}\n`) }) })Copy the code
This will achieve our image upload effect
According to
So for example, with the editor, we write a blog post, we store it in the background and we want to pull it up in some other component which is a string to HTML
Simply call Simplemde’s prototype chain method
this.contentMarkdown = SimpleMDE.prototype.markdown(content)
Copy the code
Then put the data into V-HTML
<div v-html="contentMarkdown"></div>
Copy the code
You can show
Let’s see the final result again
PS
This article is to save the image in the server’s project directory, in fact, you can upload the image to the map bed and some additional functions, such as drag and drop images directly, or paste. When I have time to work on it later on