说说QQ音乐项目的那些bug

1.开发工具

1.后端:spring+mybatis+springmvc

2.前端:html+css+js+Vue+webpack

vue中有几个核心的配置:

1.router(路由)

2.axios

3.CORS(同源策略)–可以通过在vue中的配置文件–webpack.dev.conf.js文件中配置

2…数据库

2.1 命名空间namespace

在这里插入图片描述

2.2 主键自增

关键:

如果要实现主键自增必须在代码中国通过useGeneratedKeys进行配置
,不仅如此,还必须在mysql中对表进行自增。不过Navicat中的自增不是那么好配置,我是通过复制代码然后添加自增那段代码来实现表的自增了。如果这两个都配置了,那么就不会报错了。

下面说说代码中如何配置主键自增:
在这里插入图片描述

2.3 mysql的一些坑

在配置数据库url时一定要在末尾指定时间区,如下:

jdbc.driver=com.mysql.jdbc.Driver
//下面这行代码的末尾就指定了时间
jdbc.url=jdbc:mysql://localhost:3306/my_databases?serverTimezone=GMT
jdbc.username=root
jdbc.password=123456

3.同源策略的解决

在这里插入图片描述
然后在访问时我们就可以像下面这样方位目标地址了:

在这里插入图片描述

4.vue的一些坑

1.引入element-ui时(如果要不是全部导入的话),只能以import Input from 'element-ui’这种方式一个个引入,不能使用{}包裹,不然会报错。

2.给vue原型挂上属性时,只能在Vue组件(.vue文件中),访问(目前好像是这样,不是太确定,单目前这样没有报错)。如下:

3.不需要在main.js中new Vue对象中指定axios

4.需要引入axios和VueAxios不然会报错,并且要使用Vue.use()使用它。

5.使用axios时,main.js中需要引入axios.

6.有时候更改了配置文件,最后启动以下服务器,不然会么有效果。

7.通过style=“less” 可以对element-ui组件中含有特点class选择器的值进行更改。如下:

8.如果要对绝对定位的父元素的子元素进行溢出隐藏,则需要对子元素也设置和父元素相同的定位,否则没有效果。

//这段代码需要写在外部的style中,并且将要设置的选择器包裹在.el-main(它的父元素),以防更改了全局属性。注意,lang=‘less’后面不要加scoped,不然就没有效果了
<style lang='less'>
.el-main{
  ul.el-carousel__indicators.el-carousel__indicators--horizontal{
  top: 75%;
  left: 45%;
  // 对轮播图的下面的横线变换成圆形
  .el-carousel__button{ 
    width: 13px;
    height: 12px;
    border-radius: 50%;
    margin-left: 20px;
  }  
}
}
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
Vue.prototype.$axios = axios    //全局注册,使用方法为:this.$axios
//过后在每个组件中就可以通过this.$axios访问了axios函数了

5.登录注册验证的总结

一定要先在纸上理清以下验证逻辑,不然会出现各种各样的验证错误。
既然用来element-ui中的表单组件。那么只要数据格式出现异常就直接返回callback函数就可以了,最后通过提交表单中的事件通过validate函数判断其中的参数valid是否为true就可以判断所检验的表单是否数据格式正确。不需要自己再额外定义一些标记来判断了。
下面贴上一段注册验证的代码(采用vue实现)

<template>
  <div class="login">
    <el-form
      :model="ruleForm"
      status-icon
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item prop="username">
        <el-input
          type="text"
          v-model="ruleForm.username"
          autocomplete="off"
          placeholder="请输入用户名"
        ></el-input>
      </el-form-item>
      <el-form-item prop="pass">
        <el-input
          type="password"
          v-model="ruleForm.pass"
          autocomplete="off"
          placeholder="请输入密码"
        ></el-input>
      </el-form-item>
      <!-- 再次输入密码 -->
      <el-form-item prop="repeatpass">
        <el-input
          type="password"
          v-model="ruleForm.repeatpass"
          autocomplete="off"
          placeholder="请再次输入密码"
        ></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
          >提交</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
    <div class="login_fit">
      <a href="/login">登录</a>
    </div>
    <div class="register_fit">
      <a href="/register" :style="aStyle">注册</a>
    </div>
    <!-- 用户名和密码的图标 -->
    <div class="user"><img src="@/assets/user.png" alt="" /></div>
    <div class="pass"><img src="@/assets/pass.png" alt="" /></div>
    <div class="pass_1"><img src="@/assets/pass.png" alt="" /></div>
  </div>
</template>

<script>
var patt = /([0-9]|[a-z]|[A-Z]|$|@)/i;
var starPatt = /^[0-9]/i;
var i;
export default {
  data() {
    let self = this;

    // 用户名校验
    var validateUsername = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入用户名"));
      } else {
        // 如果第一个字符是数字    注意:用户名第一个字符不能为数字  isNumber=false(代表可以首字符不可以是数字)
        if (starPatt.test(value[0])) {
          self.valiData.isNumber = false;
        }
        // 用于对格式进行长度、字符格式的校验
        self.validate(value, callback, "user");
      }
    };

    // 密码校验  value:为表单中输入的值          注意:密码第一个字符可以为数字  isNumber=true(代表可以首字符可以是数字)
    var validatePass = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入密码"));
      } else {
        self.valiData.isNumber = true; //用于对首字符进行检验     注意:data中访问数据用使用this
        self.validate(value, callback, "pass");
      }
    };

    // 对再次输入密码的校验
    var validateRepeatPass = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请再次输入密码"));
      } else {
        if (self.ruleForm.pass != self.ruleForm.repeatpass) {
          callback(new Error("2次输入的密码不一样"));
        } else {
          self.valiData.isNumber = true; //用于对首字符进行检验     注意:data中访问数据用使用this
          self.validate(value, callback, "repeatpass");
        }
      }
    };

    return {
      // ruleForm:为表单数据对象--用于初次输入密码  重复输入密码不能和它共用一个不然两者的内容一样
      // 注意:props属性的值必须在ruleForm中配置
      ruleForm: {
        username: "",
        pass: "",
        repeatpass: "",
      },
      repeatPass: {
        // 用于存储重复输入密码
        pass: "",
      },
      // 用于对首字符进行检验
      valiData: {
        isNumber: true,
      },
      status: "",
      islegal: {
        //提交的时候要对3个都进行验证才可以成功
        user: false,
        pass: false,
        repeatpass: false,
      },
      // rules:表单验证规则 即(只负责对数据的格式进行校验)
      rules: {
        // 用户名校验规则    blur:当表单失去焦点时
        username: [{ validator: validateUsername, trigger: "blur" }],
        // 密码校验规则
        pass: [{ validator: validatePass, trigger: "blur" }],
        //重复密码的校验规则
        // 注意:props属性的值必须在ruleForm中配置   否则该规则无效 即 前面的属性repeatpass对应props的值
        repeatpass: [{ validator: validateRepeatPass, trigger: "blur" }],
      },
      //样式设置
      aStyle: {
        color: "rgb(201, 20, 20)",
      },
    };
  },
  methods: {
    // 提交按钮
    submitForm(formName) {
      const that = this;
      // validate:对整个表单进行校验的方法       valid=true:代表所有数据格式检验成功  valid=false:代表有错误的红色字体提示
      that.$refs[formName].validate((valid) => {
        // 即如果输入的数据格式都合法就添加数据
        if (valid) {
          that
            .RequestMessage("/spring/adduser", that.ruleForm)
            .then((res) => {
              console.log(res);
              //将添加成功的status存入data的属性status中
              that.status = res.data.status;
              if (that.status == "success") {
                that.$message({
                  showClose: true,
                  message: "恭喜你,注册成功!",
                  type: "success",
                });
                //重定向到登录界面
                that.$router.push("/login");
              }
            })
            .catch((err) => {
              console.log("添加失败!");
              console.log(err);
              this.$message({
                showClose: true,
                message: "注册失败,可能是数据库异常,请重新注册!",
                type: "error",
              });
            });
        } else {
          this.$message({
            showClose: true,
            message: "注册失败,请重新注册!可能是数据格式校验不正确",
            type: "error",
          });
        }
        // 用于向数据库添加数据
      });
    },
    // 重置按钮
    // 注意:如果要重置表单 必须表单的所哟props属性值都必须在ruleForm中配置
    resetForm(formName) {
      // resetFields:对整个表单进行重置
      this.$refs[formName].resetFields();
    },
    // 用于对用户名和密码进行校验的函数
    //   value:为表单数值  callback为data中回调函数
    validate(value, callback, name) {
      // 对用户名进行格式校验   3<=长度<=15
      if (this.valiData.isNumber && value.length >= 3 && value.length <= 15) {
        // 用于判断数据是否满足格式要求
        for (i = 0; i < value.length; i++) {
          if (patt.test(value[i])) continue;
          // 如果不合法
          else {
            callback(new Error("只能包含[0-9]/大小写字母/$/@等字符"));
          }
        }
        if (i == value.length) {
          callback();
        }
      } else {
        if (
          !this.valiData.isNumber &&
          3 <= value.length <= 15 &&
          name == "user"
        ) {
          callback(new Error("首字符不能是数字"));
        } else {
          callback(new Error("字符个数要>=3"));
        }
      }
    },
  },
  mounted() {},
};
</script>

<style lang='less'  scoped>

6.mybatis的一些注意事项

对于查询

在这里插入图片描述

对于更新、删除

在这里插入图片描述

关于插入数据成功表中却没数据

百度过后有以下几个原因:

1.insert语句虽然执行完毕,但是事务没有执行完毕。即sql语句并不是和事务同时完成的,它们有区别。因为事务还未完成所以导致数据没有写入表中。

2.sql语句已经拼接好,但是没有执行。(这个暂时没有理解)

3.sql语句执行了事务回滚:sql语句内部事务回滚,或sql语句所在整个事务回滚 (回滚:就是数据回退,相当于撤销的意思)

约束文件内容

1.全局约束文件mybatis-config.xml文件

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

2.mapper.xml文件约束

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

3.报约束不存在
在这里插入图片描述

vue中引入jquery

首先要在webpack.conf.dev.js配置文件中的plugins选项中加上下面这段代码:

 // jQuery相关配置  
    new webpack.optimize.CommonsChunkPlugin('common.js'),
    new webpack.ProvidePlugin({
      jQuery: "jquery",
      $: "jquery" 
    }) 

7.路由配置

js文件:

// 路由
import VueRouter from 'vue-router'
import Vue  from 'vue'
import Index from '../views/index.vue'
import Neopterin from '../components/index/neopterin.vue'
import Ranking from '../components/index/ranking.vue'
import Mv from '../components/index/MV.vue'
import Footer from '../components/index/footer.vue'
import Login from '../components/login/login.vue'
import Register from '../components/register/register.vue'

Vue.use(VueRouter)

const routers=[
    {
        path:'/index',
        component:Index,
    },
    {
        path:'/new',
        component:Neopterin
    },
    {
        path:'/ranking',
        component:Ranking
    },
    {
        path:'/mv',
        component:Mv        
    },
    {
        path:'/footer',
        component:Footer
    },
    {
        path:'/login',
        component:Login
    },
    {
        path:'/register',
        component:Register
    }
]

export default new VueRouter({
    mode:'history',
    routes:routers
})

main.js中:

import router from './router/route'

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
})
Logo

更多推荐