Vue框架
内容管理
Vue小案例 ---- 简单的个人博客【好看的样式可以再完善,主要是思路】
前面分享了vue3的大部分的知识,所以专门出一篇小小的文章实操一下;后面博主会基于vue + springBoot开发个人网站,届时会在github上开源
关于这个vue运用的小demo很easy; 主要实现的功能
- 添加博客 【添加博客能够实时预览效果】
- 博客总览【所有的文章,对content进行裁剪】
- 博客详情【文章的详情】
- 编辑和删除博客
这里为了不浪费时间,就简单弄了一下,页面也没有运用太多的CSS样式
这里的博客就是随机访问的一个可以返回json数据的网站:happy:; 因为这毕竟只是一个小demo,不值得再编写后端; 目的主要是使用vue【没有使用bootstrap和Element的样式】
博客demo展示
这里demo样式真的一般,这里唯一提示的就是实现博客的标题为五颜六色,可以通过随机数来实现【每次刷新都可以变色】
博客总览页面
这里就是点击进入项目的时候就会显示该页面,该页面会显示所有的博客,博客标题大写,并且内容为前100字,博客标题变色【随机】 这里的数据都是乱写的:happy:
添加博客页面
这里就是要能够内容编辑和博客内容同步显示【这里的文本域就是textarea,没有引入各种编辑工具】
这里实现很简单,就一个v-model,没有含量
博客预览
这里的设计因为没有数据,所以就简单使用的网站的文字
这里真实的时候,会按照格式显示,因为网站上面只有title和body,所以只是为了展示正常的跳转,没有深究
博客编辑删除
点击博客编辑后,应该实现的效果就是,能够获取到博客的内容,然后基于之前的内容修改
大概这个demo就是这个样子,非常的简单,实现要不了几个小时,就几个组件就完事了,记录的目的只是因为这个过程还是完整的,学完vue了,纪念一下【虽然我是一个后端】
demo中遇到的问题
Component “default” in record with path “/blog/:id” is not a valid component
这个问题非常的easy,原因可能是因为组件没有进行路由绑定,博主是因为在路由规则中将component单词拼错了,也是导致没有绑定成功
下拉列表没有显示所有的数据
在this.data中准备的有athor的数据,使用v-for指令没有正确拿到所有的数据,是因为v-for指令绑定的位置应该是select标签,而不是option标签
<select v-model="blog.author">
<option v-for="item in authors"> <!-- 这里是一个列表,所以v-for在里面 -->
{{item}}
</option>
v-for遍历的是标签包裹的部分,这里详单与就会遍历显示item; 像遍历列表的时候,指令放在ul上面,所以就会循环显示li项
自定义指令v-color测试不成功
这里是因为如果要使用的是数据,就应该使用v-bind进行数据绑定,不然就会默认当作字符串处理; 并且v-color绑定的是颜色,是字符串String类型的,那么双引号里面还有单引号
对于标题的彩色的实现,因为颜色可以表示为# + 6位数字,可以使用随机数实现
app.directive('rainbow',(el,binding) => {
// el.style.color = binding.value //binding是一个对象
el.style.color = '#' + Math.random().toString(16).slice(2,8) //这样就可以随机生成颜色,每一个可能都不一样
})
demo部分源码
这里简单展示AddBlog.vue
<template>
<div class="add-blog-container">
<h2>添加博客</h2>
<form v-if="!submitted">
<label>博客标题</label>
<input type="text" v-model="blog.title" required/>
<label>博客内容</label>
<textarea v-model="blog.content"></textarea>
<!-- 选择博客的标签 -->
<div class="checkBoxes">
<label>Vue.js</label>
<input type='checkbox' value="Vue.js" v-model="blog.categories"/>
<label>React.js</label>
<input type='checkbox' value="React.js" v-model="blog.categories"/>
<label>Node.js</label>
<input type='checkbox' value="Node.js" v-model="blog.categories"/>
<label>SpringBoot2</label>
<input type='checkbox' value="SpringBoot2" v-model="blog.categories"/>
</div>
<label>作者:</label>
<select v-model="blog.author">
<option v-for="item in authors"> <!-- 这里是一个列表,所以v-for在里面 -->
{{item}}
</option>
</select>
<button type="button" @click.prevent="postBlog">添加博客</button>
</form>
<div v-else>你的博客添加成功</div>
<div class='preview'>
<h3>博客总览</h3>
<p>博客标题: {{blog.title}}</p>
<p>博客内容</p>
<p>{{blog.content}}</p>
<!-- 遍历数组 -->
<p>博客分类:</p>
<ul v-for="item in blog.categories">
<li>{{item}}</li>
</ul>
<p>作者: {{blog.author}}</p>
</div>
</div>
</template>
<script>
export default {
name: 'AddBlog',
props: {
},
data() {
return {
blog: {
title:'',
content:'',
categories:[],
author:'',
},
authors:["Cfeng","Cshen"],
submitted:false, //控制展示添加表单
}
},
methods:{
async postBlog() {
//这里使用网址测试https://jsonplaceholder.typicode.com/posts
const {data:res} = await this.$ajax.post('https://jsonplaceholder.typicode.com/posts',{
title: this.blog.title,
body: this.blog.content,
userId:1,
})
console.log(res)
this.submitted = true //添加后隐藏表单
}
}
}
</script>
<style lang="less" scoped>
.add-blog-container *{
box-sizing: border-box;
}
.add-blog-container {
margin: 20px auto;
max-width: 600px;
padding: 20px;
background: papayawhip;
label{
display: block; //独占一行
margin: 20px 0 10px; //边距
}
input[type = 'text'],textarea,select { //文本框
display: block;
width: 100%;
padding: 8px;
}
textarea{
height: 300px;
}
.checkBoxes{
label{
display: inline-block; //label在同一行
margin-top: 0;
}
input {
display: inline-block;
margin-right: 10px; //右边
}
}
button{
display: block;
margin: 20px 0;
background: deeppink;
color: #efefef; //文本颜色
border: 0;
padding: 14px;
border-radius: 8px; //圆角
font-size: 18px; //字体
cursor: pointer; //悬停的鼠标样式
}
//博客总览部分
.preview{
padding: 10px 20px;
border: 1px dotted #ccc;
margin: 30px 0;
h3{
margin-top: 10px;
}
}
}
</style>
这个demo就这样了,如果有什么问题欢迎交流🎉