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.
208 lines
4.3 KiB
208 lines
4.3 KiB
<template> |
|
<BlogHeader /> |
|
<div id="article-create"> |
|
<h3>发表文章</h3> |
|
<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"> |
|
<span>正文:</span> |
|
<textarea |
|
v-model="body" |
|
placeholder="输入正文" |
|
rows="20" |
|
cols="80" |
|
></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 { ref } from "vue"; |
|
export default { |
|
name: "ArticleCreate", |
|
components: { BlogHeader, BlogFooter }, |
|
data: function () { |
|
return { |
|
// 文章标题 |
|
title: "", |
|
// 文章正文 |
|
body: "", |
|
// 数据库中所有的分类 |
|
// categories: [], |
|
// 选定的分类 |
|
selectedCategory: null, |
|
// 标签 |
|
tags: "", |
|
}; |
|
}, |
|
setup() { |
|
let categories = ref([]); |
|
|
|
onMounted(() => { |
|
// 页面初始化时获取所有分类 |
|
$.ajax({ |
|
url: "http://127.0.0.1:6789/api/category", |
|
type: "GET", |
|
success(resp) { |
|
categories.value = resp; |
|
}, |
|
}); |
|
}); |
|
return { |
|
categories, |
|
}; |
|
}, |
|
methods: { |
|
// 根据分类是否被选中,按钮的颜色发生变化 |
|
// 这里可以看出 css 也是可以被 vue 绑定的,很方便 |
|
categoryStyle(category) { |
|
if ( |
|
this.selectedCategory !== null && |
|
category.id === this.selectedCategory.id |
|
) { |
|
return { |
|
backgroundColor: "black", |
|
}; |
|
} |
|
return { |
|
backgroundColor: "lightgrey", |
|
color: "black", |
|
}; |
|
}, |
|
// 选取分类的方法 |
|
chooseCategory(category) { |
|
// 如果点击已选取的分类,则将 selectedCategory 置空 |
|
if ( |
|
this.selectedCategory !== null && |
|
this.selectedCategory.id === category.id |
|
) { |
|
this.selectedCategory = null; |
|
} |
|
// 如果没选中当前分类,则选中它 |
|
else { |
|
this.selectedCategory = category; |
|
} |
|
}, |
|
// 点击提交按钮 |
|
submit() { |
|
const that = this; |
|
// 前面封装的验证函数又用上了 |
|
authorization().then(function (response) { |
|
if (response[0]) { |
|
// 需要传给后端的数据字典 |
|
let data = { |
|
title: that.title, |
|
body: that.body, |
|
}; |
|
// 添加分类 |
|
if (that.selectedCategory) { |
|
data.category_id = that.selectedCategory.id; |
|
} |
|
// 标签预处理 |
|
data.tags = that.tags |
|
// 用逗号分隔标签 |
|
.split(/[,,]/) |
|
// 剔除标签首尾空格 |
|
.map((x) => x.trim()) |
|
// 剔除长度为零的无效标签 |
|
.filter((x) => x.charAt(0) !== ""); |
|
|
|
// 将发表文章请求发送至接口 |
|
// 成功后前往详情页面 |
|
const token = localStorage.getItem("access_blog"); |
|
$.ajax({ |
|
url: "http://127.0.0.1:6789/api/article/", |
|
type: "POST", |
|
data: data, |
|
headers: { |
|
Authorization: "Bearer " + token, |
|
}, |
|
success(resp) { |
|
that.$router.push({ |
|
name: "detail", |
|
params: { id: resp.id }, |
|
}); |
|
}, |
|
}); |
|
} else { |
|
window.alert("令牌过期,请重新登录。"); |
|
} |
|
}); |
|
}, |
|
}, |
|
}; |
|
</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; |
|
} |
|
.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: 60px; |
|
} |
|
</style>
|
|
|