Table of contents
Create article publishing and editing pages
Implement the article publishing and editing interface
Implement the file upload interface
Article publishing and editing functions are very important parts when building a personal blogging system. This feature not only allows us to add new articles, but also allows us to modify existing articles. In this blog, we will use Vue 3 as the front-end framework, Go as the back-end language, and MySQL as the database to achieve this function.
front end
Create article publishing and editing pages
First, we need to create a new component under src/components
the directory ArticleEditor.vue
for publishing and editing articles.
<template>
<div>
<input type="text" v-model="article.title" placeholder="Title" />
<textarea v-model="article.content" placeholder="Content"></textarea>
<button @click="submit">Submit</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
article: {
title: '',
content: '',
},
};
},
methods: {
async submit() {
const res = await axios.post('http://localhost:8080/articles', this.article);
this.$router.push(`/article/${res.data.id}`);
},
},
};
</script>
In this component, we first define an article
object , which is used to bind the value of the input box and the text area. Then we define a submit
method that will be called when the "Submit" button is clicked. In this method, we use axios to send a POST request to the backend to submit the article data, and then jump to the details page of the new article.
Implement rich text editing
For rich text editing, we can use a rich text editor library quill
called . First, we need to install this library in our project:
npm install quill
Then, we can ArticleEditor.vue
use this library in our components:
<template>
<div>
<input type="text" v-model="article.title" placeholder="Title" />
<div id="editor"></div>
<button @click="submit">Submit</button>
</div>
</template>
<script>
import axios from 'axios';
import Quill from 'quill';
export default {
data() {
return {
article: {
title: '',
content: '',
},
editor: null,
};
},
mounted() {
this.editor = new Quill('#editor');
},
methods: {
async submit() {
this.article.content = this.editor.getContents();
const res = await axios.post('http://localhost:8080/articles', this.article);
this.$router.push(`/article/${res.data.id}`);
},
},
};
</script>
In this component, we mounted
first initialize quill
the editor in the hook function. Then in submit
the method , we get the content from the editor and assign it to article.content
.
Implement file upload
For file uploads, we can use HTML's input
element and the axios library. First, we need ArticleEditor.vue
to add a input
element to the component's template:
<script>
// other code
export default {
// other code
methods: {
// other methods
async upload(e) {
const file = e.target.files[0];
const formData = new FormData();
formData.append('file', file);
const res = await axios.post('http://localhost:8080/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
this.article.image = res.data.url;
},
},
};
</script>
In this method, we first get the selected file from the event object, then create a FormData
object and add the file to it. Then we use axios to send a POST request to the backend to upload the file. Finally, we assign the URL of the uploaded file to article.image
.
backend part
Implement the article publishing and editing interface
On the backend, we need to implement the interface for publishing and editing articles in main.go
the file . First, we need to add two new routes to main
the function :
func main() {
// other code
r.POST("/articles", createArticle)
r.PUT("/articles/:id", updateArticle)
// other code
}
Then, we need to implement createArticle
and updateArticle
function:
func createArticle(c *gin.Context) {
// parse and validate the request body
var article Article
if err := c.ShouldBindJSON(&article); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// insert the article into the database
res, err := db.Exec("INSERT INTO articles (title, content) VALUES (?, ?)", article.Title, article.Content)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// return the article ID
id, err := res.LastInsertId()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"id": id})
}
func updateArticle(c *gin.Context) {
// get the article ID from the URL
id := c.Param("id")
// parse and validate the request body
var article Article
if err := c.ShouldBindJSON(&article); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// update the article in the database
_, err := db.Exec("UPDATE articles SET title = ?, content = ? WHERE id = ?", article.Title, article.Content, id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// return the article ID
c.JSON(http.StatusOK, gin.H{"id": id})
}
In these two functions, we first parse and validate the article data from the request body, then insert the article data into the database ( createArticle
function) or update the article data in the database ( updateArticle
function). Finally, we return the ID of the newly created or updated article.
Implement the file upload interface
To implement file uploads, we need to add a new route to main
the function :
func main() {
// other code
r.POST("/upload", upload)
// other code
}
Then, we need to implement upload
the function:
func upload(c *gin.Context) {
// get the file from the request
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// save the file
path := fmt.Sprintf("./uploads/%s", file.Filename)
if err := c.SaveUploadedFile(file, path); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// return the file URL
c.JSON(http.StatusOK, gin.H{"url": fmt.Sprintf("http://localhost:8080/uploads/%s", file.Filename)})
}
In this function, we first get the file from the request, and then save the file to ./uploads
the directory . Finally, we return the URL of the file.
That's all for posting and editing articles using Vue 3, Go, and MySQL. If you have any questions, please leave a message in the comment area.