You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

264 lines
5.6 KiB

<template>
<BlogHeader />
<div id="article-create">
<h3>发表文章</h3>
<form id="image_form">
<div class="form-elem">
<span>文章标题图片:</span>
<input
v-on:change="onFileChange"
type="file"
id="file"
style="padding-bottom: 10px"
/>
</div>
</form>
<form>
<div class="form-elem">
<span>标题</span>
<input v-model="title" type="text" placeholder="输入标题" />
</div>
<div class="form-elem">
<span>分类:</span>
<span v-for="category in categories" :key="category.id">
<!--样式也可以通过 :style 绑定-->
<button
class="category-btn"
:style="categoryStyle(category)"
@click.prevent="chooseCategory(category)"
>
{{ category.title }}
</button>
</span>
</div>
<div class="form-elem">
<span>标签:</span>
<input
v-model="tags"
type="text"
placeholder="输入标签,用逗号分隔"
/>
</div>
<div class="form-elem">
<div style="margin-bottom: 10px;">正文:</div>
<textarea
v-model="body"
placeholder="输入正文"
rows="20"
cols="100"
></textarea>
</div>
<div class="form-elem">
<button v-on:click.prevent="submit">提交</button>
</div>
</form>
</div>
<BlogFooter />
</template>
<script>
import BlogHeader from "@/components/BlogHeader.vue";
import BlogFooter from "@/components/BlogFooter.vue";
import authorization from "@/utils/authorization";
import $ from "jquery";
import { onMounted } from "@vue/runtime-core";
import { useRouter } from 'vue-router';
import { ref } from "vue";
export default {
name: "ArticleCreate",
components: { BlogHeader, BlogFooter },
setup() {
// 文章标题
let title = ref("");
// 文章正文
let body = ref("");
// 数据库中所有的分类
let categories = ref([]);
// 选定的分类
let selectedCategory = ref(null);
// 标签
let tags = ref("");
// 标题图 id
let avatarID = ref(null);
const router = useRouter();
onMounted(() => {
// 页面初始化时获取所有分类
$.ajax({
url: "http://127.0.0.1:6789/api/category",
type: "GET",
success(resp) {
categories.value = resp;
},
});
});
// 根据分类是否被选中,按钮的颜色发生变化
const categoryStyle = (category) => {
if (
selectedCategory.value !== null &&
category.id === selectedCategory.value.id
) {
return {
backgroundColor: "black",
};
}
return {
backgroundColor: "lightgrey",
color: "black",
};
};
// 选取分类
const chooseCategory = (category) => {
// 如果点击已选取的分类,则将 selectedCategory 置空
if (
selectedCategory.value !== null &&
selectedCategory.value.id === category.id
) {
selectedCategory.value = null;
} else {
selectedCategory.value = category;
}
};
const onFileChange = (e) => {
// 将二进制文件数据添加到提交数据中
const file = e.target.files[0];
let formData = new FormData();
formData.append("content", file);
$.ajax({
url: "http://127.0.0.1:6789/api/avatar/",
type: "POST",
data: formData,
processData: false,
contentType: false,
headers: {
"Authorization":
"Bearer " + localStorage.getItem("access_blog"),
},
success(resp) {
avatarID.value = resp.id;
}
});
};
// 点击提交按钮
const submit = () => {
// 前面封装的验证函数又用上了
authorization().then((response) => {
if (response[0]) {
// 需要传给后端的数据字典
let data = {
title: title.value,
body: body.value,
};
// 添加分类
if (selectedCategory.value) {
data.category_id = selectedCategory.value.id;
}
// 标签预处理
data.tags = tags.value
// 用逗号分隔标签
.split(/[,,]/)
// 剔除标签首尾空格
.map((x) => x.trim())
// 剔除长度为零的无效标签
.filter((x) => x.charAt(0) !== "");
data.avatar_id = avatarID.value;
// 将发表文章请求发送至接口
// 成功后前往详情页面
const token = localStorage.getItem("access_blog");
$.ajax({
url: "http://127.0.0.1:6789/api/article/",
type: "POST",
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json',
headers: {
Authorization: "Bearer " + token,
},
success(resp) {
router.push({
name: "detail",
params: { id: resp.id },
});
},
});
} else {
window.alert("令牌过期,请重新登录。");
}
});
}
return {
categories,
title,
body,
avatarID,
tags,
selectedCategory,
categoryStyle,
chooseCategory,
onFileChange,
submit,
}
},
};
</script>
<style scoped>
.category-btn {
margin-right: 10px;
}
#article-create {
text-align: center;
font-size: large;
}
form {
text-align: left;
padding-left: 100px;
padding-right: 10px;
padding-bottom: 100px;
}
#image_form {
text-align: left;
padding-left: 100px;
padding-right: 10px;
padding-bottom: 0px;
}
.form-elem {
padding: 10px;
}
input {
height: 25px;
padding-left: 10px;
width: 50%;
}
button {
height: 35px;
cursor: pointer;
border: none;
outline: none;
margin: 0 auto;
background-color: steelblue;
color: whitesmoke;
border-radius: 5px;
width: 50px;
}
</style>