{
>
> public User selectByUsername(String username);
>
> }
> ~~~
>
> 创建mapper文件
>
> ~~~xml
>
> PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
>
>
>
> insert into users(username,password,user_img,user_regtime,user_modtime)
> values(#{username},#{password},#{userImg},#{userRegtime},#{userModtime})
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
## 逆向工程
> 简介 - 逆向工程,根据创建好的数据表,生成实体类、DAO、映射文件
> 1. 在src/main/resources的generator目录中创建generatorConfig.xml
>
> ~~~xml
>
> PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
> "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> connectionURL="jdbc:mysql://localhost:3306/vue"
> userId="root" password="root">
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> 2. 添加依赖
>
> ~~~xml
>
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>
> mall-demo
> tech.guan
> 0.0.1-SNAPSHOT
>
> 4.0.0
>
> generator
>
>
> tk.mybatis
> mapper-spring-boot-starter
> 2.1.5
>
>
>
>
>
> org.mybatis.generator
> mybatis-generator-maven-plugin
> 1.3.5
>
> ${basedir}/src/main/resources/generator/generatorConfig.xml
>
>
>
> mysql
> mysql-connector-java
> 5.1.47
>
>
> tk.mybatis
> mapper
> 4.1.5
>
>
>
>
>
>
> ~~~
# Vue简介
## Jquery的复杂性问题
- 使用jQuery进行前后端分离开发,既可以实现前后端交互(ajax),又可以完成数据渲染;
- 存在的问题:jQuery需要通过HTML标签拼接、DOM节点操作完成数据的显示,开发效率低且容易出错,渲染效率较低
- vue 是继jQuery之后的又一优秀的前端框架:专注于前端数据的渲染——语法简单、渲染效率高
## VUE简介
### 前端框架
- 前端三要素:HTML、CSS、JavaScript
- HTML决定网页结构
- CSS决定显示效率
- JavaScript决定网页功能(交互、数据显示)
- UI框架:
- Bootstrap
- amazeUI
- Layui
- JS框架:
- jQuery(jQuery UI)
- React
- angular
- nodejs----后端开发
- vue 集各种前端框架的优势发展而来
### MVVM
> 项目结构经历的三个阶段:
**后端MVC** 我们就可以理解为单体架构,流程控制是由后端控制器来完成
**前端MVC** 前后端分离开发,后端只负责接收响应请求
**MVVM** 前端请求后端接口,后端返回数据,前端接收数据,并将接收的数据设置“VM”,HTML从vm取值
- M model 数据模型 指的是后端接口返回的数据
- V view 视图
- VM ViewModel 视图模型 数据模型与视图之间的桥梁,后端返回的model转换前端所需的vm,视图层可以直接从vm中提取数据
# Vue入门使用
> vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.
> vue的引入
>
> 1. 离线引用:下载vue的js文件,添加到前端项目,在网页中通过script标签引用vue.js文件
> 2. CDN引用:
## 声明式渲染
~~~html
{{msg}}
~~~
> 1. 渲染基本数据类型和字符串
>
> > ~~~html
> >
> >
> >
> >
> >
> >
> > Document
> >
> >
> >
> >
> > {{id}}
> > {{msg}}
> >
> > {{student.stuName}}
> >
> >
> >
> >
> >
> > ~~~
## v-if以及v-for的入门使用
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
> | 序号 |
> 学号 |
> 姓名 |
> 性别 |
> 年龄 |
>
>
> | {{index+1}} |
> {{s.stuNum}} |
> {{s.stuName}} |
> {{s.stuGender=='M'?'男':'女'}} |
> {{s.stuAge}} |
>
>
>
>
>
>
>
> ~~~
## v-bind绑定标签属性
~~~html
Document
~~~
## v-model
> 表单的双向绑定
- 只能使用在表单输入标签
- v-model:value 可以简写为 v-model
~~~html
Document
{{msg}}
~~~
# Vue实例
> 每个使用vue进行数据渲染的网页文档都需要创建一个Vue实例 —— ViewModel
## Vue实例的生命周期
> vue实例生命周期——vue实例从创建到销毁的过程
- 创建vue实例(初始化data、加载el)
- 数据挂载(将vue实例data中的数据渲染到网页HTML标签)
- 重新渲染(当vue的data数据发生变化,会重新渲染到HTML标签)
- 销毁实例
## 钩子函数
为了便于开发者在vue实例生命周期的不同阶段进行特定的操作,vue在生命周期四个阶段的前后分别提供了一个函数,这个函数无需开发者调用,当vue实例到达生命周期的指定阶段会自动调用对应的函数。

~~~html
Document
~~~
# Vue计算属性和侦听器
## 计算属性
> * data中的属性可以通过声明获得,也可以通过在computed通过计算获得
>
> * 特性:计算属性所依赖的属性值发生变化会影响计算属性的值同时发生变化
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
> {{count3}}
>
>
>
>
>
>
> ~~~
## 侦听器
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
> {{count3}}
>
>
>
>
>
> ~~~
# class与style绑定
> 我们可以使用mustache语法将vue中data的数据绑定到HTML标签及标签的属性,如何将data中的值绑定到标签的class及style属性呢?
## class绑定
~~~html
Document
~~~
## style绑定
~~~html
Document
~~~
# 条件与列表渲染
## 条件渲染
### 1. v-if使用
> 在html标签可以添加v-if指令指定一个条件,如果条件成立则显示此HTML标签,如果不成立则不显示当前标签;
>
> 条件可以是一个表达式也可以是一个具体的bool类型值
~~~html
Document
可以看见我是可爱的小管
看不到我
~~~
### 3. v-else使用
> 注意点:v-else标签需要紧跟在v-if的标签之后,中间不能有其他标签
~~~html
Document
可以看见我是可爱的小管
看不到我
嘿嘿
~~~
### 3. v-else-if
~~~html
Document
可以看见我是可爱的小管
看不到我
嘿嘿
优秀
良好
中等
及格
不想理你
~~~
### 4. v-if和v-show区别
> 从功能上将v-show和v-if作用是相同的,渲染过程有区别
> `v-if` 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
>
> `v-if` 也是**惰性的**:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
>
> 相比之下,`v-show` 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
>
> 一般来说,`v-if` 有更高的切换开销,而 `v-show` 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 `v-show` 较好;如果在运行时条件很少改变,则使用 `v-if` 较好。
## 列表渲染
> 将集合数据以表格、列表的形式显示
~~~html
Document
-
{{c.cname}}
| 序号 |
学号 |
照片 |
姓名 |
性别 |
年龄 |
操作 |
| {{index+1}} |
{{s.stuNum}} |
![]() |
{{s.stuName}} |
|
{{s.stuAge}} |
删除
修改
|
~~~
# 事件处理
> - 在使用vue进行数据渲染时,如果使用原生js事件绑定(例如onclick),如果需要获取vue实例中的数据并传参则需要通过拼接来完成
> - vue提供了v-on指令用于绑定各种事件(v-on:click),简化了从vue取值的过程,但是触发的方法需要定义在vue实例的 methods中
> - `v-on:click可以缩写为`@click`
## hello案例
~~~html
~~~
## 原生js函数传值
~~~html
Document
~~~
## 使用dataset对象传值
~~~html
Document
~~~
## 混合使用
> js函数传值和dataset对象传值,俩者混合使用
~~~html
Document
~~~
# 事件修饰符
> 当使用v-on进行事件绑定的时候,可以添加特定后缀,设置事件触发的特性
> 事件修饰符使用示例
>
>~~~html
>
>~~~
> 1. **.prevent** 消除元素的默认事件
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
> ~~~
>
> 2. 阻止事件冒泡(阻止子标签向上冒泡)
>
> 3. 设置只能自己触发事件(子标签不能触发)
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
> ~~~
> 4. .once - 限定事件只触发一次
## 按键修饰符
> 按键修饰符就是针对键盘事件的修饰符,限定哪个按键会触发事件
> 为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名
> .enter
>
> .tab
>
> .delete` (捕获“删除”和“退格”键)`
>
> .esc
>
> .space
>
> .up
>
> .down
>
> .left
>
> .right
~~~html
~~~
## 修饰符别名
除了以上vue提供按钮的别名之外,我们还可以根据键盘为按键自定义别名
你还可以通过全局 `config.keyCodes` 对象[自定义按键修饰符别名](https://cn.vuejs.org/v2/api/#keyCodes):
~~~html
Document
~~~
## 系统修饰符
> 组合键
>
> - `.ctrl`
> - `.alt`
> - `.shift`
> - `.meta` windows键
~~~html
Document
~~~
# 表单输入绑定
> 表单输入绑定,即双向绑定:就是能够将vue实例的data数据渲染到表单输入视图(input\textarea\select),也能够将输入视图的数据同步更新到vue实例的data中
~~~html
Document
~~~
# 组件介绍和使用
> 组件介绍及示例
>
> 组件,就是将通用的HTML模块进行封装——可复用
## 自定义组件的结构
> - `data` 定义组件的模板渲染的数据
> - `template` 组件的HTML模块(HTML标签\css样式)
> - `methods` 定义组件中的标签事件绑定的JS函数
## 全局组件注册
~~~html
Document
~~~
## 私有组件
~~~html
Document
此处必须要有一个根元素
我是一个私有组件
~~~
## 切换组件
> Vue提供了component来展示对应名称的组件 component是一个占位符 :is属性用来指定要显示的组件的名称
~~~html
Document
~~~
## 组件通信
> vue实例本身就是一个组件(模板就是el指定容器 ,data就是组件数据,methods就是组件的事件函数)
> 在vue实例指定的el容器中引用的组件称为子组件 ,当前vue实例就是父组件
### 父传子
> vue实例引用组件的时候,传递数据到引用的组件中,示意图
> 
> 代码示例父中代码
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
> ~~~
> 子组件示例
>
> **props:["title"]**
>
> ~~~html
> const Feature = Vue.component('header-bar',{
> data:function(){
> return {
> //title:"亲爱的小管"
> }
> },
> template:`
>
>
>
>
> |
>
>
> |
>
>
> |
>
>
>
`,
> props:["title"],
> methods:{
> test:function(){
> alert("组件中定义的函数")
> }
> }
> }
> );
> ~~~
### 子传父
> 通过子组件的按钮“调用”父组件的函数,通过函数传值.示意图
>
> 
~~~html
Document
从子组件传递过来的数据{{str1}} - {{str2}}
~~~
## 组件插槽
> 当我们自定义vue组件时,允许组件中的部分内容在调用组件时进行定义——插槽
> 1. 插槽的使用
>
> 在自定义组件时通过`slot`标签在组件的模版中定义插槽
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
> 2. 具名插槽
>
> 当组件中的插槽数量>1时,需要给组件中的slot标签添加name属性指定插槽的名字
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
> 3. 插槽作用域
>
> 定义组件时,将组件中的数据绑定到`slot`标签
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
> {{res.stus}}
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
# axios
> vue可以实现数据的渲染,但是如何获取数据呢?
>
> vue本身不具备通信能力,通常结合axios—一个专注于异步通信的js框架来使用
>
> - axios 数据通信
> - vue 数据渲染
## axios入门
> - 原生ajax --- 实现步骤复杂
> - jQuery 笨重
> - axios 简洁、高效,对RESTful支持良好
## 案例
> 1. get请求 - 查询所有
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
>
> 后端
>
> ~~~java
> @CrossOrigin
> @Api(value = "axios",tags = "axios交互接口")
> @RestController
> @RequestMapping("/axios")
> public class AxiosController {
> @ApiOperation("查询所有")
> @GetMapping
> public ResultVO hello(){
> Users users = new Users();
> users.setNickname("梦中人");
> users.setRealname("亲爱的小管");
> users.setUserBirth(new Date());
> return new ResultVO(200,"get请求",users);
>
> }
> }
> ~~~
> 2. get请求传参- 使用params
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
>
> 后端
>
> ~~~java
> @ApiOperation("传参")
> @GetMapping
> public ResultVO hello2(String name,Integer id){
> Users users = new Users();
> users.setNickname(name);
> users.setUserId(id);
> users.setUserBirth(new Date());
>
> return new ResultVO(200,"get请求接受参数",users);
> }
> ~~~
> 3. get请求传参-字符串拼接形式
>
> ~~~html
>
>
>
>
>
>
> Document
>
>
>
>
>
>
>
>
>
>
>
>
>
> ~~~
>
> 后端
>
> ~~~java
> @ApiOperation("传参")
> @GetMapping
> public ResultVO hello2(String name,Integer id){
> Users users = new Users();
> users.setNickname(name);
> users.setUserId(id);
> users.setUserBirth(new Date());
>
> return new ResultVO(200,"get请求接受参数",users);
> }
> ~~~
>
> 4. get请求传参restful
>
> ~~~js
> search2:function(name,id){
> axios.get('http://localhost:8888/axios/'+name+'/'+id).then(function(res){
> console.log(res.data.data)
> vm.user = res.data.data
>
> })
> }
> ~~~
>
> ~~~java
> @ApiOperation("传参")
> @GetMapping("/{name}/{id}")
> public ResultVO hello2(@PathVariable("name") String name, @PathVariable("id") Integer id){
> Users users = new Users();
> users.setNickname(name);
> users.setUserId(id);
> users.setUserBirth(new Date());
>
> return new ResultVO(200,"get请求接受参数restful",users);
>
> ~~~
> 5. post请求
>
> ~~~js
> search3:function(name,id){
> axios.post('http://localhost:8888/axios/'+name+'/'+id).then(function(res){
> console.log(res.data.data)
> vm.user = res.data.data
> })
> }
> ~~~
>
> 或者
>
> ~~~js
> search3:function(name,id){
> axios.post('http://localhost:8888/axios?name='+name+'&id='+id).then(function(res){
> console.log(res.data.data)
> vm.user = res.data.data
> })
> }
> 6. post请求注意点
>
> 如果前端发送参数是这样写的
>
> ~~~js
> search3:function(name,id){
> axios.post('http://localhost:8888/axios',{
> username:name,
> userId:id
>
> }).then(function(res){
> console.log(res.data.data)
> vm.user = res.data.data
>
> })
> }
> ~~~
>
> 那么后端接受数据的时候需要配合使用@RequestBody
>
> ~~~java
> @ApiOperation("传参")
> @PostMapping
> public ResultVO hello3(@RequestBody Users users){
> System.out.println(users);
>
> return new ResultVO(200,"get请求接受参数",users);
> }
> ~~~
>
> 7. delete请求
>
> ~~~js
> axios.delete('http://localhost:8888/axios',{
> params:{
> username:name,
> userId:id
> }
> 或者
> search4:function(name,id){
> axios.delete('http://localhost:8888/axios/'+name+'/'+id)
> .then(function(res){
> console.log(res.data.data)
> vm.user = res.data.data
>
> })
> }
> 或者使用字符串拼接
> ~~~
## 执行多个并发请求
~~~js
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
~~~
## 箭头函数
~~~js
//箭头函数
search4:function(name,id){
axios.delete('http://localhost:8888/axios/'+name+'/'+id)
.then(res=>{
console.log(res);
vm.user = res.data.data
})
}
~~~
# 路由router
> 单页面应用中使用场景居多
>
> router是由vue官方提供的用于实现组件跳转的插件
## 下载
> 路由插件的引用
**离线使用**
```html
```
**在线CDN**
```html
```
####
## 入门案例
~~~html
Document
~~~
## 动态路由匹配
> 通配符*可以匹配任意路径
例如:
- `/user-*` 匹配所有以`user-`开头的任意路径
- `/*` 匹配所有路径
`注意`如果使用通配符定义路径,需要注意路由声明的顺序
示例如下:
~~~html
Document
~~~
## 路由传参
> `/a/:id` 可以匹配 `/a/`开头的路径
>
> {{$route.params.id}}用于获取参数
示例如下
~~~html
Document
删除
~~~
> `通过props传参`
~~~html
路径A
~~~
## 嵌套路由
> 在一级路由的组件中显示二级路由
示例如下:
~~~html
Document
首页
首页-c1
首页-c2
~~~
## 编程式导航
### hello示例
~~~html
Document
~~~
### push参数
> 1. 字符串
>
> myrouter.push("/a");
>
> 2. 对象
>
> myrouter.push({path:"/a"})
>
> 3. 命名路由
>
> > ~~~js
> > // myrouter.push({
> > // name:"r1",
> > // params:{id:100}
> > // })
> > ~~~
> >
> > ~~~js
> > const myrouter = new VueRouter({
> > routes:[
> > {
> > path:"/a/:id",
> > name:"r1",
> > component:t1
> > }
> > ]
> > });
> > ~~~
> >
> > 给路由取个名字 - 路由的命名
> >
> > params传参 - 接受参数如下
> >
> > ~~~js
> > const t1 = {template:`index=>{{$route.params.id}}
`}
> > ~~~
> 4. url传参 相当于/a?id=101
>
> ~~~js
> // myrouter.push({
> // name:"r1",
> // query:{
> // id:101
> // }
> // })
> ~~~
>
> query传参,接受参数如下
>
> ~~~js
> const t1 = {template:`index=>{{$route.query.id}}
`}
> ~~~
> 5. restful传参 相当于/a/100
>
> ~~~js
> myrouter.push({
> path:"/a/200"
> })
> ~~~
>
> ~~~js
> routes:[
> {
> path:"/a/:id",
> name:"r1",
> component:t1
> }
> ]
> ~~~
>
> restful接受参数如下
>
> ~~~js
> const t1 = {template:`index=>{{$route.params.id}}
`}
> ~~~
示例代码如下:
~~~html
Document
~~~
### replace()
~~~js
功能与push一致,区别在于replace()不会向history添加新的浏览记录
~~~
### go()
> 参数为一个整数,表示在浏览器历史记录中前后/后退多少步 相当于`window.history.go(-1)`的作用
## 命名路由
> 命名路由:在定义路由的时候可以给路由指定name,我们在进行路由导航时可以通过路由的名字导航
示例如下
~~~html
Document
login
register
~~~
## 命名路由视图
> 如果在HTML中有一个以上的路由视图router-view,需要给router-view指定name,在路由中使用components映射多个组件根据name设置组件与router-view绑定关系
示例如下
~~~html
Document
t1
t2
~~~
## 重定向和别名
> 1. 根据路由路径重定向
> 2. 根据路由name重定向
> 3. 根据路由别名重定向
> 演示重定向
> 访问`/b`,重定向到`/a`
~~~html
Document
路径A
路径B
~~~
> 根据路由命名重定向
~~~js
routes:[
{
path:"/a",
name:"r1",
component:t1
},
{
path:"/b",
//根据路径重定向
//redirect:"/a"
//根据路由命名重定向
redirect:{name:"r1"}
}
]
~~~
> 根据路由别名重定向
~~~html
Document
路径A
路径B
路由别名
~~~
# ElementUI
> 官网-https://element.eleme.io/#/zh-CN
CDN在线引入
> ~~~css
>
>
>
>
> ~~~
离线方式 - 下载上述俩个文件,在html文件中引入即可