Spring Boot+Vite+Vue3 二手商城
- 2023-06-13 江苏
本文字数:6463 字
阅读完需:约 21 分钟

Spring Boot+Vite+Vue3 二手商城
软件环境
node .js v16.16.0
npm v8.11.0
jdk v1.8
vite v2.9.13
后端 JAVAIDE
idea 2022.2.1
前端开发 IDE
webStrom 2022.2.1
HBuilderX 3.6.14
maven-3.8.6-bin
前端框架搭建
vite 搭建
# npm 7+, 需要额外的双横线:npm init vite@latest 项目名称 -- --template vuecd 安装路径npm installnpm run dev
引入 element-plus
npm install element-plus --save
引入 vue-router
npm install vue-router -S
修改 vite 项目下的 main.js
import { createApp } from 'vue'import ElementPlus from 'element-plus'//引入element-plus框架import 'element-plus/dist/index.css'//应用element-plus样式import App from './App.vue'import router from './router'//引入vue-router
const app = createApp(App)
app.use(ElementPlus).use(router).mount('#app')//.use(ElementPlus).use(router)使用引入的组件
前端框架编写
编写 router 配置
在 src 目录下创建 router 目录
在目录下床架 index.js 来配置路由文件
import { createRouter, createWebHistory, } from 'vue-router' // 默认的网页标题 const defaultTitle = 'home'; // 配置路由文件 const routes = [ { // 对应的路由路径 path: '/', name: 'Home', // 对应的页面 component: () => import('../views/Home.vue'), // 对应页面的名称 meta: {hidden: true, title: "主页"} }, ] // 创建路由对象 const router = createRouter({ history: createWebHistory("/"), routes: routes, }) // 改变对应页面的标题 router.beforeEach((to, from, next) => { document.title = to.meta.title ? to.meta.title : defaultTitle; next(); }); /** - 输出对象 */ export default router;
应用 router 配置
在 src 目录下创建 views 目录,即具体的路由界面
在 views 目录下创建需要的页面
改写 App.vue
<template> <router-view /> </template> <script> </script> <style> * { margin: 0; padding: 0; } </style>
运行前端框架
npm run dev
编写登录页面
页面主体
编写 SM.MS 图床上传(巨坑)
在 vite.config.js 中配置跨域设置
坑:不能直接使用官方 api 地址,官方 api 地址在中国无法访问,需要改为"https://smms.app/api/v2/"
server:{ proxy: { '/api': { secure: false, changeOrigin: true, target: 'https://smms.app/api/v2/', rewrite: path => path.replace(/^\/api/, '') } } }
编写前端请求
<template> <input type="file" accept="image/*" ref="picture" multiple="multiple" @change="getPicture($event)"/> </template>
<script setup> import axios from "axios"; function getPicture(e) { const formData = new FormData(); formData.append("smfile", e.target.files[0]); axios({ method: "POST", url: "/api/upload",//sm.ms图床 headers: {'Content-Type': 'multipart/form-data', 'Authorization': 'kNpYkOLitfvgPOkitOTBwDfzNzGPMDLY'}, data: formData }).then((response) => { // 在控制台输出响应体中图片在服务器中的url地址 console.log(response.data)//response.data就有返回的图片地址 }); } //存储图片 </script>
<style>
</style>
后端框架搭建
配置 maven(提高导包速度)
apache-maven-3.8.6\conf\setting.xml
<mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf></mirror>
<mirror><id>uk</id><mirrorOf>central</mirrorOf><name>Human Readable Name for this Mirror.</name><url>http://uk.maven.org/maven2/</url></mirror>
<mirror><id>CN</id><name>OSChina Central</name><url>http://maven.oschina.net/content/groups/public/</url><mirrorOf>central</mirrorOf></mirror>
<mirror><id>nexus</id><name>internal nexus repository</name><url>http://repo.maven.apache.org/maven2</url><mirrorOf>central</mirrorOf></mirror>
设置 idea
安装插件
MyBatisX
LomBok(默认已安装)
更改文件编码格式
全改为 UTF-8
设置 maven 路径
创建 Spring-Boot 项目
使用 idea 自动搭建 Spring-Boot 项目
选择生成器中的 Spring Initializer
将服务器 URL 改为:start.aliyun.com
类型选择 Maven
Java 版本选 Java8
选择组件
Spring Web (SpringMVC)
Mybatis
Lombok
编写后端框架
设置 application.properties 来链接数据库
# 应用名称spring.application.name=demo#下面这些内容是为了让MyBatis映射#指定Mybatis的Mapper文件mybatis.mapper-locations=classpath:mappers/*xml#指定Mybatis的实体目录mybatis.type-aliases-package=com.example.demo.entity# 数据库驱动:spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# 数据源名称spring.datasource.name=defaultDataSource# 数据库连接地址spring.datasource.url=jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2b8&characterEncoding=utf8# 数据库用户名&密码:spring.datasource.username=rootspring.datasource.password=root# 应用服务 WEB 访问端口server.port=8080
解决跨域问题
在路径下新建 common 包
新建 Java 类,命名为 CorsConfig
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { // 当前跨域请求最大有效时长。这里默认1天 private static final long MAX_AGE = 24 * 60 * 60; @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址 corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 corsConfiguration.setMaxAge(MAX_AGE); source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置 return new CorsFilter(source); } }
创建 Mapper(接口)目录
在 resources 文件下创建 mapper 目录(mybatis.mapper-locations=classpath:mappers/*xml 由上方该条语句来确定创建目录的位置)
创建 entity(实体)类
创建 entity 包,用于管理不同实例 entity 类
以实例 User 为例
// 引入lombok,快速创建get,set函数 import lombok.Data; // 标记为lombok的Data @Data public class User { // 根据数据库设置对应数据类型 private Integer id; private String username; private String password; private String sex; private Integer age; private String phone; private String email; private String address; private String avatar; }
创建和编写 dao(工具)类
创建 dao 包,用于管理不同实例 dao 类
以实例 UserDao 为例
import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; // 为controller类中使用@Autowired自动注入 @Mapper public interface UserDao { // 创建函数后使用Alt+Enter快捷键通过插件快速创建对应的Mapper(需要先创建Mapper接口) // 寻找表中所有元素 List<User> findAll(); User findById(Integer id); // @Param("username") String username 传入参数,且参数名称为"username" User getByUser(@Param("username") String username, @Param("password") String password); // 添加后会返回向表中添加元素的个数 int insert(User user); int update(User user); int deleteById(Integer id); User findByUser(String username); }
配置相应 Mapper.xml 的文件头部来相互链接
以 UserMapper.xml 文件为例
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="对应Dao类的空间地址"> </mapper>
编写 Mapper(写 SQL 查询语句)文件
以 UserMapper.xml 为例
增:
<insert id="insert"> INSERT INTO `user`(username, password,sex,age,phone,email,address,avatar) values (#{username}, #{password},#{sex},#{age},#{phone},#{email},#{address},#{avatar}); </insert>
删:
<delete id="deleteById"> DELETE from `user` where id = #{id}; </delete>
改(使用了动态判断):
<update id="update"> update `user` <set> <if test="username != null and username != ''"> username = #{username}, </if> <if test="password != null and password != ''"> password = #{password}, </if> <if test="sex != null and sex != ''"> sex = #{sex}, </if> <if test="age != null"> age = #{age}, </if> <if test="phone != null and phone != ''"> phone = #{phone}, </if> <if test="email != null and email != ''"> email = #{email}, </if> <if test="address != null and address != ''"> address = #{address}, </if> <if test="avatar != null and avatar != ''"> avatar = #{avatar}, </if> </set> where id = #{id} </update>
查:
查询所有:
<select id="findAll" resultType="com.example.demo.entity.User"> SELECT * FROM user; </select>
通过 Id 查询
<select id="findById" resultType="com.example.demo.entity.User"> SELECT * FROM user WHERE id = #{id}; </select>
通过用户名和密码查询
<select id="getByUser" resultType="com.example.demo.entity.User"> SELECT * FROM user WHERE username = #{username} AND password = #{password}; </select>
创建 Result(返回数据打包)类
在 common 包中创建 Result 类
package com.example.demo.common; import lombok.Data; @Data public class Result { private String code; private String msg; private Object data; private static final String SUCCESS_CODE = "200"; private static final String SUCCESS_MSG = "请求成功"; private static final String ERROR_CODE = "-1"; // 成功的返回的函数(无参数) public static Result success() { Result result = new Result(); result.setCode(SUCCESS_CODE); result.setMsg(SUCCESS_MSG); return result; } // 有返回参数的函数 public static Result success(Object data) { Result result = success(); result.setData(data); return result; } // 请求失败后,返回一个失败原因 public static Result error(String msg) { Result result = new Result(); result.setCode(ERROR_CODE); result.setMsg(msg); return result; } }
创建和编写 controller(控制)类
创建 controller 包,用于管理不同实例 controller 类
以 UserController 为例
package com.example.demo.controller;
import com.example.demo.common.Result; import com.example.demo.dao.UserDao; import com.example.demo.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
import java.util.List;
// 设置该类为控制器类 @RestController // 设置默认访问路径,即通过"127.0.0.1/user"来访问接口 @RequestMapping("/user") public class UserController {
// 自动注入 @Autowired private UserDao userDao;
// Get接口 @GetMapping public Result findAll() { return Result.success(userDao.findAll()); }
// @PathVariable需要一个参数时 @GetMapping("/{id}") public Result findById(@PathVariable Integer id) { return Result.success(userDao.findById(id)); }
@GetMapping("/username/{username}") public Result findByUser(@PathVariable String username) { return Result.success(userDao.findByUser(username)); }
// @RequestBody 需要多个参数时,直接把前端的对象转换为实体类 @PostMapping public Result save(@RequestBody User user) { // 一旦不满足要求就直接返回失败 if (user.getUsername() == null || user.getPassword() == null) { return Result.error("参数错误"); } Result result =Result.success(userDao.insert(user)); return result; }
@PostMapping("/login") public Result login(@RequestBody User user) { if (user.getUsername() == null || user.getPassword() == null) { return Result.error("参数错误"); } User result = userDao.getByUser(user.getUsername(), user.getPassword());
if (result == null) { return Result.error("账号或密码错误"); }
return Result.success(result); }
@PutMapping public Result update(@RequestBody User user) { if (user.getId() == null) { return Result.error("参数错误"); } userDao.update(user); return Result.success(); }
@DeleteMapping("/{id}") public Result delete(@PathVariable Integer id) { if (id == null || id == 0) { return Result.error("参数错误"); } return Result.success(userDao.deleteById(id) == 1); } }
版权声明: 本文为 InfoQ 作者【路北路陈】的原创文章。
原文链接:【http://xie.infoq.cn/article/0d1638daa4b8db540f3ec420b】。文章转载请联系作者。
路北路陈
还未添加个人签名 2023-06-10 加入
还未添加个人简介










评论 (1 条评论)