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就这样了,如果有什么问题欢迎交流🎉

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐