前端:vite+vue3+ts+elementplus+less

后端:springboot2.7.6+mybatisplus

最终效果大致如下:

后端:

引入pom依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

运行sql

/*
 Navicat Premium Data Transfer

Source Server         : MyDemo
 Source Server Type    : MySQL
 Source Server Version : 80027
 Source Host           : 192.168.157.134:3306
 Source Schema         : giveALike

Target Server Type    : MySQL
 Target Server Version : 80027
 File Encoding         : 65001

Date: 21/11/2022 23:50:34
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for article
-- ----------------------------
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '编号',
  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '内容',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of article
-- ----------------------------
INSERT INTO `article` VALUES (1, '11');
INSERT INTO `article` VALUES (2, '666');
INSERT INTO `article` VALUES (3, '777');
INSERT INTO `article` VALUES (4, '999');

-- ----------------------------
-- Table structure for giveALike
-- ----------------------------
DROP TABLE IF EXISTS `giveALike`;
CREATE TABLE `giveALike`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '编号',
  `user_id` int NULL DEFAULT NULL COMMENT '用户编号',
  `article_id` int NULL DEFAULT NULL COMMENT '文章编号',
  `is_like` int NULL DEFAULT NULL COMMENT '是否点赞(0表示未点赞,1表示点赞)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 935456769 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of giveALike
-- ----------------------------

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '编号',
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '11', '11');

SET FOREIGN_KEY_CHECKS = 1;

项目结构

yml配置,数据库改成你自己的数据库

server:port: 5000spring:application:name: service-userdatasource:url: jdbc:mysql://192.168.157.134:3306/giveALike?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root

entity下的三个实体类

Article:

@Data
public class Article {@TableId(value = "id", type = IdType.AUTO)private Integer id;//编号private String content;//内容
}

GiveALike:

@Data
@TableName("giveALike")
public class GiveALike {@TableId(value = "id", type = IdType.AUTO)private Integer id;private Integer articleId;//文章编号private Integer userId;//用户编号private int isLike;//是否点赞(0表示未点赞,1表示点赞)
}

User:

@Data
public class User {@TableId(value = "id", type = IdType.AUTO)private Integer id;//用户idprivate String username;//用户名private String password;//密码
}

mapper

ArticleMapper:

@Mapper
public interface ArticleMapper extends BaseMapper<Article> {
}

GiveALikeMapper:

@Mapper
public interface GiveALikeMapper extends BaseMapper<GiveALike> {
}

UserMapper:

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

controller

@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/giveALike")
public class GiveALikeController {@Resourceprivate UserMapper userMapper;@Resourceprivate ArticleMapper articleMapper;@Resourceprivate GiveALikeMapper giveALikeMapper;//登录@PostMapping("/login")public User login(@RequestBody User user) {QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();userQueryWrapper.eq("username", user.getUsername());User vo = userMapper.selectOne(userQueryWrapper);if (vo != null && Objects.equals(vo.getPassword(), user.getPassword())) {return vo;} else {return null;}}//获取所有文章数据@GetMapping("/getList")public List<Article> getList() {return articleMapper.selectList(null);}//获取当前用户点赞表的数据@GetMapping("/getUserLike/{id}")public List<GiveALike> getUserLike(@PathVariable int id) {QueryWrapper<GiveALike> wrapper = new QueryWrapper<>();wrapper.eq("user_id", id);return giveALikeMapper.selectList(wrapper);}//点赞@PostMapping("/saveUserLike")public GiveALike saveUserLike(@RequestBody GiveALike giveALike) {QueryWrapper<GiveALike> wrapper = new QueryWrapper<>();wrapper.eq("article_id", giveALike.getArticleId()).eq("user_id", giveALike.getUserId());GiveALike vo = giveALikeMapper.selectOne(wrapper);if (vo != null) {if (vo.getIsLike() == 0) {vo.setIsLike(1);} else {vo.setIsLike(0);}giveALikeMapper.updateById(vo);return vo;} else {giveALike.setIsLike(1);giveALikeMapper.insert(giveALike);return giveALike;}}
}

前端:

相关依赖

目录结构

main.ts页面

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from "./router";createApp(App).use(router).use(ElementPlus).mount('#app')

App.vue页面

<template><div id="app"><router-view/></div>
</template>
<style></style>

路由router.ts

import { createRouter,createWebHistory } from "vue-router";const routes = [{path:"/home",name:'首页',component:()=>import('../page/home.vue')},{path:"/",name:'登录',component:()=>import('../page/login.vue')},
]const router = createRouter({history:createWebHistory(),routes:routes,
})export default router

登录页面login.vue

<template><div class="main"><div class="main_username"><input v-model="user.username" class="username" type="text" placeholder="请输入用户名"></div><div class="main_password"><input v-model="user.password" class="password" type="password" placeholder="请输入密码"></div><el-button @click="login" type="primary" class="main_login">登录</el-button></div>
</template><script setup lang="ts">
import {ElMessage} from 'element-plus'
import {reactive} from "vue";
import axios from "axios";
import router from "../router";interface User {username: string,password: string
}//登录所需的信息
const user = reactive<User>({username: '11',password: '11'
})//登录
const login = () => {axios.post("http://localhost:5000/giveALike/login", user).then((res) => {if (res.data != '') {ElMessage({message: '登录成功',type: 'success',})//跳转页面router.push("/home")//将用户信息存到sessionwindow.sessionStorage.setItem("user", JSON.stringify(res.data))} else {console.log(66)ElMessage.error('登录失败')}})
}
</script><style lang="less" scoped>
.main {.main_username {margin-bottom: 10px;input {font-size: 30px;}}.main_password {input {font-size: 30px;}}.main_login {font-size: 30px;margin-top: 10px;}
}
</style>

home.vue页面

<template><div v-loading="loading"><div v-for="item in data.articleList" :key="item.id"><div class="item"><div class="item_id">编号:{{ item.id }}</div><div class="item_content">内容:{{ item.content }}</div><div>{{ item }}</div><img v-if="item.isLike===0" @click="handleLike(item.id)" src="../assets/未点赞.png" class="item_img" alt="图片"><img v-else @click="handleLike(item.id)" src="../assets/点赞.png" class="item_img" alt="图片"></div></div></div>
</template><script setup lang="ts">
import axios from "axios";
import {reactive, ref} from "vue";
import {ElMessage} from "element-plus";//加载特效
const loading = ref<boolean>(true)const data = reactive({articleList: [] as Article[],//所有内容列表userLikeList: [] as any[]//当前用户点赞表的数据
})interface giveALike {articleId: number,userId: number
}interface Article {id: number,content: string,isLike?: number
}//点赞所需的参数
const giveALikeParam = reactive<giveALike>({articleId: 0,//文章编号userId: 0//用户编号
})//获取所有内容
const getList = () => {axios.get("http://localhost:5000/giveALike/getList").then((res) => {data.articleList = res.data})
}//点赞
const handleLike = (row: number) => {//从session中获取用户信息const user = JSON.parse(window.sessionStorage.getItem("user") || '')//设置用户编号giveALikeParam.userId = user.id//设置文章编号giveALikeParam.articleId = rowaxios.post("http://localhost:5000/giveALike/saveUserLike", giveALikeParam).then((res) => {data.articleList[row - 1].isLike = data.articleList[row - 1].isLike === 1 ? 0 : 1;if (res.data.isLike == 1) {ElMessage({message: '点赞成功',type: 'success',})} else {ElMessage({message: '取消点赞',type: 'warning',})}})
}//获取当前用户点赞表的数据
const getLikeList = async () => {//从session中获取用户信息const user = JSON.parse(window.sessionStorage.getItem("user") || '')const res = await axios.get("http://localhost:5000/giveALike/getUserLike/" + user.id)data.userLikeList = res.data//懒加载setTimeout(async ()=>{await userIsLike()loading.value = false},1000)
}//查询用户是否点赞
const userIsLike = () => {if(data.userLikeList.length!=0){for (let i = 0; i < data.articleList.length; i++) {for (let j = 0; j < data.userLikeList.length; j++) {if (data.articleList[i].id === data.userLikeList[j].articleId) {data.articleList[i].isLike = data.userLikeList[j].isLikebreak;} else {data.articleList[i].isLike = 0}}}}else{for (let i = 0; i < data.articleList.length; i++) {data.articleList[i].isLike = 0}}
}getList()
getLikeList()
</script><style lang="less" scoped>
.item {display: flex;.item_id {margin-right: 10px;}.item_content {width: 100px;}.item_img {width: 100px;height: 100px;cursor: pointer;}
}
</style>

上述代码如有问题,欢迎提出来,博主看到了会第一时间解决

springboot3+react18+ts版

springboot+vue3+ts实现一个点赞功能相关推荐

  1. WebSocket——SpringBoot+Vue3+TS+SockJS+STOMP简单连接使用

    WebSocket--SpringBoot+Vue3+TS+SockJS+STOMP简单连接使用 本文视频以及相关资源 关于WebSocket 文档 什么时候使用WebSocket WebSocket ...

  2. Vue3VideoPlay+vue3+ts封装一个视频播放组件

    vue3+ts封装一个视频播放组件 基于Vue3VideoPlay 做了常用的配置,复制即用! 官方文档https://codelife.cc/vue3-video-play/ 安装 npm安装: n ...

  3. 一个“点赞”功能的实现代码

    "点赞"是最近很流行的一个词,自己也琢磨了一下代码,暂时只实现了功能性代码,要添加漂亮效果,可以继续用Jquery来实现. 主要有两个文件:一是:index.htm,呈现前端页面, ...

  4. 怎么实现一个点赞功能?

    准备redis三种键分别为: product_comment_likes:{%d}[评论赞成数量维护](hash结构,%d=productId,key=评论id,value=评论赞成数量) user_ ...

  5. 使用Vue3+ts封装一个音频audio播放器

    封装后音频播放器样式 大概思路是引入audio音频播放器标签,如果不设置control属性,音频标签就会隐藏,这样我们可以自己写音频播放器的样式,然后调用audio标签的方法,达到封装音频播放器的效果 ...

  6. HTML jQuery实现点赞功能(模仿CSDN的样式)

    效果:(点赞前和点赞后) css代码: #dianzan {width: 55px;height: 22px;display: flex;flex-direction: row;justify-con ...

  7. JavaScript cookie操作实现点赞功能

    实现一个点赞功能十分简单,主要问题在于不能重复点赞. 若是一个有用户的网站,可以通过数据库设计记录用户的点赞,这是可行的. 但是若是一个不记名的网站,如何记录一个用户呢? 这里有两种方法: 第一种是利 ...

  8. mysql表点赞实现_小程序实现列表点赞功能

    最近在开发一个小程序,想添加一个点赞功能,那到底怎么实现呢?因为要和后台服务器同步数据,所以这个我想了好几天应该怎么实现点赞和取消点赞的逻辑,经过两天的实践调试,最终实现了. 思路如下: 1.找到对应 ...

  9. 小程序之列表点赞功能的实现

    最近在开发一个小程序,想添加一个点赞功能,那到底怎么实现呢?因为要和后台服务器同步数据,所以这个我想了好几天应该怎么实现点赞和取消点赞的逻辑,经过两天的苦逼实践调试,最终实现了(真的好累啊). 思路如 ...

最新文章

  1. 均值极差图控制上下限_年度质量回顾-单值移动极差
  2. python中序列类型和数组之间的区别_「Python」序列构成的数组
  3. matlab完整脚本模板,在PyCharm中给Python脚本设置默认的代码模板和活动模板,文末有一个案例(MATLAB GUI和Qt对比做一个界面)...
  4. Java实现统计某字符串在另一个字符串中出现的次数
  5. python3连接oracle 11G数据库
  6. Apache Load Balance Using Haproxy
  7. Spring Boot 如何快速改造老项目?原来这么爽
  8. 职称计算机internet应用模块,全国职称计算机考试题库(Internet应用XP版模块)
  9. Excel常用10个函数
  10. 迅雷下载电影天堂片源,出现“应版权方要求,文件无法下载”的解决方法
  11. 球面坐标系转换为笛卡尔坐标系
  12. bugzilla安装
  13. 伦敦 quant_伦敦统一用户组(LUUG)见面v2.0
  14. Oracle 递归查询详解
  15. 新手学网站建设解疑与技巧1200例
  16. 桌面多出一个IE图标无法删除的解决办法
  17. 用户存续期价值评估CLV(三) Gamma-Gamma模型 Python模拟
  18. 利安德巴赛尔启动韩国年产能40万吨的聚丙烯生产设施;固特异完成收购固铂轮胎 | 能动...
  19. 复选框旁边出现三个点
  20. 2017年8月16日训练日记

热门文章

  1. Anti-aliasing Semantic Reconstruction for Few-Shot Semantic Segmentation
  2. 【期末复习】计算机通信与网络
  3. Java项目使用阿里云平台发送短信说明
  4. 何为大型机、中型机、小型机
  5. 怎样恢复出厂设置并还原Apple Silicon M1 Mac?
  6. 苹果6手机怎么录屏_OPPO手机怎么录屏
  7. 第93天学习打卡(Vue 初识Vue)
  8. 七层网络模型与四层网络模型以及每层网络协议
  9. matlab 损耗计算,matlab配网潮流及线路损耗计算程序.doc
  10. 世界杯四分之一决赛手记 - Part 2