parent
932ed5ed5a
commit
f36f731994
10 changed files with 318 additions and 69 deletions
Binary file not shown.
@ -0,0 +1,208 @@ |
|||||||
|
<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> |
Loading…
Reference in new issue