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 vue
cd 安装路径
npm install
npm 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=root
spring.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 条评论)