springBoot+vue

Vue

运行时自动打开页面

在package.json中

"scripts": {
    "serve": "vue-cli-service serve --open",
    "build": "vue-cli-service build"
  },

头部

<div style="height: 50px; line-height: 50px;border-bottom: 1px solid #ccc;display: flex">
<div style="width: 200px">后台管理</div>
<div style="flex: 1"></div>
<div style="width: 100px">下拉框</div>
</div>

去除一下框框中空白部分

创建global.css

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

在main.js中引入

import '@/assets/css/global.css'

安装element-plus

npm install element-plus --save
yarn add element-plus

注意,出现了一个错误或BUG,刚开始使用的cnpm下载的,可能是因为我用的yarn管理的,所以一直报错,el组件没有用,最后卸载了重新用yarn下载了一下解决了

安装图标插件

yarn add @element-plus/icons-vue

侧边栏

App.vue中

<nav>

  <Header></Header>
  <div style="display: flex">
    <Aside></Aside>
    
    <router-view style="flex: 1" />   这个样式让他分成左右两部分
  </div>
Aside.vue中

.el-menu-vertical-demo{
    min-height: calc(100vh - 50px);     calc是计算,此处注意calc(100vh空格-空格50px)
}

表格

<el-table :data="tableData" border stripe style="width: 100%">
    <el-table-column prop="date" sortable label="Date"/>
    <el-table-column prop="name" label="Name"/>
    <el-table-column prop="address" label="Address"/>
</el-table>
属性
border 边框
stripe 斑马纹
sortable  排序

安装axios

yarn add axios

△!△!坑坑坑△!△!上面是@RestController,后端接收数据要控制格式@RequestBody

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
   @PostMapping("/sss")
    public Result save(@RequestBody User user){
       userService.saveUser(user);
       return Result.success();
   }

SpringBoot

1.mybatis-plus之联表查询实现

①简单的思路就是将查询的数据进行打包、封装到实体类中

例如实体类中Commodity商品

@TableField(exist = false)
    private List<Img> imgList;

@TableField(exist = false) 表示它不是数据库表中的字段

将查询到的图片集合存入到其中

最后将Commodity对象集合返回给前端即可

②★★写Mapper.xml 以购物车模块为例★★

  1. 在Mapper中编写相应的方法

    @Repository
    public interface CartMapper extends EasyBaseMapper<Cart> {
        List<Cart> selectCart(@Param("userId")Integer userId);
    }
    
  2. 在resources/目录下创建一个mapperXML文件夹便于管理,在其中放入Mapper.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="cn.com.liucccc.mapper.CartMapper">
        <select id="selectCart" resultMap="selectCartMap">
            SELECT cart_id,commodity_id,commodity_quantity FROM tab_cart WHERE user_Id=#{userId}
        </select>
        <resultMap id="selectCartMap" type="Cart">★★这里type本应写全Bean的路径因为在yaml中配置了所以直接写就行★★
            <id property="cartId" column="cart_id"/>
            <result property="commodityId" column="commodity_id"/>
            <result property="commodityQuantity" column="commodity_quantity"/>
            <!--调用CommodityMapper的查询-->
            <association property="commodity" column="commodity_id" select="cn.com.liucccc.mapper.CommodityMapper.selectOneCommodity"/>
        </resultMap>
    </mapper>
    
  3. 主启动类里面加入@MapperScan(“cn.com.liucccc.mapper”) 扫包

  4. yaml中配置

    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      mapper-locations: classpath:mapperXml/*.xml
      type-aliases-package: cn.com.liucccc.bean
    

2.商品类别/迭代联表调用:

<select id="getCategoryList" resultMap="getCategoriesMap">
  SELECT category_id,`name`,category_level,is_base FROM tab_category WHERE parent_category_id=0
</select>
<!--嵌套查询-->
<select id="getCategories" resultMap="getCategoriesMap">
  SELECT category_id,`name`,category_level,is_base FROM tab_category WHERE parent_category_id=#{categoryId}
</select>
<resultMap id="getCategoriesMap" type="Category">
    <id property="categoryId" column="category_id"/>
    <result property="name" column="name"/>
    <result property="categoryName" column="category_name"/>
    <result property="categoryLevel" column="category_level"/>
    <result property="isBase" column="is_base"/>
    <collection property="childrenList" ofType="Category" column="{categoryId=category_id}" select="getCategories"/>
</resultMap>

3.Mybatis-plus insertBatchSomeColumn批量插入

基础的自带的:

不光有个BaseMapper 还有个IService接口,它里面有个saveBatch方法,但它是伪批量提交实际上还是一条一条插入,效能不太行

★★insertBatchSomeColumn批量插入★★

https://blog.csdn.net/qq_50652600/article/details/126038809 别的博主写的博客

  1. 导入拓展包

    <!--拓展包-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-extension</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    
  2. 在config目录下编写一下内容即可
    编写SQL注入器

    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
    import com.baomidou.mybatisplus.core.metadata.TableInfo;
    import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
     
    import java.util.List;
     
    public class EasySqlInjector extends DefaultSqlInjector {
     
     
        @Override
        public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
            // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
            List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
            methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
            return methodList;
        }
     
    }
    
  3. 注册插件在MybatisPlusConfig总配置文件中(就是那个注册分页插件等等的地方)

    //批量插入
        @Bean
        public EasySqlInjector easySqlInjector() {
            return new EasySqlInjector();
        }
    
  4. 重写BaseMapper,便于以后调用

    package cn.com.liucccc.config;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    
    import java.util.Collection;
    
    /*重写BaseMapper*/
    public interface EasyBaseMapper<T> extends BaseMapper<T> {
        /**
         * 批量插入 仅适用于mysql
         *
         * @param entityList 实体列表
         * @return 影响行数
         */
        Integer insertBatchSomeColumn(Collection<T> entityList);
    }
    
    
  5. 调用

    //直接继承重写后的BaseMapper即可
    public interface CartMapper extends EasyBaseMapper<Cart> 
    

新知!

1.关于对话窗口调用DOM问题

父组件调用子组件

<!--用户注册组件-->
<UserRegister ref="UserRegister"/>
this.$refs.UserRegister.form

配合ref和this.$refs.UserRegister.

对话框中的内容是懒加载的,这意味着在对话框打开之前,默认插槽(个人理解为el-dialog标签内的内容)不会被渲染到DOM上。因此,如果你需要执行一个DOM操作或通过ref访问组件,可在open事件等回调事件中进行。

在本次实验中,我把用户表单放到了一个组件中,在注册时用户时等调用这个组件,但是这样无疑也造成了许多麻烦,比如这里调用子组件的表单信息,因为它懒加载,所以不能直接的、直观的把form数据取出来,在向后台提交数据form的时候无疑产生了问题,无法取到数据。

**(1)**在本次实验中,针对这个问题,数据的传递时,在确认框里面(对话窗点击确定后弹出的)的回调区域调用,猜测都是回调,在生命周期地位相同,所以可以操作到DOM,取到数据

(2)新想法,在el-dialog标签中绑定鼠标点击事件,在点击确定的时候点下的时候,将表单数据传到父组件中新定义的form中,绑定松开鼠标的时候,调用一个三元判断,来确定调用注册的函数还是更新的函数,在对应的函数里编写相应的提交数据的代码,因为将子组件的数据提前存到了父组件中,所以使用起来就没有障碍了,

关于确认框怎么处理,还没有想到好的解决办法,因为想点击确认的时候再提交数据,虽然可以重复写代码,但是会感觉代码有点冗余,有待改进

2.△!△!坑坑坑△!△!

后端接收数据要控制格式@RequestBody

上面是@RestController,后端接收数据要控制格式@RequestBody

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
   @PostMapping("/sss")
    public Result save(@RequestBody User user){
       userService.saveUser(user);
       return Result.success();
   }

因为前后端分离了所以要加@RestController而不是Controller

3.id 的封装应该使用Integer

如果用int的话id的默认值会是0,会出现一些问题,比如在mypatisplus使用save时就不能使用算法生成id了,这样会生成id0的数据,如果有唯一或者主键约束的话,下一次生成就会报错。

4.三元运算符和if-else

最根本的区别就是?:是表达式,是有结果以及其他表达式的特性的。而if else是控制语句

关于vue中写if报错,网友说法是对象中不能写if-else,但可以使用三元运算符

错误写法if-else不可使用

if(this.form.id){
    request.put("/users/updateUser", this.$refs.UserRegister.form).then(res => {
        console.log(res)
        this.load()/*刷新表格*/
    })
}else{
    /*提交表单信息*/
    request.post("/users/save", this.$refs.UserRegister.form).then(res => {
        console.log(res)
        this.load()/*刷新表格*/
    })
}

正确写法

/*判断表单中数据有没有id,如果有id那就是要更新,没有就是注册*/
this.form.id?request.put("/users/updateUser", this.$refs.UserRegister.form).then(res => {
    console.log(res)
    this.load()/*刷新表格*/
}):
/*提交表单信息*/
request.post("/users/save", this.$refs.UserRegister.form).then(res => {
    console.log(res)
    this.load()/*刷新表格*/
})

原来整体代码

/*新增用户*/
save() {
    /*提示框*/
    ElMessageBox.confirm(
        '您确定提交吗?',
        '提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    )

        .then(() => {
        /*如果提交成功,就把注册的弹窗关闭*/
        this.dialogVisible = false,
            /*判断表单中数据有没有id,如果有id那就是要更新,没有就是注册*/
            this.form.id?request.put("/users/updateUser", this.$refs.UserRegister.form).then(res => {
            console.log(res)
            this.load()/*刷新表格*/
        }):
        /*提交表单信息*/
        request.post("/users/save", this.$refs.UserRegister.form).then(res => {
            console.log(res)
            this.load()/*刷新表格*/
        }),
            ElMessage({
            type: 'success',
            message: '提交成功',
        })


    })
        .catch(() => {
        ElMessage({
            type: 'info',
            message: '取消提交',
        })
    })
}

5.mybatis-plus中插件的使用

注意:

使用多个功能需要注意顺序关系,建议使用如下顺序

  • 多租户,动态表名
  • 分页,乐观锁
  • sql 性能规范,防止全表更新与删除

总结: 对 sql 进行单次改造的优先放入,不对 sql 进行改造的最后放入

在后端中使用了分页和乐观锁两个插件

//分页查询
    @Bean
    public MybatisPlusInterceptor pageInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    //注册乐观锁插件
    @Bean
    public MybatisPlusInterceptor versionInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }

6.可以使input背景变成透明的

background: #ffffff00;

或者background-color: rgba(255, 255, 255, 0.247);

7.图标问题

  • 绑定型,input框里面的图标
<el-input
          :prefix-icon="Search" />


搭配
setup(){
    return {
    	Search
    	}
}

components:中注册没有用
  • 组件型
<el-icon style="vertical-align: middle">
                    <Search/>
                </el-icon>
搭配
components: {
    Search
    }

8.数字类验证问题

解决“element表单验证输入的数字检测出来是string”的问题

数字类型的验证需要在 v-model 处加上 .number 的修饰符,这是 Vue 自身提供的用于将绑定值转化为 number 类型的修饰符。

v-model.number="age“

9.form居中

父元素:text-align: center
子元素:display: inline-block

10.vue element 数据动态生成 el-menu

根据博主的思路,递归调用组件实现了效果

注意判断时我感觉根据长度判断最好,因为有的时候子节点存在,但是为空

v-if=“menuItem.childrenList.length!=0”

<template>
<template v-for="menuItem in list"
          :key="menuItem.categoryId">
    <el-sub-menu :index="menuItem.categoryId.toString()" v-if="menuItem.childrenList.length!=0">
        <template #title>
            <el-icon>
                <GoodsFilled/>
    </el-icon>
            <span>{{menuItem.name}}</span>
</template>
<Aside :list="menuItem.childrenList"> </Aside>
</el-sub-menu>

<el-menu-item :index="menuItem.categoryId.toString() " v-else>
    <el-icon><GoodsFilled /></el-icon>
    <template #title>{{menuItem.name}}</template>
</el-menu-item>
</template>
</template>

<script>
    import {GoodsFilled} from "@element-plus/icons-vue";

    export default {
        name: "Aside",
        props: {
            list: {},
        },
        components: {GoodsFilled,},
    }
</script>

<style scoped>

</style>

调用处

<el-menu
         default-active="Commodity"
         class="el-menu-vertical-demo"
         :collapse="isCollapse"
         style="max-width: 200px;"
         >
    <el-menu-item index="Commodity">
        <el-icon><Shop /></el-icon>
        <template #title>所有商品</template>
    </el-menu-item>
    <Aside :list="categoryList"></Aside>
</el-menu>

11.组件属性之props

如上例子中

name: "Aside",
  props: {
  list: {},
},

通过如下可以传递数据

<Aside :list="categoryList"></Aside>

12.vue内置动态组件component使用详解

虽然使用的时候出现了种种问题,但感觉它仍是一个重要的知识点

<component
/*判断有没有子节点*/
      :is="menuItem.children ? 'el-submenu' : 'el-menu-item'"
      v-for="menuItem in list"
      :key="menuItem.id"
      :index="menuItem.id.toString()"
    >
      <template v-if="menuItem.children">
        <template slot="title">{{ menuItem.name }}</template>
        <本组件 :list="menuItem.children"></本组件>
      </template>
      <template v-else>
        <i :class="menuItem.icon"></i>
        <span slot="title">{{ menuItem.name }}</span>
      </template>
    </component>

其中,根据绑定的is的值决定拿个组件被渲染。

13.VUE级联选择器,通过props(配置选项)可以控制数据源格式

el-cascader/

emitPath 在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值

14.mySQL数据库相关(级联删除,自增回滚)

级联删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n0NzDOef-1688618603283)(D:\笔记资料\JavaEE笔记\imgs\级联删除.JPG)]

在外键设置里面更改为“CASCADE”,既级联

删除时,被引用的父表某字段删除,子表跟着一起删除

自增回滚

在日常使用MySQL时,我们手动删除几条记录后,会发现后续的数据主键自增出现不连续的情况

我们可以执行如下代码解决

1.如果删除完数据还没有新增数据,即还没有出现不连贯的数据ID时,执行以下语句:

ALTER TABLE 表名 AUTO_INCREMENT = 1;

2.如果表中已经出现不连贯的数据ID时,执行以下语句进行修改:

修改代码中“表名”,和“自增字段名”即可

SET @auto_id = 0;
UPDATE 表名 SET 自增字段名 = (@auto_id := @auto_id + 1);
ALTER TABLE 表名 AUTO_INCREMENT = 1;

15.运算精度问题(使用bigNumber.js)

下载:

yarn add bignumber.js --S

使用:

  • 引入:

  • import { BigNumber } from 'bignumber.js';
    
  • 例子 (自己尝试得出的结论:不知道对不对,两个数运算的时候,只需对其中一个数进行BigNumber转换即可<代码见下>

  • a = BigNumber(a);
    b = BigNumber(b);
    ★★加★★
    a.plus(b).toNumber();   //结果需要用toNumber转为普通数字,不加这个转换好像是返回一个BigNumber对象
    ★★减★★
    a.minus(b).toNumber();
    ★★乘★★
    a.multipliedBy(b).toNumber();
    ★★除★★
    a.dividedBy(b).toNumber();
    多个数求和
    multiAdd(...params) {
      let data = BigNumber(0);
      for (let index = 0; index < params.length; index++) {
        const element = BigNumber(params[index]);
        data = data.plus(element);
      }
      return data.toNumber();
    }
    
    multiAdd(1,2,3,4,5);   //15
    ★★保留两位小数★★
    .toNumber之后
    .toFixed(2)
    

★★自己摸索出的结论:不知道对不对两个数运算的时候,只需对其中一个数进行BigNumber转换即可★★

目前看上去没啥问题

sum(){
let a=BigNumber(0.3)
let b = 0.1
return a.minus(b).toNumber();
},
sum2(){
let a=0.3
let b=0.1
return a-b;
}
运算结果:
sum=0.2
sum2=0.19999999999999998

16.MySql DataTime类型 返回值矫正

时间类型返回数据的时候,返回的值不是我想要的年月日时分秒的形式,而是带英文单词的格式

解决办法:

/*将时间格式转换成正常的*/
@JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date createTime;

17.mybatis的xml中调用别的xml的查询方法

<!--调用CommodityMapper的查询-->
<association property="commodity" column="commodity_id" select="cn.com.liucccc.mapper.CommodityMapper.selectOneCommodity"/>

注意:要写全mapper的namespace

18.逻辑删除

  • 局部使用

    @TableLogic(value = "0",delval = "1")
    private Integer deleted;
    
  • 全局使用

    mybatis-plus:
      global-config:
        db-config:
          logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
          logic-delete-value: 1 # 逻辑已删除值(默认为 1)
          logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
    

在使用insertBatchSomeColumn批量插入的时候,会让自动插入默认值失效

**解决办法:**使用mybatis plus带的自动填充策略

this.setFieldValByName("deleted",0,metaObject);

问题!

1.动态el-menu,折叠文字不隐藏、菜单导航折叠后文字不隐藏

原文链接:https://blog.csdn.net/xixiyuguang/article/details/120289766

简单说就是el-menu用了div

这里研究了一下,发现只要我把el-submenu直接放入到el-menu中是可以的,但是实际业务中做动态路由的时候会带着菜单项也为动态的,那么基本上就会吧菜单项抽离为组件然后循环渲染,但是由于 element-ui 的标签本身希望里面嵌套的是,,之一,但是却嵌套了

,而导致收折就隐藏不了文字那么解决方案就来了,我们手动写样式将文字和>隐藏!

注意

2.vue element 数据动态生成 el-menu

原文链接:https://blog.csdn.net/wyk304443164/article/details/124124845

根据这个文章虽然没有实现,因为的问题,就是标题渲染不上去,后来我根据他的思路把component改为template实现了效果,详细见“新知 10.”

<component
      :is="menuItem.children ? 'el-submenu' : 'el-menu-item'"
      v-for="menuItem in list"
      :key="menuItem.id"
      :index="menuItem.id.toString()"
    >
      <template v-if="menuItem.children">
        <template slot="title">{{ menuItem.name }}</template>
        <本组件 :list="menuItem.children"></本组件>
      </template>
      <template v-else>
        <i :class="menuItem.icon"></i>
        <span slot="title">{{ menuItem.name }}</span>
      </template>
    </component>

其中写法在vue 3中 slot改为v-slot写法不同,

3.数据库字段

在实验中,数据库字段起名字起的不规范,造成了许多麻烦

例如许多表中都有name字段,在查询的时候就会出现 “模棱两可的” 报错

4.横向滚动条

想给它加两个按钮,一个往左翻,一个往右翻,

或者说用滑轮能实现滚动

据这个文章虽然没有实现,因为的问题,就是标题渲染不上去,后来我根据他的思路把component改为template实现了效果,详细见“新知 10.”

<component
      :is="menuItem.children ? 'el-submenu' : 'el-menu-item'"
      v-for="menuItem in list"
      :key="menuItem.id"
      :index="menuItem.id.toString()"
    >
      <template v-if="menuItem.children">
        <template slot="title">{{ menuItem.name }}</template>
        <本组件 :list="menuItem.children"></本组件>
      </template>
      <template v-else>
        <i :class="menuItem.icon"></i>
        <span slot="title">{{ menuItem.name }}</span>
      </template>
    </component>

其中写法在vue 3中 slot改为v-slot写法不同,

3.数据库字段

在实验中,数据库字段起名字起的不规范,造成了许多麻烦

例如许多表中都有name字段,在查询的时候就会出现 “模棱两可的” 报错

4.横向滚动条

想给它加两个按钮,一个往左翻,一个往右翻,

或者说用滑轮能实现滚动

没有实现

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值