MySQL
一张message的表:
message:留言内容;
username:由后端进行处理,如果提交的为空,那么设置名字为“匿名”;
upTime:提交时间;
likeNum:点赞数量,默认0。
后端
只需做一些简单的增删改查即可
MessageMapper:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.lzy.blog.Mapper.MessageMapper">
<insert id="addMessage" useGeneratedKeys="true" keyProperty="id">
insert into message set message = #{message},username=#{username},upTime=now()
</insert>
<update id="addLike">
update message set likeNum = likeNum + 1 where id = #{id}
</update>
<delete id="deleteMessage">
delete from message where id = #{id}
</delete>
<select id="selectAllMessage" resultType="cn.lzy.blog.Pojo.Message">
select * from message order by upTime desc
</select>
</mapper>
MessageController:
@RestController
@RequestMapping("/message")
public class MessageController {
@Autowired
private MessageService messageService;
@PostMapping("/add")
public Response addMessage(@RequestBody Message message){
Integer id = messageService.addMessage(message);
if(id >0){
return Response.Success("留言成功!",id);
}
return Response.Fail("留言失败");
}
@DeleteMapping("/del/{id}")
public Response delMessage(@PathVariable Integer id){
if(messageService.delMessage(id))
return Response.Success("删除留言成功");
return Response.Fail("删除留言失败");
}
@GetMapping("/all")
public Response selMessage(@RequestParam @DefaultValue(value = "1") Integer pageNo,@RequestParam @DefaultValue(value = "10") Integer pageSize){
PageInfo<Message> messagePageInfo = messageService.selectMessage(pageNo, pageSize);
if(messagePageInfo != null){
return Response.Success(messagePageInfo);
}
return Response.Fail("获取留言失败");
}
@PostMapping("/like")
public Response addLike(@RequestBody JSONObject object){
if(messageService.addLike(object.getInteger("id")))
return Response.Success("success");
return Response.Fail("fail");
}
}
MessageService:
@Service
public class MessageService {
@Autowired
private MessageMapper messageMapper;
public Integer addMessage(Message message){
if(StringUtils.isEmpty(message.getUsername())){
message.setUsername("匿名");
}
return messageMapper.addMessage(message);
}
public boolean delMessage(Integer id){
if(messageMapper.deleteMessage(id) > 0)
return true;
return false;
}
public PageInfo<Message> selectMessage(Integer pageNo,Integer pageSize){
PageHelper.startPage(pageNo,pageSize);
return new PageInfo<>(messageMapper.selectAllMessage());
}
public boolean addLike(Integer id){
if(messageMapper.addLike(id) > 0){
return true;
}
return false;
}
}
留言板的渲染主要是前端的工作,前后端分离下,后端只需分页查找返回数据,由前端进行渲染。
Card封装
对每一条Card,我们进行封装,数据由父组件进行提供。在它加载的时候我们随机生成它的颜色,那么怎么做呢?
设置颜色列表,加载时候产生随机数,随机选定一种颜色作为本卡片的颜色。
每一个Card可以设置like,以及点击like的事件(提交post请求使like+1),为防止多次点击,可以设置标志位,点击后置为true,防止再次点击。
<!-- -->
<template>
<el-card
:style="'margin:0 10px 15px 0;background-color:' + color"
shadow="hover"
>
<div>
<h2 style="font-size: 100%;font-weight: normal;">{{messageData.upTime|dateFormat}}</h2>
</div>
<div>
<p style="font-size: large;">{{messageData.message}}</p>
</div>
<div>
<h3 class="username">来自:{{messageData.username}}</h3>
</div>
<div @click="like" style="float: right;">
<el-link type="primary" :underline="false">
<i class="el-icon-thumb"></i>
({{messageData.likeNum}})
</el-link>
</div>
</el-card>
</template>
<script>
import { dateFormat2 } from "@/utils/dateFormat";
import {post} from '@/utils/http'
export default {
data() {
return {
colorList: ["#97cae6", "#cfc", "#FAC8C8", "#ffc", "#FAC8C8", "#ccf","#c9c","6cc","ff3","#9f6"],
color: "",
isLike: false,
};
},
props: ["messageData"],
mounted() {
this.color = this.colorList[Math.floor(Math.random() * 10)];
},
methods: {
like() {
if (!this.isLike) {
post("/message/like", { id: this.messageData.id }).then(res => {
if (res.code == 200) {
this.messageData.likeNum += 1;
this.isLike = true;
}
});
}
},
},
filters: {
dateFormat(val) {
return dateFormat2(val);
}
}
};
</script>
<style>
.username {
font-family: "Eater", cursive;
color: rgba(33, 33, 33, 0.7);
}
</style>
父组件调用
加载的时候从后端获取Card数据,以及根据分页找到的本页数量,随机生成每一张Card的宽度width[i]。
之后用v-for循环设置每一个卡片的生成,传递message给子组件。
<div style="display: flex;justify-content: space-around;flex-wrap: wrap">
<div
v-for="(message,index) in messageData"
:key="index"
:style="'width:' + width[index] + '%'"
>
<Card :messageData="message"></Card>
</div>
</div>
加载本页所有卡片的代码:
<!-- -->
<template>
<div>
<Add></Add>
<div style="display: flex;justify-content: space-around;flex-wrap: wrap">
<div
v-for="(message,index) in messageData"
:key="index"
:style="'width:' + width[index] + '%'"
>
<Card :messageData="message"></Card>
</div>
</div>
<div style="float:right">
<el-pagination
background
layout="prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
</template>
<script>
import Add from "@/components/message/Add";
import Card from "@/components/message/Card";
import { get, post } from "@/utils/http";
export default {
data() {
return {
messageData: [],
loading: false,
total: 0,
pageNo: 1,
num: 0,
width: []
};
},
components: {
Add,
Card
},
mounted() {
this.loadMessage();
},
methods: {
loadMessage() {
get("/message/all", {
pageNo: this.pageNo,
pageSize: 10
}).then(res => {
if (res.code == 200) {
this.total = res.result.total;
this.messageData = res.result.list;
this.num = res.result.size;
for (var i = 0; i < this.num; i++) {
this.width[i] = this.randomNum(20, 50); //每个卡片宽度介于20%-50%之间
}
this.loading = false;
window.scrollTo(0, 0);
} else {
this.$message.error(res.msg);
this.loading = false;
}
});
},
handleCurrentChange(val) {
this.pageNo = val;
this.loadMessage();
},
randomNum(minNum, maxNum) { //产生一个介于minNum到maxNum的随机数
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
break;
default:
return 0;
break;
}
}
}
};
</script>
<style>
</style>
添加留言组件封装
<!-- -->
<template>
<div>
<el-input
type="textarea"
:autosize="{ minRows: 4, maxRows: 10}"
placeholder="留下你对网站的意见或建议吧"
v-model="message"
style="width:60%;margin:18px 20% 0 20%"
></el-input>
<div>
<el-row :gutter="20">
<el-col :span="12" :offset="5">
<el-input
placeholder="可以选择留下自己的昵称"
v-model="username"
></el-input>
</el-col>
<el-col :span="7">
<el-button @click="submit" type="primary" v-loading="loading" style="margin-bottom:18px">留言</el-button>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import { post } from "@/utils/http";
export default {
data() {
return {
message: "",
username: "",
loading: false
};
},
inject: ["reload"], //封装reload,用于刷新页面
methods: {
submit() {
this.loading = true;
if (this.message == "") {
this.$message.error("你好像没有留言内容哦");
this.loading = false;
return;
}
var params = {
username: this.username,
message: this.message
};
post("/message/add", params).then(res => {
if (res.code == 200) {
this.$message({ type: "success", message: res.msg });
this.reload();
} else {
this.$message.error(res.msg);
this.username = "";
this.message = "";
this.loading = false;
}
});
}
}
};
</script>
<style>
</style>
欢迎大家去我的网站留个言呀。