当前位置: 首页 > news >正文

Vue3环境搭建+Mybatis-plus的使用

文章目录

  • 一、Vue简介
  • 二、Vue 3安装
  • 三、使用Vite构建工具创建Vue 3项目
    • 创建项目
    • 配置 vite.config.js,添加server配置项。
  • 四、快速上手:Axios发送异步请求
  • 五、关于Mybatis-plus
  • 六、前后端分离项目常见问题:禁止跨域:

一、Vue简介

vue是前端知识,是前端框架,单页应用,他只有一个首页,其他都放在js里面,需要的时候js在页面中画出来应用。无需直接操作Dom元素。

二、Vue 3安装

安装node.js: 帮助我们编译vue里面的组件。

官网下载长期支持版本即可,傻瓜式安装,全部下一步即可。

安装pnmp:

npm install -g pnpm   #命令窗口以管理员的身份运行

在这里插入图片描述

三、使用Vite构建工具创建Vue 3项目

创建项目

cd d:/vue3       //切换到创建项目的路径
pnpm create vite@latest demo1   //在项目创建向导中,需要手动选择使用的技术栈

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
项目创建完成。

注:创建demo1目录时,必须在拥有文件写操作权限的位置,
尽量不要选择在C 盘,也不建议在根目录下。
cd demo1        #进入到demo1目录
pnpm install    #在项目目录下,执行此指令安装Vue项目所有依赖

使用cd指令进入到项目目录下 必须是在包含package.json所在目录下 ,使用pnpm install安装Vue 3项目依赖包。

在这里插入图片描述
创建成功后会多出来两个文件:
在这里插入图片描述
输入pnpm dev进行项目测试 :
在这里插入图片描述
在这里插入图片描述
成功,使用IDEA打开

配置 vite.config.js,添加server配置项。

import {defineConfig} from 'vite';
import vue from '@vitejs/plugin-vue';
import {resolve} from "path";// https://vite.dev/config/
export default defineConfig({plugins: [vue()],server: {host: "localhost",port: 3000,//启动后自动打开浏览器open: true},resolve: {alias: [{find: "@",replacement: resolve(__dirname, "src")//把项目中的@符换成src路径}]}
})

在这里插入图片描述
退出终端的方式:Ctrl+C

进入到项目目录下,安装vue-router和axios
写程序这两个是不可或缺的:

pnpm install vue-router
pnpm install axios

在这里插入图片描述

四、快速上手:Axios发送异步请求

安装:pnpm install axios
我们的当前页面是客户管理页面,客户管理页面这种 通常是需要显示相关的数据的,相关数据就来自后端响应给我们
在这里插入图片描述
前端向后端发送一个get请求 。请求的路径如上。并携带着分页参数。所以会去查找这个路径,对应的方法就要做出响应,所以接下来要写后端部分。我们使用这个Vue是做前后端分离的项目。在前后端分离的项目中,我们前端负责响应页面,后端只需要响应数据即可。

我们后端使用:Mybatis-plus。如下介绍。

五、关于Mybatis-plus

引入依赖:pom.xml

        <!--        mybatis-plus--><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.12</version></dependency>

以及:

<!-- 自动分页插件https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-jsqlparser -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>3.5.12</version>
</dependency>

其他层次的后端写法是一样的,这项技术是用来改造Dao层的:

关于Mybatis-plus的使用,首先需要我们Dao层这个接口去继承BaseMapper<具体的模型类>
然后将自定义的查询接口改成默认方法:default修饰
Mybatis-plus能够根据查询条件的对象自动组装条件(前端传递的参数哪个不为空就根据哪个查询,但是全是=判断的,不提供范围的查询方式,范围查询需要我们在Dao层代码中自己实现):前提得去实体类里面配置:在实体类加:

(1)必做项:在类的上面加上@TableName("对应的数据库表名")//指定模型类对应哪个表
(2)必做项:在主键 上面加上@TableId(type = IdType.AUTO)//指定表的主键
(3)可选项:如果属性名和数据库表中的列名不一致,我们需要在字段上面添加   @TableField("数据库中实际的列名")
(4)可选项:参数的自动查询是依照=进行的,但是比如我们想要模糊查询:名字、电话这种等等,可以在对应的字段上面加上    @TableField(condition = SqlCondition.LIKE)
(5)比如根据范围查询,这种mybatis-plus没有提供,需我们手写。

所以实体类代码示例 :

package com.stedu.model;import com.baomidou.mybatisplus.annotation.*;
import com.stedu.util.AuditEntity;
import lombok.*;import java.time.LocalDate;@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString@TableName("t_member")//指定模型类对应哪个表
public class Member extends AuditEntity {@TableId(type = IdType.AUTO)//指定表的主键private Integer id;@TableField(condition = SqlCondition.LIKE)private String phone;private String username;private String password;@TableField(condition = SqlCondition.LIKE)private String name;private String pinyin;private String sex;private LocalDate birthday;@TableField(condition = SqlCondition.LIKE)private String wechat;@TableField(condition = SqlCondition.LIKE)private String email;private String description;}

Dao层代码 示例:

package com.stedu.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stedu.model.Member;
import com.stedu.model.search.MemberSearchBean;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface MemberMapper extends BaseMapper<Member> {//查询全部default Page<Member> findAll(Page<Member> page, MemberSearchBean msb) {//能够根据查询条件的对象自动组装条件:前提得配置:去实体类里面LambdaQueryWrapper<Member> queryWrapper = Wrappers.lambdaQuery(msb);//关于查询范围的条件查询:只能手写,mybatis-plus没有提供范围的查询,手写 :if (msb.getBirthdayFrom() != null) {//拼一个条件:大于等于:ge他的条件queryWrapper.ge(Member::getBirthday, msb.getBirthdayFrom());}if (msb.getBirthdayTo() != null) {//拼一个条件:小于等于:lt他的条件queryWrapper.lt(Member::getBirthday, msb.getBirthdayTo());}return selectPage(page, queryWrapper);//返回页,在baseMapper里面。分页查询,包装器。}
}

其他层次相关调用汇总如下:

模型类另外的::
MemberSearchBean 封装查询对象

package com.stedu.model.search;import com.stedu.model.Member;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;import java.time.LocalDate;@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor//假设有查询需求是:查询出生日期在这个范围内的人:在业务类中不可能有,但是还需要查询。封装成查询对象
public class MemberSearchBean extends Member {private LocalDate birthdayFrom;private LocalDate birthdayTo;}

service层:
MemberService

package com.stedu.service;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stedu.model.Member;
import com.stedu.model.search.MemberSearchBean;public interface MemberService {
//查询全部会员:多条件组合分页查询page:分页对象,msb:查询条件Page<Member> findAll(Page<Member> page, MemberSearchBean msb);}

MemberServiceImpl

package com.stedu.service.impl;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stedu.dao.MemberMapper;
import com.stedu.model.Member;
import com.stedu.model.search.MemberSearchBean;
import com.stedu.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MemberServiceImpl implements MemberService {private MemberMapper memberMapper;//控制反转:依赖注入,将创建对象的权限反转。@Autowiredpublic void setMemberMapper(MemberMapper memberMapper) {this.memberMapper = memberMapper;}@Overridepublic Page<Member> findAll(Page<Member> page, MemberSearchBean msb) {return  memberMapper.findAll(page,msb);}
}

util层:
AuditEntity

package com.stedu.util;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
//审计字段:
public abstract class AuditEntity {private String createdBy;private LocalDate createdTime;private String updatedBy;private LocalDate updatedTime;
}

JsonResult

package com.stedu.util;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;@Getter
@Setter
@AllArgsConstructor//返回响应格式是Json的工具类:
public class JsonResult<T> {private int code;//错误码,有规范private boolean success;private String msg;//错误提示信息private T data;//日期//提供相关正确和错误信息的返回方法public static JsonResult<?> success() {return success(null);}public static <T> JsonResult<T> success(T data) {return new JsonResult<>(200, true, "操作成功", data);}public static JsonResult<?> fail(int code, String msg) {return new JsonResult<>(code, false, msg, null);}public static JsonResult<?> fail(String msg) {return fail(500, msg);}
}

MemberApi

package com.stedu.api;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stedu.model.Member;
import com.stedu.model.search.MemberSearchBean;
import com.stedu.service.MemberService;
import com.stedu.service.impl.MemberServiceImpl;
import com.stedu.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;@RestController//既包含了@Controller也包含了@ResponseBody
//设置路径以及响应格式:
@RequestMapping(value = "/api/v1/members",produces = MediaType.APPLICATION_JSON_VALUE)
public class MemberApi {//依赖注入:用于自动创建对象,有对象了直接调用方法就行了private MemberService memberService;@Autowiredpublic void setMemberService(MemberService memberService) {this.memberService = memberService;}//查询全部的方法:关于传参 ,肯定有分页参数:分别是页码和页面大小,设置默认的参数1和20。并传入查询条件(封装成对象了)@GetMappingpublic ResponseEntity<JsonResult<?>> findAll(@RequestParam(defaultValue = "1") Integer pageNo,@RequestParam(defaultValue = "20") Integer pageSize,MemberSearchBean msb){//创建分页对象new Page:mybatis-plus自带的Page<Member> page = new Page<>(pageNo, pageSize);//查询全部Page<Member> serviceAll = memberService.findAll(page, msb);return ResponseEntity.ok(JsonResult.success(serviceAll));}
}

六、前后端分离项目常见问题:禁止跨域:

进入到项目目录下,执行指令pnpm install axios,如已安装,则忽略此步。
在项目根目录下创建utils目录,在其下创建api.js,编写内容如下:

import axios from "axios";const api = axios.create({baseURL: "/api",timeout: 3000
});api.interceptors.response.use(resp => resp.data,error => Promise.reject(error || "接口调用异常"));

export default api;
在Customer.vue下,编写内容如下:

<template><h1>客户列表页</h1>
</template><script setup>
import {onMounted} from "vue";
import api from "@/utils/api.js";onMounted(async () => {let resp = await api({url: "http://localhost:8080/api/v1/customers",method: "get",params: {page: 1,limit: 10}});console.log(resp);
});
</script>

此时,控制台会提示错误:禁止跨域。

在这里插入图片描述

跨域解决方案:

1.后端配置:在Controller类上添加@CrossOrigin注解。不推荐

@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@RestController
@RequestMapping(value = "/api/v1/customers", produces = MediaType.APPLICATION_JSON_VALUE)
public class CustomerApi {

2.前端配置:在vite.config.js中配置跨域。此时,axios发送请求时,可使用相对路径,会被自动代理为后端服务器路径。(推荐使用)

import {defineConfig} from 'vite';
import vue from '@vitejs/plugin-vue';
// 导入resolve函数
import {resolve} from "path";// https://vitejs.dev/config/
export default defineConfig({plugins: [vue()],// 服务器端配置server: {open: true,host: "localhost",port: 3000,// 开发时配置代理proxy: {// "/api"对应于util目录下的api.js中配置的baseUrl"/api": {//路径必须以http://开头,不能省略协议名称target: "http://localhost:8080",changeOrigin: true,// 第一个参数是正则表达式,使用/xxx/,双斜线表示正则表达式,xxx是正则表达式内容,没有双引号rewrite: url => url.replace(/^\/api/, "/api/v1")}}},// 配置路径别名,使用@代替src目录resolve: {alias: {"@": resolve(__dirname, "src")}}
})

还有注意修正方式:
在这里插入图片描述

在这里插入图片描述
如果只想拿到data而不想要其他的信息,解决方案:

写个工具类:

import axios from "axios";//创建一个axios实例
let api = axios.create({baseURL: "/api",timeout: 3000
});//配置响应拦截器
api.interceptors.response.use(resp => {//成功的操作:只显示数据return resp.data;
}, resp => {//出现错误的时候return Promise.reject(resp.data.msg || "后台服务异常");
});export default api;//导出api

然后修改前端vue组件:
在这里插入图片描述

在这里插入图片描述

http://www.xdnf.cn/news/1267597.html

相关文章:

  • 【ref、toRef、toRefs、reactive】ai
  • 具体数学:和式(四)求和的一般方法
  • 【linux基础】Linux目录和Windows目录的区别
  • Openlayers基础教程|从前端框架到GIS开发系列课程(19)地图控件和矢量图形绘制
  • SimBA算法实现过程
  • GitHub第三方登录全解析:OAuth 2.0流程详解(适合初学者)
  • 华为实验: 单区域/多区域OSPF
  • 华为实验-VLAN基础
  • ComfyUI——舒服地让大模型为我所用
  • 微信原生小程序 Timeline 组件实现
  • AI大语言模型在生活场景中的应用日益广泛,主要包括四大类需求:文本处理、信息获取、决策支持和创意生成。
  • python学智能算法(三十六)|SVM-拉格朗日函数求解(中)-软边界
  • 算法题(183):质量检测
  • Java异常:认识异常、异常的作用、自定义异常
  • 扣证件照要点
  • 全栈:JDBC驱动版本和SQLserver版本是否有关系?怎么选择JDBC的版本号?
  • 数据结构—二叉树及gdb的应用
  • WebGIS视角下基孔肯雅热流行风险地区分类实战解析
  • 开源智能手机安全相机推荐:Snap Safe
  • Python如何将图片转换为PDF格式
  • PDF编辑工具,免费OCR识别表单
  • 论文阅读-ZeroDCE和ZeroDCE++
  • 【Spring Boot 快速入门】八、登录认证(二)统一拦截
  • elementui input无法输入问题
  • 202506 电子学会青少年等级考试机器人一级理论综合真题
  • 【n8n教程笔记——工作流Workflow】文本课程(第二阶段)——5 自动化业务工作流——0 用例 (Use case)
  • 阿里云 ECS 怎么用 nginx 部署80端口多个网站
  • 大语言模型提示工程与应用:前沿提示工程技术探索
  • Baumer高防护相机如何通过YoloV8深度学习模型实现输电线路塔电缆检测分割(C#代码UI界面版)
  • 图片拆分工具,自定义宫格切割