hello

考研数学到底怎么样才能上一百分?我来告诉你...

接下来我将以:

1
2
3
4
5
n月份~6月份

7月份~9月份

以及最后考试前两个月的时间段来描述具体如何备考

6月份之前(基础阶段):

这个时间段,是铁定的基础阶段,当然这个基础阶段是要打上引号的!所谓的基础阶段,并不是单纯地看本科阶段所学科目的书!而是从->本科书->到名师基础班的过渡。

也就是说,这个阶段最重要的事情就是:打好基础!越牢越好,切忌好高骛远,埋头苦干。

我复习的时候,看的老师:

高等数学:汤家凤(基础阶段)

线性代数:李永乐

基础阶段我建议,先看高等数学、线性代数的书,入门知识过一遍。能够掌握做课后习题的方法即可!不要做太难的题。

再看完高等数学、线性代数的书后,可以开始进入真正的考研数学基础班了。

还是建议数学汤家凤基础阶段紧跟!

值得一提的是,我非常建议

1
2
3
4
5
买汤家凤老师的《接力题集1800

汤家凤老师的高等数学讲义

关注汤家凤老师的微信、微博(关注寒暑假等假期的的直播课程)

对的,必买!!!

汤老师在课程中,会讲数学一、数学二、数学三的公共部分!

对于数学科目的独属部分以及题集的部分讲解,会在公众号以直播的形式播出!

在这里插入图片描述

给出自己基础阶段的复习方法:

高等数学跟汤家凤老师,线性代数跟李永乐老师即可。

☆ 第一、看对应的汤老师视频课程,但不要看多了,建议是看数集视频(看自己的状态)然后立马投入到1800题集的题海中!

过完一章后,最好是看看这一章学到了什么?可不可以以笔记的形式过一遍。

☆ 第二、《接力题集1800》,一定要关注、标黑错题。错题是很有价值的,到底自己是错在哪里?

详细看看答案,为什么汤老师要这么写?

如果不知道,那么,看了答案后,下次是否能够同步汤老师的思维! 看到该类型的题,就要想起:

1
2
3
4
5
6
7

这个题是涵盖哪些章节的知识(真正的考题都是综合题)

解该题的基本方法是什么?

在计算的过程:字迹工整!!思路清晰(对,恨不得给出注释那种)

在这里插入图片描述
为数不多还遗留下来的笔记了!

这个阶段不是很困难,但是一定要养成基本的解题素养!要知道常见的题型,以及常见的解法!

长时间的 Deliberate Practice(刻意练习) 即可!重复重复再重复。

第三、线性代数我想特别说明:

由于线性代数的抽象性!导致我们看了老师的课程内容 != 我们会做对应的题目,

这个时候我们要反复地看书、经典的例题!!!

  • 重难点绝对是:向量,方程组以及特征值、特征方程~(大题就是这么来的)

7/8月份~9月份(强化阶段):

高等数学:汤老师的1800题集、武忠祥老师的系统强化课

线性代数:李永乐老师的系统强化课

这个阶段就是决定自己到底能不能在数学科目有所突破!有所成长的关键时候了。

对,这个阶段要做大量的题,高难度的题,综合的题

请注意!我这里说的难题,是指贴合考研数学考场难度的题目

这个阶段我推荐:

1
2
3
4
5
6
7
汤老师的 《接力题集1800》强化篇 (除开基础篇即可)

武忠祥老师的《高等数学辅导讲义》

李永乐老师的《线性代数辅导讲义》

武忠祥、李永乐老师(好像今年他们去到不同的机构)的330重点题

☆ 强化班:听武忠祥老师的课程!!!

☆ 强化班:听线性代数,李永乐老师的课程!!

其他阶段的课程我不建议反复听,但是:

强化班的课程很有必要反复听!!!

听课的同时,一定要加强自己计算的能力!速度,准确度!

强化班不是基础班,是真正要上战场的预备课!练习的题目也都是大量高于考场的题目,不要畏难!

这个阶段是绝对适合做高难度的题目的。

  • 同时!基础阶段的标黑题目、多次错误题目也不能落下他们,因为很有可能是因为自己的哪一部分的基础不扎实

很有必要在这个阶段提一嘴!所谓的多种方法,其实在考场上是不适用的。

let’s put it another way,也就是说你会什么方法,就用什么方法解题。熟悉自己的解题方法,熟练自己的解题方法即可。

10月份国庆~12月份(冲刺阶段)

☆☆☆ 汤老师的套题

☆☆☆☆ 李永乐老师团队的套题

☆☆☆ 张宇老师的闭关修炼

☆☆☆☆☆ 李林老师的套题

在大量方法的灌输下,国庆节之后,我们可以开始做套题了!

☆☆☆☆☆ 李林老师的四套卷、八套卷

☆☆☆ 汤老师的卷子(不做参考,因为部分题源是1800题集上的题目)

其他的卷子没有做过..不予评价

请千万记住,不能按照自己做模块题目的思路去做题,一定要强迫自己在规定的时间2~2.5h内做完卷子!!

请千万记住,做卷子的目的不是,所有的题目都要做出来!而是拿到对于这张卷子,自己能拿到的分数!

否则,只会懊悔自己,为什么自己的分数不如自己所愿!

就像我的好研友李总说的那样,你上岸又不是一定要数学150分

说的很好,每个人对数学的理解能力不同,要求自己做对能做对的题目(这点很重要)

对于实在不会或者算不出来的题目,字迹要工整、思路要清晰,是老师给你评分,不是你自己的思路给你自己评分!

一定要老师知道,你每一步的意义。老师也是 按点给分,按步骤给分!

同时,如果有条件。可以看看数学张宇老师的《闭关修炼》,为的是拓展自己的数学思维!

注意!越是临近考试,越不能放弃考研数学的本质!刷题。结合强化阶段的题目以及做套题的错题

考研数学真题>模拟套题

刷题最开始的阶段,请选择 x年到2010年,x为自己决定起点年份的卷子!

对于近年的真题卷子,一定要珍惜不能浪费!

  • 建议整理真题、部分精彩的模拟题的错题!反复阅读。

那么,到了最后的冲刺阶段:

是一定要多看李林老师的《四套卷》、《六套卷》

By the way 直到考试前的早上!我还在看六套卷的选择题。结果你懂的

上考场的具体答题顺序建议:高等数学、线性代数的顺序做题方式。

Ajax请求PostAndGet

Ajax的Get与Post方法

请注意,必须引入JQuery

CDN代码如下:

1
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>

Get方法

请注意GET方法一般用于从后台中获取数据,而不是提交数据

默认是GET方法,速度很快。但是由于数据将直接以localhost:8080?data1=111&data2=222的形式

出现在浏览器的地址栏中,

因而Get方法一般不用于:敏感、隐私的数据传输

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var id = $("input[name='editor']").val() 
$.ajax({
//后台的请求路径 一般在@Controller层中添加相关注解
//注解一:@RequestMapping(value="/show_paper")或者指定@GetMapping(value="/show_paper")
url:"show_paper",
data:{"Id":, id},
type:"GET",
//注解二:由于指定返回类型为JSON数据
//@ResponseBody
dataType:"JSON",
success:function(result){
//后台的回调函数中 result中可以找到 后台返回的JSON数据
console.log(result);
},
error:function () {
alert("抱歉,请求失败,请重新发出请求!")
}
});

1. 在SpringBoot中,@RestController=@Controller+@ResponseBody

2. 使用Get方式请求时,后台SpringMVC用@RequestParam(“Id”)来获取

Post方法

与Get方法不同的是,Post方法一般用于向服务器提交数据。而不是获取数据!

因此,我们可以将需要隐私处理的数据以POST方式以服务器交互:比如账户密码,业务逻辑数据等等

1. 网页中没有form标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var username = $("input[name='username']").val() 
var password = $("input[name='password']").val()
$.ajax({
//对应的Controller 指定登录
url:"login",
//字符串拼接的方式添加参数 后台可用MVC捕捉 或创建Bean对象
data:{"username":username , "password":password},
type:"POST",//HTTP请求方式
dataType:"JSON",//返回值的类型。
success:function(result){ //请求事件成功的回调函数
console.log("JSON:"+result);
},
error:function(data){//处理页面出错以后执行的函数
console.log(data);
window.location.replace("./index.jsp");
}
});

1. 后台函数参数中可以使用与前端同名的变量

1
public void fun(String username, String password)

2. 后台可以使用Bean对象 User类 其中属性与前端参数同名

UserController.java

1
public void fun(User user)

User.java

1
2
3
4
5
6
7
public class User{
private Integer id;
private String username;
pruvate String password;

...省略GET、SET方法
}

2.网页中有form标签(更便捷)

关键代码

1
data:$("#form").serialize(),

解释:

  1. 给网页中的form表单一个id=”form”

  2. 在进行AJAX请求时 找到这个表单

  3. 对这个表单中的数据进行序列化serialize()

注意:后台用对象User来接收,并且前端name中的值需要与Bean对象User中的private属性一一对应

1
2
3
4
5
6
7
8
$.ajax({
url:"addUser",
type:"POST",
data:$("#form").serialize(),
success:function (result) {
showData(result);
}
});

VUE学习笔记-3-SpringBoot+SpringJPA+Vue 开发实战

原生VUE实战(查询数据)(含SpringBoot+Vue)

1.创建VUE项目

在命令行中输入

1
vue ui

在这里插入图片描述

2.进入dashboard中 创建项目

在这里插入图片描述

3.进入VUE 工程管家创建工程

在这里插入图片描述

修改以下参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建完之后就可以了。

4.从IDEA中导入项目编写前端代码

打开IDEA->导入项目….

  1. 安装Vue.js插件
  2. 修改JavaScript语言为ECMAScript 6
  3. 在控制台中输入npm run serve来启动项目

*******************

(开发从这里开始)VUE前端项目的结构图

项目结构图如图所示:
在这里插入图片描述
通过结构图我们可以知道:

  • App.vue 是网页的主界面,页面中包括许多组件 component
  • 其中Home、About都是导航栏,但注意我们导航至Home与About并不代表像传统意义那样,我们去打开一个新的页面。而是说,我们在页面上加载不同来源的内容

具体含义,如图所示:

在这里插入图片描述

1
2
3
4
5
6
7
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</template>

在上述代码中,我们可以看出router-link标签负责导航栏 to表示导航路径
而具体的路径配置是交给项目结构中的
router下的index.js来配置

index.js中的关键代码如图
在这里插入图片描述
import代表从那个vue页面中导入相关组件

而在routes中具体配置相应的路径,名字,以及组件的名字

在这里插入图片描述

  1. 这里的path需要与前端页面vue中router-link中的to属性参数一一对应
  2. name可以不填写,但最好与组件名一致
  3. component代表组件 这里的component需要与import导入语句后面一致

而对于VUE3.0,我们建立导航可以用新的写法:

import语句可以省略,除了写path与name参数之外,
我们的component参数可以变成:

1
component:()=>import('../views/About.vue)

创建SpringBoot项目

添加以下依赖:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1. Lombok
2. Spring Web
3. Spring Data JPA
4. MySQL Driver

以上四个依赖

1.资源文件中添加数据库文件连接信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
datasource:
url: jdbc:mysql://localhost:3306/vuetest?characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 123456

jpa:
show-sql: true
properties:
hibernate:
format_sql:true
server:
port: 8181
  1. 连接数据库信息
  2. JPA打印SQL 格式化SQL
  3. 端口8181 避免占用(vue的端口与后台的端口占用)

建立实体类

User类(注意使用@Entity @Data注解 @Id放在主键属性上)

值得注意的是,类中的每个属性,在首字母小写后-必须等于数据库表中的字段名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@Data
public class User {
//默认是类名首字母小写 与数据库中的表进行对应

@Id
private Integer id;
private String username;
private String password;
private String email;

}

ApiResponse 后端前台通用-交互类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

import lombok.Data;

@Data
public class ApiResponse{

private int code;
private String message;
private Object data;

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}
}

建立Repository层或称DAO层

UserRepository类 extends JpaRepository<User, Integer>

(其中User是对应的类 Integer是主键)利用这种方法,可以避免写一些比如1.查询一条数据2.查询全部数据3.根据主键查询数据…
已经封装好了 常见的DAO层操作

1
2
3
4
5
6
7
8

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

//继承已经封装好了的 JPA不用自己去写简单的 增删改查接口
public interface UserRepositery extends JpaRepository<User, Integer> {

}

建立RepositoryTest测试类 先看看能不能获得到数据库的数据!

  1. 在类名上右键
  2. Goto中选择test
    在这里插入图片描述
  3. 命名UserRepositeryTest
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    @SpringBootTest
    class UserRepositeryTest {

    @Autowired
    private UserRepositery userRepositery;

    @Test
    void findAll(){
    System.out.println(userRepositery.findAll());
    }
    }
  4. 点击函数名左边的运行!测试看控制台能否读取数据库数据。

建立Service层以及对应的Impl实现类

值得注意的是 注解@Service应加在实现类上

UserService接口

1
2
3
4
5
6
7
8
import com.example.demo.entity.User;
import org.springframework.stereotype.Service;

import java.util.List;
public interface UserService {
List<User> showAllTheUsers();
}

UserServiceImpl实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepositery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepositery userRepositery;

@Override
public List<User> showAllTheUsers() {
return userRepositery.findAll();
}
}

建立Controller层

UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.example.demo.entity.ApiResponse;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping(value = "/user")
public class UserController {

@Autowired
private UserService userService;

@GetMapping("/show")
public ApiResponse showAll(){
ApiResponse apiResponse = new ApiResponse();
List<User> users = userService.showAllTheUsers();
apiResponse.setData(users);
apiResponse.setMessage("返回成功!");
return apiResponse;
}
}

值得注意的是:@RestController = @Controller + @ResponseBody后台从数据库中查询到的数据
以XML或者JSON的格式,返回给前端。

解决端口跨域的问题

由于我们修改了SPRINGBOOT的端口为8181 而VUE默认是8080因此,我们需要对SpringBoot做一个配置!

新建config.CorsConfig类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*");
config.setAllowCredentials(true);
// 允许服务端访问的客户端请求头
config.addAllowedHeader("*");
// 允许访问的方法名,GET POST等
config.addAllowedMethod("*");
// 对接口配置跨域设置
source.registerCorsConfiguration("/**" , config);
return new CorsFilter(source);
}
}

到此为止,后台的代码基本算是完成了!
接下来开始编写

*******************

(前端代码开始)User导航栏

修改App.vue文件中的template标签为

1
2
3
4
5
6
7
8
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>|
<router-link to="/user">User</router-link>
</div>
<router-view/>
</template>

同时在router文件夹中的index.js文件中 配置router导航映射(见文章前部分内容!)

第一种方式:适用于VUE2(显式声明)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import User from '../views/User.vue' //建立VUE页面与组件的映射

const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user',
name: 'User',
component: User //从上方的import User中建立映射
}
]

第二种方式:建立隐式映射

1
2
3
4
5
6
7
8
//注释掉上方的import User from '../views/User.vue' 

//但是下方变成:
{
path: '/user',
name: 'User',
component: ()=>import('../views/User.vue') //边声明组件 边建立映射
}

创建User.vue 具体显示内容

在views文件夹下创建User.vue文件:

Style CSS样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style scoped>
table{
font-size:25px;
}
table{
table-layout:fixed;
empty-cells:show;
border-collapse: collapse;
margin:0 auto;
}
td{
height:20px;
}
</style>

JavaScript 利用axios与后台交互

第一步、添加axios插件(并修改一些内容)

首先,在命令行中输入

1
vue add axios

然后找到项目结构图中的plugins文件夹下面的axios.js
粘贴以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
"use strict";

import Vue from 'vue';
import axios from "axios"

// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

let config = {
// baseURL: process.env.baseURL || process.env.apiUrl || ""
// timeout: 60 * 1000, // Timeout
// withCredentials: true, // Check cross-site Access-Control
};

const _axios = axios.create(config);

_axios.interceptors.request.use(
function(config) {
// Do something before request is sent
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);

// Add a response interceptor
_axios.interceptors.response.use(
function(response) {
// Do something with response data
return response;
},
function(error) {
// Do something with response error
return Promise.reject(error);
}
);
export default _axios

第二步、引用axios并发起get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import axios from "../plugins/axios"; //引用axios

export default {
name: "User",
data(){
return{
// 具体的变量
msg: 'Hello, Vue!',
users:[]
}
},
created(){ //当网页准备就绪时
const _data = this //利用这个this好使得在回调函数中 调用回调函数外的data中的数据
axios('http://localhost:8181/user/show').then(function (response) {
_data.users = response.data.data //将controller返回给后台的data 赋给data中的数组
}) //跟ajax一样 直接请求8181端口下的请求路径 注意 已经配置了跨域!不用担心
}
}
</script>

第三步、将数据显示在网页中

template HTML内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<!--template中写html代码 且只能有一个根div节点-->
<div>
<table>
<tr>
<td>id</td>
<td>用户名</td>
<td>密码</td>
<td>邮箱</td>
</tr>
<tr v-for="user of users">
<!--利用for循环 加载data中users数组中数据-->
<td >{{user.id}}</td>
<td >{{user.username}}</td>
<td >{{user.password}}</td>
<td >{{user.email}}</td>
</tr>
</table>
</div>
</template>

到此为止。一个简单的查询数据库所有数据的请求就完成了

项目效果图如下:
在这里插入图片描述

VUE学习笔记-基础语法及相应应用-1-基本语法

# Vue开头好戏-小案例 ## Hello World
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>
<script>
Vue.createApp({
template: '<div>Hello World</div>'
}).mount("#app")
</script>
</html>

面向数据编程->实现计时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计数器</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>

<script>
Vue.createApp({
data(){
return {
counter:1
}
}, //需要一个mounted方法 自动执行
mounted(){ //页面渲染完 就自动执行
setInterval(()=>{
this.$data.counter += 1
}, 1000) //周期执行
},
template: '<div>{{counter}}</div>' //字面量 双括号 放JS表达式或者变量
}).mount("#app")
</script>
</html>

mounted()表示当文档加载时 就执行该函数

data(){}中存放类似 全局数据

template:放入全局数据 取值

绑定数据&事件->编写方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>象牙山洗脚城</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>

<script>
Vue.createApp({
data(){
return {
content:"",
num:0,
Menu:'真空套餐 帝王套餐 夏日套餐 学生套餐',
isShowMenu: false //标志不展示
}
},
methods:{
welcomeBtnClick(){
this.content = "欢迎光临, 贵宾" + ++this.num + "位"
},
byeBtnClick(){
if(parseInt(this.num) == 0){
alert("操作有误,无人可离.")
return;
}
this.content = "还剩贵宾" + --this.num + "位, "+"欢迎下次光临!"
},
hideBtnClick(){
this.isShowMenu = !this.isShowMenu
}
},
template: //波浪 代表多行 v-on:click="" 表示对某个标签绑定某个函数
//{{content可以看做是数据绑定 从data中取出的数据}}
`
<div>
<div>{{content}}</div>
<button v-on:click="welcomeBtnClick">有顾客来</button> &nbsp;
<button v-on:click="byeBtnClick">顾客离开</button>
<div>
<div v-if="isShowMenu">{{Menu}}</div>
<button v-on:click="hideBtnClick">显示/隐藏套餐</button>
</div>
</div>
` //字面量 双括号 放JS表达式或者变量
}).mount("#app")
</script>
</html>

data(){} 中可以放多个数据

template: ``波浪中可以放多行的 前端代码

v-on:click=”function” 指定点击事件

当变量boolData为真时 变量data才会显示出来

parseInt(val) 可以将val值转换为数值型数据

for循环增加佳丽(技师)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>for循环遍历佳丽</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>

<script>
Vue.createApp({
data(){
return {
waitresses: ['小红', '小丽', '小芳']
}
},
methods:{

},
template:
`
<div>
<div>
<ul>
<li v-for="(waitress, index) of waitresses">[{{index}}]{{waitress}}</li>
</ul>
</div>
</div>
`
}).mount("#app")
</script>
</html>

v-for=”(item, index) of list” 属性 代表从数组list中遍历每个item且附上索引 index

将手动输入的值 添加佳丽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手动输入增加佳丽数据</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>

<script>
Vue.createApp({
data(){
return {
waitresses: ['小红', '小丽', '小芳'],
inputWaitress:''
}
},
methods:{
addWaitress(){
this.waitresses.push(this.inputWaitress)
this.inputWaitress = ''
}
},
template: //波浪 代表多行 v-on:click="" 表示对某个标签绑定某个函数
//{{content可以看做是数据绑定 从data中取出的数据}}
`
<div>
<div>
<input v-model="inputWaitress" /> <button v-on:click="addWaitress">增加技师</button>
</div>

<div>
<ul>
<li v-for="(waitress, index) of waitresses">[{{index}}]{{waitress}}</li>
</ul>
</div>
</div>
` //字面量 双括号 放JS表达式或者变量
}).mount("#app")
</script>
</html>

v-model=”stringVal” 定义输入的值 传给变量stringVal

同时给按钮绑定函数 将对应输入的值 尾添至数组中(同时输入框值清空)

Vue重要概念:组件式开发

什么是组件?组件就像是 “网页窗体中-一个又一个不同的Section” 网页上所看到的任何东西 都可以写成组件

比如在上个例子中的->增加佳丽 就可以利用这种思想来-> 组件式开发

把可以抽出来或者说可能重复被用到的代码块 抽离出来

小案例:组件式开发-洗脚城系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手动输入增加佳丽数据</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>

<script>
//app是一个可以将自己的内容 挂载在id为app区域上的变量
const app = Vue.createApp({
data(){
return {
waitresses:['小红', '小芳', '小丽'],
inputValue:' '
}
},
methods:{
add(){
this.waitresses.push(this.inputValue)
this.inputValue = ' '
}
},
template: `
<my-title/>

<input v-model="inputWaitress"/>
<button v-on:click="add">添加佳丽</button>

<div>
<ul>
<my-waitress
v-for="(item, index) of waitresses"
v-bind:item="item"
v-bind:index="index"
/>
</ul>
</div>
`
})

app.component('my-title',{
template:'<h1 style="text-align=center">洗脚城</h1>'
})

//抽离出上个例子中 动态地渲染 参数为props列表中的值
app.component('my-waitress', {
props:['item', 'index'],
template:`<li>[{{index}}] {{item}}</li>`
})

app.mount("#app")
</script>
</html>

VUE的组件式开发之总结:

  1. 在代码中,首先将app作为一个const常量(不可更改) 创建出来-> const app = Vue.createApp({})
  2. 然后编写这个app常量的各个组件- app.component(‘name’,{data})
  3. ….重复编写组件
  4. 最后选择把这个app挂载在 网页中的某个区域(可以id选择器,class选择器等..) app.mount(“#id_name”)

重要属性:

1.组件中的template:’’/ ``分别填写单行、多行HTML

2.v-on:click=”fun_name” 绑定单击事件

3.v-for=”(item, index) of list” 利用for循环遍历数组

4.v.bind->绑定这个自定义组件中的props参数数组中的参数

VUE的createApp()方法 与 mount()方法讲解

1
2
const app = Vue.createApp({})
app.mount("#app")
  1. createApp就是Vue创建一个应用
  2. mount方法就是挂载到某一个DOM节点

VUE的设计模式:mvvm->model, view, viewModel

Vue的编程设计模式应该叫做mvvm的设计模式。什么叫做mvvm?它首先是面向数据的编程,程序中定义了数据,然后定义了模板,Vue就可以把数据和模板自动进行关联。最后挂载到真实的DOM上,展示给用户。

1
mvvm解释: 第一个m代表model数据,第一个v代表view视图,最后两个字幕vm代表viewModel视图数据连接层。

小案例认识 “数据” “模板” “数据视图连接层”

1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = Vue.createApp({
data() {
return {
message: 'vincent99013.github.io' //1.在这里定义了数据,也就是`model`数据
}
},
template: "<h2>{{message}}</h2>" //2.在这里定义了模板,也就是`view`,
//定义后的自动关联,就叫做`vm`,viewModel数据视图连接层。
})
const vm = app.mount("#app")
</script>
  1. data(){} 中放数据
  2. template:”” 中放模板view 即HTML代码
  3. 使得数据与视图之间得以连接

model数据,是我们自己定义的,view模板也是我们自己定义的,但是vm是Vue自动给我们关联的。

当我们明白了什么是mvvm后,你就知道为什么我们给根组件起名vm了。

当我们获取了vm根节点后,其实就可以操作里边的数据了。比如在控制台中输入下面的代码:

1
vm.$data.message = 'vincent'

如果在app里 我们使用this指针操作data数组中某个变量

自动执行函数的理解

说起自动执行函数,还要从被动执行函数说起。比如给网页某一个元素一个点击事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: '弹窗成功'
}
},
methods: {
clickFun() {
alert(this.message)
}
},
template: `<div>
<button v-on:click="clickFun">点击我弹窗(被动事件)</button>
</div>`
})
app.mount("#app")
</script>
</html>

在面向数据编程中,此时给该按钮加入点击事件。只有当该按钮被点击时,事件才会被触发。这就是被动函数的概念!

而对于自动执行函数..不需要相应的点击事件才触发

自动执行函数-> mounted()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: '弹窗成功'
}
},
mounted(){
alert('自动弹出的内容')
},
methods: {

},
template: `<div>
<h1>不用点击 自动弹窗</h1>
</div>`
})
app.mount("#app")
</script>
</html>

在网页加载完成后,自动进入mounted函数中,即自动执行里面的代码块。

(很重要!)VUE的所有生命周期

在这里插入图片描述

重要的四个基本生命周期函数

  1. beforeCreate(): 在实例生成之前会自动执行的函数
  2. created(): 在实例生成之后会自动执行的函数
  3. beforeMount(): 在模板渲染完成之前执行的函数
  4. mounted(): 在模板渲染完成之后执行的函数

那么,现在用具体的例子来演示一下这四个基本周期函数吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: '弹窗成功'
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
methods: {

},
template: `<div>
<h1>不用点击 自动弹窗</h1>
</div>`
})
app.mount("#app")
</script>
</html>

浏览器的控制台:
在这里插入图片描述
可以看到:执行流程是: beforeCreate -> created -> beforeMount -> mounted

beforeUpdate和updated生命周期函数

这两个周期函数是在VUE中的data数据发生变化时,才会被执行,一个是在变化之前,一个是在变化之后。

用一个改变data中变量message的值的例子来说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo7</title>
<script src="https://unpkg.com/vue@next"></script>
</head>

<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
message: '初始值'
}
},
beforeUpdate(){
console.log('当前的值未被改变!')
},
updated(){
console.log('当前的值已被改变!')
},
methods: {
clickFun(){
this.message = '恭喜您,成功更改message的值!'
}
},
template: `<div>
<div>{{message}}</div>
<div>
<button v-on:click="clickFun">点击改变data中的数据值</button>
</div>
</div>`
})
app.mount("#app")
</script>
</html>

beforeUnmount和unmounted周期函数

这两个生命周期函数是在VUE销毁时自动执行的函数,一个是销毁前执行,一个是销毁后执行。
beforeUnmount(): 当VUE应用失效时,会自动执行。
unmounted():当VUE应用失效,且DOM完全销毁之后,会自动执行。

代码演示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

<script>
const app = Vue.createApp({
data() {
return {
message: '初始值'
}
},
beforeUnmount(){
console.log('beforeUnmount!')
},
unmounted(){
console.log('unmounted!')
},
methods: {
clickFun(){
this.message = '恭喜您,成功更改message的值!'
}
},
template: `<div>

</div>`
})
app.mount("#app")
app.unmount()
</script>

可以看到,页面在调用unmount函数前后,控制台会打印:
在这里插入图片描述
app.unmount()函数执行后,在beforeUnmount()方法里,DOM还是有内容的,然后到了unmounted方法中,就已经没有任何的DOM内容了。

VUE中最重要的概念-八大生命周期

创建,挂载,更改,非挂载

记住八大生命周期,可回想安卓中的生命周期函数!
各有两个un-XXxx-ed

如图所示:
在这里插入图片描述

插值表达式与v-bind数据绑定

在之前的代码类似 content 这种,正确叫法是 插值表达式 当然也可以叫做 字面量

JSP中从后台SpringMVC中的ModelAndView中存储的数据 利用EL表示JSP网页取值一样

1
2
3
4
5
6
7
8
9
<script>
const app = Vue.createApp({
data() {
return {message: '数据'}
},
template: "<div>{{message}}</div>"
})
app.mount("#app")
</script>

在以上代码中,我们利用面向数据编程的插值表达式 在模板template当中显示出data数组中的数据。

但有时可能我们需要显示的一些数据变量,中含有HTML标签,我们想在网页中以标签的形式显示出来而不是字符串的内容(即不会把<>这样的内容也显示出来),这样我们就需要用到 v-html=”message” ,需要注意的是,我们需要用多行代码块`而不是单行代码块”

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
<script>
const app = Vue.createApp({
data() {
return {
message: '<i>斜体的内容(不含标签)<i>'
}
},
template: `<div v-html="message"></div>`
})
app.mount("#app")
</script>

VUE中的数据双向绑定

在模板template中引用的data数据,被绑定到模板对应mount挂载的网页区域中。当data中的数据发生改变时,对应网页中显示出来的内容也会发生改变。这就是双向数据绑定,而有时我们只需要这样的数据,让它只在第一次渲染出来,而之后不再跟随data中的数据的值变化而变化。这样的思想,我们可以用v-once属性完成!

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

<script>
const app = Vue.createApp({
data() {
return {
message: 'message数据的初始内容'
}
},
methods:{
fun(){
this.message = '更改数据中...'
}
},
template: `
<div>
<div v-once>只会显示初始数据:{{message}}</div>
<div><button v-on:click="fun">点击我但不会改变message的初始值</button> </div>
</div>`
})
app.mount("#app")
</script>

在上述代码中,我们无论点击多少次按钮,带有v-once属性的div中的字面量数据,绝对不会再次渲染新值

插值表达式中-使用JS代码(三目运算)

比如我们要实现这么一个功能:这里有一个灯(不是开着的,就是关着的),我们利用嵌入JS代码至插值表达式中,实现开关灯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const app = Vue.createApp({
data() {
return {
Switch: true //我们默认灯是开着的
}
},
methods:{
fun(){
this.Switch = !this.Switch //点击一下 就改变一下灯的状态
}
},
template: `
<div>
<div>状态:{{Switch? '灯已关闭': '灯已打开'}}</div>
<div><button v-on:click="fun">开关灯</button></div>
</div>`
})
app.mount("#app")
</script>

在某些情况下,我们需要这种“非真即假”的场景,来为我们改变一些元素的状态!

v-bind 给某个元素绑定属性

假设我们data数组中有message这个数据,而我们想要某个元素有一个title属性,同时这个title的值为message的值。(联想我们插入HTML标签,而不是标签变成了字符串)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容'
}
},
template: `
<div v-bind:title = "message" > {{message}} </div>`
})
app.mount("#app")
</script>

此时我们将鼠标移到对应的数据内容上,悬停出来的内容即为title,而title的值也是数据内容。说明,我们利用v-bind属性给这个元素赋值了message变量中的内容。
在这里插入图片描述

v-on 的基本用法及简写

v-on 是用来绑定响应事件的,在之前提到:

1
2
3
4
methods:{
alert('显示数据中...')
},
template:" <button v-on:click="fun">点击我弹窗显示数据</button> "

现在可以利用@click来代替:v-on:click事件

也就是说 @事件=v-on:事件

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容'
}
},
methods: {
fun(){
alert(this.message)
}
},
template:
`
<button @click="fun">点击我弹窗显示数据</button>
`
})
app.mount("#app")
</script>

效果图如下:
在这里插入图片描述

v-bind绑定的基本用法及简写

与v-on一样,v-bind也可以用来绑定属性。基本用法是:

:title=”val_name(变量名)”,即绑定title为data中的变量名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容',
title: ':title生成的按钮标题'
}
},
methods: {
fun(){
alert(this.message)
}
},
template:
`
<button @click="fun" :title="title">点击我弹窗显示数据</button>
`
})
app.mount("#app")
</script>

效果图如下:
在这里插入图片描述

模板动态参数

属性动态参数

对于绑定的title属性,我们可以看成是一个动态变量parameter里面,赋值为title,title的值为相应的变量名。

所以我们可以利用这样的形式来写:
简写bind函数时,我们不用title(:title),我们把title抽离出来,看成是一个parameter变量的值

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容',
name: 'title',
val: '标题值'
}
},
methods: {
fun(){
alert(this.message)
}
},
template:
`
<button @click="fun" :[name]="val">点击我弹窗显示数据</button>
`
})
app.mount("#app")
</script>

事件动态绑定

与属性动态绑定一样,我们可以将点击这个动作抽象成一个变量event,其值为click作为参数。对应的值不变!仍为data中的变量。

1
<button @[event]="fun" :[name]="val">点击我弹窗显示数据</button> 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容',
name: 'title',
val: '标题值',
event: 'click'
}
},
methods: {
fun(){
alert(this.message)
}
},
template:
`
<button @[event]="fun" :[name]="val">点击我弹窗显示数据</button>
`
})
app.mount("#app")
</script>

通过事件绑定,属性绑定,这样我们可以动态切换对应的事件。只需要更改this.event以及this.parameter的值

VUE阻止默认事件(比如表单的默认提交)

最常见的事件就是阻止表单的默认提交,比如在表单的数据还没有完全验证成功情况下。是必须阻止表单默认提交的!

通常我们的代码会像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容',
name: 'title',
val: '标题值',
event: 'click'
}
},
methods: {
handleButton(e){
e.preventDefault()
}
},
template:
`
<form action="https://www.baidu.com">
<button type="submit" @click="handleButton">提交数据</button>
</form>
`
})
app.mount("#app")
</script>
  1. 我们给一个自定义的阻止事件handleButton(e)
  2. 这个e看做是触发事件的源按钮 看做是哪一个按钮触发了这个事件,就指哪一个按钮
  3. 调用**e.preventDefault()**函数以阻止默认事件

对于那些经常要做的阻止操作而言,这种方法太低效了。

因而,VUE给我们提供了一个模板修饰符,直接可以阻止默认行为,写法如下:

1
2
3
<form action="https://www.baidu.com" @click.prevent="handleButton">
<button type="submit">提交<button>
</form>

上述代码中:@click.prevent=”阻止之后 转而进入的事件
完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
const app = Vue.createApp({
data() {
return {
message: '数据内容',
name: 'title',
val: '标题值',
event: 'click'
}
},
methods: {
handleButton(){
alert('拦截成功...')
}
},
template:
`
<form action="https://www.baidu.com" @click.prevent="handleButton">
<button type="submit" >提交数据</button>
</form>
`
})
app.mount("#app")
</script>

VUE中模板的条件判断 v-if

前面我们提到了三目运算符,结合例子说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
const app = Vue.createApp({
data() {
return {
num: 10,
inputNum:'',
flag: false,
message: ''
}
},
methods: {
handleButton(){
this.message = (parseInt(this.inputNum)>this.num)? '你输入的数比10大': '并没有比10大'
}
},
template:
`
<input v-model="inputNum"/>
<button @click="handleButton">查询</button>
<div>{{message}}</div>
`
})
app.mount("#app")
</script>

当输入的数字大于10或者小于10时 都会提示

现在从这种三目运算符到v-if的过渡:

如果有这么一个场景,当输入的值为“蓝色”时,标签的背景是蓝色,如果是红色,背景是红色。

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

<script>
const app = Vue.createApp({
data() {
return {
num: 10,
inputValue:'',
flag: false,
message: ''
}
},
methods: {
handleButton(){
this.message = this.inputValue
}
},
template:
`
<input v-model="inputValue"/>
<button @click="handleButton">查询</button>
<div v-if="message=='红色'" class="red">这片区域是红色</div>
<div v-if="message=='蓝色'" class="blue">这片区域是蓝色</div>
`
})
app.mount("#app")
</script>

<style type="text/css">
.red{color:red}
.blue{color:blue}
</style>

VUE中的computed域

对应一般的方法而言,若页面重新渲染;则相应需要计算的方法,会再进行一次计算。

比如,现data数据中有val,和content两个变量;
有一个涉及val变量的方法,计算val*10的值。

现在若在普通方法中,更改同在data中的变量content,那么val变量会重新计算一遍。

现在将代码放入computed域中,现在更改content的值时涉及val的方法不会再执行

VUE中的watch域

Watch译为监听,则我们可以将一些需要监听数据变化,并对这些变化作出一些操作的数据源
放在Watch域中。而且可以获取到 改变前的值&改变后的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
const app = Vue.createApp({
data(){
return{
num: 1
}
},
computed:{

},
methods:{
fun(){
this.num--;
}
},
watch:{
num(current, prev){
alert("你的num数据从" + prev + "变化到了" + current)
}
},
template:`
<div>{{num}}</div>
<div><button @click="fun">点我减一</button></div>
`
})
const vm = app.mount("#app")
</script>

VUE中的模板样式绑定详细讲解

单个样式动态绑定

现有三种样式,我们动态地引用这三个样式:

1
2
3
.red{color:red}
.green{color:green}
.back{background-color:orange}

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

<script>
const app = Vue.createApp({
data(){
return{
className:'red'
}
},
template:`
<h1 :class="className">初始字体颜色为红色</h1>
<h2>您可以通过在控制台中修改vm.$data.className来动态引用class</h2>
`
})
const vm = app.mount("#app")
</script>

<style>
.red{color:red}
.green{color:green}
.back{background-color: orange;}
</style>

其中利用动态绑定:class=”className”,而在data中的变量className值代表真正的class值
因此,我们可以在控制台中修改:vm.$data.className=’green’

使得我们在style标签中的CSS样式能够生效。

对象形式绑定多个样式

在上个例子中,我们有字体颜色.red类,有背景颜色.back类
现在我们想要绑定这个DOM元素,既让它有样式.red,又让它有样式.back
则我们可以利用一个自定义对象classObject,将想要生效的样式置为true

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const app = Vue.createApp({
data(){
return{
className:'red',
classObject:{'red':true, 'back':true}
}
},
template:`
<h1 :class="cl assObject">初始字体颜色为红色</h1>
<h2>您可以通过在控制台中修改vm.$data.className来动态引用class</h2>
`
})
const vm = app.mount("#app")
</script>

其中,我们看到,相应的red、back样式类都为true

VUE中的for循环(以及如何避免重新渲染)

在之前的for循环,我们每次都是重新渲染页面:
如果有含初始数据的数组,我们只需要重新渲染“新数据”的内容
每次添加数据 我们可以避免重新渲染之前的已有数据

利用 :key=”index+item” 绑定key属性!

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
const app = Vue.createApp({
data(){
return{
list:['初始值']
}
},
methods:{
fun(){
this.list.push('尾添数据')
}
},
template:`
<button @click="fun">点我</button>
<ul>
<li v-for="(item, index) in list" :key="index+item">
[{{index}}]{{item}}
</li>
</ul>
`
})
const vm = app.mount("#app")
</script>

VUE中的事件对象-event

无参函数

tips: 我们用event.target看到事件触发源

含参函数

当我们有参数时,调用函数若想用event

此时应用click(para1, para2 …, $event)

VUE中一个按钮绑定两个方法

有时,我们可能需要同时对一个按钮绑定一个事件。并同时执行两个方法fun1与fun2

**@click=”fun1(), fun2()”**可以完成这个功能。会顺序执行这两个方法!

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const app = Vue.createApp({
data(){
return{
}
},
methods:{
fun1(){
alert("小明取走100元")
},fun2(){
alert("银行少了100元")
}
},
template:`
<button @click="fun1(), fun2()">点我交易</button>

`
})
const vm = app.mount("#app")
</script>

VUE中的事件修饰符

VUE中有六种常见的事件修饰符他们分别是:

  1. stop
  2. prevent
  3. capture
  4. self
  5. once
  6. passive

停止事件的冒泡机制-事件修饰符@click.stop

所谓冒泡机制(就像水里面的泡泡,DOM树中的事件就像泡泡一样向上逐个被捕捉!)

比如网页结构是!

1
2
3
4
<body>
<h2>
<button>
...省略闭合标签

那么此时给button加的事件,会自底向上得逐个被各个标签捕获
也就是说,若给h2添加点击事件,给button添加点击事件。

最终根据冒泡机制,会执行h2的点击事件
完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
const app = Vue.createApp({
data(){
return{
count: 1
}
},
methods:{
divClick(){
alert('最终被标签捕捉到了!')
},
btnClick(){
this.count++
console.log(this.count)
}
},
template:`
<div @click="divClick">
<button @click="btnClick">点击我体验冒泡机制</button>
</div>

`
})
const vm = app.mount("#app")
</script>

而我们可以用**@click.stop=”btnClick”**给下边的按钮添加,避免它往上冒泡被捕获到。

prevent修饰符:阻止默然行为的修饰符@click.prevent

例如阻止form表单的默认提交行为。

1
2
3
<form @click.prevent="handleButton">

</form>

上述代码可以避免自动form自动提交,转而转向handleButton函数

capture修饰符,冒泡反方向(自顶向下)

once修饰符,事件只执行一次

once修饰符修饰的事件,只会执行一次。

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
const app = Vue.createApp({
data(){
return{
count: 1
}
},
methods:{
divClick(){
alert('最终被标签捕捉到了!')
},
btnClick(){
this.count++
console.log(this.count)
}
},
template:`
<div @click="divClick">
<button @click.once="btnClick">只会自增一次</button>
</div>

`
})
const vm = app.mount("#app")
</script>

passive修饰符:解决滚动时性能的修饰符

VUE中的MOUSE、KEYBOARD鼠标&键盘按键绑定

在某种场景下,我们需要按下Enter键登录&注册
我们需要在鼠标hover悬停于某个元素上方时,进行交互

这样的操作还涉及到键盘、鼠标之间的事件

KEYDOWN事件绑定 敲下键盘里的某个键(input属性)

在输入框中输入内容时,会触发keydown事件

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<script>
const app = Vue.createApp({
data(){
return{
count: 1
}
},
methods:{
keyDownHandler(){
console.log('正在键入....')
}
},
template:`
<div >
<input @keydown="keyDownHandler" />
</div>

`
})
const vm = app.mount("#app")
</script>

单个特定键位检测(input属性)

对于特定的键Enter、Space等键有时我们会需要检测
比如实现表单的Enter提交方式

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
const app = Vue.createApp({
data(){
return{
count: 1,
username:''
}
},
methods:{
keyEnterDownHandler(){
console.log('提交成功!您的数据为' + this.username)
}
},
template:`
<div >
<input @keydown.enter="keyEnterDownHandler" v-model="username"/>
</div>

<div>
<button >提交表单</button>
</div>

`
})
const vm = app.mount("#app")
</script>

表单的数据双向绑定

什么叫数据的双向绑定?

所谓数据的双向绑定,就是指:data中的变量val与页面中的字面量相互绑定

  1. 当data中的val发生改变时 前端页面显示的值会发生变化
  2. 当前端中的内容发生变化(比如输入框输入不同的值) 那么data中的内容也会发生变化

这种两方中其中一方发生变化,而另一方必然随之变化的过程,称为双向绑定

表单INPUT TEXTAREA文本框的绑定

比如data中有一个变量val

1
2
3
4
5
data(){
return{
val:''
}
}

而前端页面中,输入的值赋给val

1
template:"<input v-model="val" />"

这样,输入不同的前端页面,data中的val也会不同!

  1. input单行文本框添加**v-model=”val”**属性
  2. textarea多行文本框同样适用

表单单选框RADIO的绑定

单选框一般用字符串接收

参与单选框中的v-model对应的data中的字符串变量命名意义是:这些若干同属的类别
**比如男、女 其v-model=”gender”**这样命名

其次,应有不同的value属性值来区分这些单选框!

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
const app = Vue.createApp({
data(){
return{
gender:''
}
},
methods:{
keyEnterDownHandler(){
console.log('提交成功!您的数据为' + this.username)
}
},
template:`
<div >
<input type="radio" v-model="gender" value="男"/>男
<br>
<input type="radio" v-model="gender" value="女"/>女
</div>

`
})
const vm = app.mount("#app")
</script>

表单多选框CHECKBOX的绑定

对于多选框的每个框要么属于checked被选中的状态 要么没被选中

  1. 所以如果只有一个选项 我们应用Bool值true与false来确定多选框的选中状态
  2. 如果有多个选项,我们**应该用一个数组[]**来装!

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
const app = Vue.createApp({
data(){
return{
gender:'',
interests:[]
}
},
methods:{
keyEnterDownHandler(){
console.log('提交成功!您的数据为' + this.username)
}
},
template:`
<div >
<input type="checkbox" v-model="interests" value="打篮球"/>打篮球
<br>
<input type="checkbox" v-model="interests" value="游泳"/>游泳
</div>
`
})
const vm = app.mount("#app")
</script>

深入v-model

1.LAZY 懒显示

对于双向绑定,当输入框绑定data中的变量content后,如果页面的某一个区域立即用到了这个content
那么在输入的过程中,页面会实时显示content的值

我们使用 v-model.lazy=”val” 来懒显示,即输入框失去焦点后,内容才会发生变化

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const app = Vue.createApp({
data(){
return{
content:''
}
},
template:`
输入框失去焦点才会显示的content:{{content}}
<div >
<input v-model.lazy="content"/>
</div>
`
})
const vm = app.mount("#app")
</script>

2.NUMBER 输入数字

默认输入的内容是字符串类型 为避免后台转换数字

我们可以使用v-model.number=”val” 来转换成输入绑定data中的变量val

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const app = Vue.createApp({
data(){
return{
content:''
}
},
template:`
输入的数据类型是:{{typeof content}}
<div >
年龄:<input v-model.number="content"/>
</div>
`
})
const vm = app.mount("#app")
</script>

去除前后空格-trim

trim属性用来消除input框输入内容前后的空格的。现在我们再字符串上输入空格,其实它会在DOM元素上进行增加空格的,这个可以在控制台清楚的看出(详细请看视频操作)。 加入trim修饰符后,Vue就会自动给我们去除前后的空格.

1
v-model.trim="content"

翻译作品--如何像母语者一样说英语

How to speak English fast and understand natives (Part I) | 如何更快理解母语者

该视频由YouTube博主讲述如何像母语者一样说英语

Do you really need to speak English fast? When native English speakers speak fast, the boundaries between words disappear and this gives the impression of talking fast. In reality, they are not talking faster than normal —it’s just that the sounds in their pronunciation flow together in the most smooth and efficient way.
你一定要说得快吗?当以英语为母语的人说得很快时,单词之间的界限就消失了,这会给人一种说得很快的印象。在现实生活中,他们并没有说得比平时快,只是他们的发音中的声音以最流畅和有效的方式衔接在一起。

视频地址

复试代码(仅供参考)

题目:03 成本与利润最大化问题

题目背景

地球上所有的自然资源是有限的。拿矿物资源来说,它不是上帝的恩赐,
而是经过几百万年,甚至几亿年的地质变化才形成的。地球是无私的,它向人
类慷慨地提供矿产资源。但是,如果不加节制地开采,必将加速地球上矿产资
源的枯竭。

人类生活需要的水资源、森林资源、生物资源、大气资源,本可以不断地
再生,长期给人类做贡献。但是因为人类随意毁坏自然资源,不顾后果地滥用
化学用品,不但使它们不能再生,还造成了一系列生态灾难,给人类生存带来
了严重的威胁。

资源是有限的,我们必须要加以珍惜,合理使用地球上有限的资源,细水
长流,方能持久!

在资源有限的前提下,人类在生产生活中,需要设计合理、优化的资源使
用方案,以满足其利润最大化的需求。

假设工程项目总数为 n,可利用的资源份额总数为 m,给每项工程投入的资
源份额数不同时,所获得的利润也不同。
其利润表如下所示:

在这里插入图片描述

题目描述

一、请完成如下问题的求解:
■问题 1(50 分):请利用 C/C++编程实现并输出当所获得的利润最大时,
资源的投入方案。
测试用例(备注:须遵守测试用例所示范的输入、输出格式及形式要求):

备注 1:测试用例示范
测试用例 1
输入:
请输入工程项目总数 n:X↙
请输入资源份额总数 m:X↙
请输入工程项目与投入资源份额数所对应利润:(可参考问题 2 中的利润表
数据形式)
输出:
最后的决策结果为:给工程 1 投入 X 个份额,工程 2 投入 X 个份额,……,
工程 X 投入 X 个份额的资源时,可达到最大利润 XXX. (其中 X 为具体数值)

测试用例 2
输入:
请输入工程项目总数 n:3↙
请输入资源份额总数 m:8↙
请输入工程项目与投入资源份额数所对应利润:(参考问题 2 中的利润表数
据)
输出:
最后的决策结果为:给工程 1 投入 0 个份额,工程 2 投入 4 个份额,工程 3
投入 4 个份额的资源时,可达到最大利润 140.

■问题 2(30 分):当可利用的资源份额总数为 8,工程项目总数为 3 以及
利润表如下所示时,请给出资源投入最优方案的分析、计算过程。
在这里插入图片描述

■问题 3(10 分):分析给出所实现算法的时间复杂度;

■问题 4(10 分):请简要给出可能的进一步提高算法时间复杂度的解决

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<bits/stdc++.h>
using namespace std;

int maxProfit = 0;

//最终的各个工程的对应份额数
vector<int> finalShare;

//n代表工程数
//m代表份额数
int n, m;

//data表示所有数据数组 currentProfit代表当前利润 projectNum代表已到工程索引 shareNum代表已用的份额数 currentShare代表当前份额数组
void cacl(vector<vector<int>> &data, int currentProfit, int projectNum, int shareNum, vector<int> currentShare)
{
//跳出递归有两个条件
//1.当份额数达到规定数
//2.工程索引超出规定数
if(shareNum >= m){
if(shareNum == m){
if(currentProfit > maxProfit){
maxProfit = currentProfit;
finalShare.clear();

for(int i=0; i<currentShare.size(); i++){
finalShare.push_back(currentShare[i]);
}
}
}
return;
}

if(projectNum >= n){
if(currentProfit > maxProfit){
maxProfit = currentProfit;
finalShare.clear();
for(int i=0; i<currentShare.size(); i++){
finalShare.push_back(currentShare[i]);
}
}
return;
}

vector<int> temp;

//最开始的currentShare数组为空 for循环不会进入
for(int i=0; i<currentShare.size(); i++){
temp.push_back(currentShare[i]);
}

//temp暂时存储要选的份额->这里push_back表示第一层不选
temp.push_back(0);

//进入下一层 然后继续进入temp.push_back(0) 第二层也不选
//直到工程索引达到3 见边界if函数 return往下进入 for循环
cacl(data, currentProfit, projectNum+1, shareNum, temp);

//开始从第三层开始 选第一个! 比较利润 选第二个..同理下去
//然后回退到第二层 选第二层第一个 第三层分别第1~8个 第二个..同理
//然后回退到第一层 选第一层第一个 第二层第1~8个 第三层第1~8个
//这个过程中 一直比较利润确定最终利润(在选中的规定份额数内)

for(int i=0; i<data[projectNum].size(); i++){
vector<int> temp1;
for(int j=0; j<currentShare.size(); j++){
temp1.push_back(currentShare[j]);
}
temp1.push_back(i+1);
cacl(data, currentProfit+data[projectNum][i], projectNum+1, shareNum+(i+1), temp1);
}
}

void fun(){
cout << "请输入工程项目总数n:";
cin >> n;

cout << "请输入资源份额总数m:";
cin >> m;

vector<vector<int>> dataVector;
int temp;

for(int i=0; i<n; i++){
vector<int> columnVector;
for(int j=0; j<m; j++){
cin >> temp;
columnVector.push_back(temp);
}
dataVector.push_back(columnVector);
}

cacl(dataVector, 0, 0, 0, {});

for(int k=0; k<finalShare.size(); ++k){
cout << "给工程" << k+1 << "投入" << finalShare[k] << "个份额,";
}
cout << "可达最大利润" << maxProfit << "." <<endl;
}

int main(){
fun();
}

C++管理系统

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<cstring>

using namespace std;

typedef struct student //学生信息
{
char stu_num[15]; //学号
char name[15]; //姓名
char stu_id[20]; //身份证号
char institute[50]; //学院
char stu_type; //学生类型
char major[50]; //专业
char route[100]; //返校路线
char TrafficTools[100]; //交通工具
char isCloseContact; //近14天是否有密切接触确诊人员
char temperature[10]; //入校时温度
char isFever; //是否发烧
char isCough; //是否咳嗽
char time[20]; //进校时间

}Student;

void Print(Student stu) //输出学生信息
{
printf("\n*****************学生信息*****************\n\n");
printf("学号: %s\n姓名: %s\n身份证号: %s\n学生类型: %c\n",stu.stu_num,stu.name,stu.stu_id,stu.stu_type);
printf("学院: %s\n专业: %s\n返校路线: %s\n交通工具: %s\n",stu.institute,stu.major,stu.route,stu.TrafficTools);
printf("过去14天是否密切接触确诊人员(是:1/否:0): %c\n返校温度: %s\n",stu.isCloseContact,stu.temperature);
printf("是否发烧(是:1/否:0): %c\n是否咳嗽(是:1/否:0): %c\n返校时间: %s\n",stu.isFever,stu.isCough,stu.time);
}

void Instruction() //帮助
{
printf("====================学生返校信息管理系统====================\n");
printf("= =\n");
printf("= ***功能介绍*** =\n");
printf("= =\n");
printf("= 1.录入学生信息 =\n");
printf("= 2.查找学生信息 =\n");
printf("= 3.修改学生信息 =\n");
printf("= 4.按顺序输出某学院学生信息 =\n");
printf("= 5.请求帮助 =\n");
printf("= 6.退出系统 =\n");
printf("= =\n");
printf("= =\n");
printf("============================================================\n");
return ;
}

void WriteStuInfo(){
FILE *fp;
char c = 'y';
char file[50] = "C:\\Users\\Administrator\\Desktop\\";

while(c == 'y'){
Student stu = {0}; //初始化
cout << "请按照以下内容初始化:\n";

cout << "请输入学号\n";
cin >> stu.stu_num;

cout << "请输入姓名\n";
cin >> stu.name;

cout << "请输入身份证\n";
cin >> stu.stu_id;

cout << "学生类型:(1本 2研 3博)\n";
cin >> stu.stu_type;

cout << "所在学院\n";
cin >> stu.institute;

cout << "所在专业\n";
cin >> stu.major;

cout << "返校所经城市\n";
cin >> stu.route;

cout << "交通工具\n";
cin >> stu.TrafficTools;

cout << "是否接触确诊:1是 0否";
cin >> stu.isCloseContact;

cout << "入校时的温度\n";
cin >> stu.temperature;

cout << "是否发烧: 1是 0否\n";
cin >> stu.isFever;

cout << "是否咳嗽: 1是 0否\n";
cin >> stu.isCough;

cout << "入校时间\n";
cin >> stu.time;

strcat(file, stu.institute);
strcat(file, ".txt");

cout << file;
fp = fopen(file, "a");
if(fp == NULL){
cout << "文件无法打开\n";
exit(0);
}

if(fwrite(&stu, sizeof(Student), 1, fp) != 1){
cout <<"数据无法录入\n";
}

//在定义的数组长度不够的情况下
//每次读入一组数据 可以在文件中打印一个换行符
//fprintf(fp, "\n");

fclose(fp);
cout << "是否继续录入?(y/n)\n";
cin >> c;
}
}

void Search(){
char c = 'y';
int flag = 0;
FILE* fp;
int isSearch;
Student stu = {0};
while(c == 'y'){
char stu_info[50], ins[50] = {0};
char file[50] = "C:\\Users\\Administrator\\Desktop\\";
cout << "输入学生所在学院\n";
cin >> ins;

strcat(file ,ins);
strcat(file, ".txt");

fp = fopen(file, "r");
cout << "请输入查找方式:1/学号,2/姓名\n";
cin >> flag;

cout << "待查找的信息:" <<endl;
cin >> stu_info;

isSearch = 0;
while(fread(&stu, sizeof(Student), 1, fp) == 1 ){
//当读到数据时
if(flag == 1){
if(!strcmp(stu.stu_num, stu_info)){
cout << "找到了,数据为:\n";
Print(stu);
isSearch = 1;
break;
}

if(!strcmp(stu.name, stu_info)){
cout << "找到了,数据为:\n";
Print(stu);
isSearch = 1;
break;
}
}
if(isSearch == 0){
cout << "查无此人!" <<endl;
}
fclose(fp);

cout << "是否继续查找(y/n)\n";
cin >> c;
}
}
}

void Alter(){
FILE* fp;
int isSearch;
int pos, num;
int i;

char c = 'y';
while(c == 'y'){
char newfile[10000] = "C:\\Users\\Administrator\\Desktop\\";
char stu_info[50], ins[50], file[50] = "C:\\Users\\Administrator\\Desktop\\";
Student all_stu[50], goal_stu, stu={0};

cout << "请输入学生所在学院\n";
cin >> ins;
strcat(file, ins);
strcat(file, ".txt");

fp = fopen(file, "r");
cout <<"输入学生学号:\n";
cin >> stu_info;

isSearch = 0;
pos = 0;
num = 0;
for(pos=0; fread(&stu, sizeof(Student), 1, fp)==1; pos++){
if(!strcmp(stu.stu_num, stu_info)){
goal_stu = stu;
isSearch = 1;
}else{
all_stu[num++] = stu;
}
}

if(isSearch){
fclose(fp);
fp = fopen(file, "w");
for(i =0; i<num; i++){
fwrite(&all_stu[i], sizeof(Student), 1, fp);
}

fclose(fp);

cout << "请输入信息:\n\n";
cout << "请输入学号:\n";
cin >> stu.stu_num;

cout << "请输入姓名:\n";
cin >> stu.name;

cout << "请输入身份证号:\n";
cin >> stu.stu_id;

cout << "请输入学生类型:1/本, 2/硕, 3/博\n";
cin >> stu.stu_type;

cout << "请输入所在学院:\n";
cin >> stu.institute;

cout << "请输入所在专业:\n";
cin >> stu.major;

strcat(newfile, stu.institute);
strcat(newfile, ".txt");
fp = fopen(newfile, "a");
fwrite(&stu, sizeof(Student), 1, fp);
}else{
cout << "查无此人\n";
}
fclose(fp);
cout << file <<endl;
fp = fopen(file, "r");
while(fread(&stu, sizeof(Student), 1, fp)==1){
Print(stu);
}
fclose(fp);
cout << "是否继续修改y/n \n";
cin >> c;
}
}

void print_Sort(){
FILE* fp;
int j, Min;
int num = 0;
int i;
Student all_stu[50]={0}, stu={0};
char newfile[10000] = "C:\\Users\\Administrator\\Desktop\\sort_";
char ins[20], file[50] = "C:\\Users\\Administrator\\Desktop\\";

cout << "请输入学院:\n";
cin >> ins;

strcat(file, ins);
strcat(file, ".txt");

fp = fopen(file, "r");

while(fread(&all_stu[num++], sizeof(Student), 1, fp) == 1){
;
}
fclose;

for(i=0; i<num-1; i++){
Min = i;
for(j=i+1; j<num; j++){
if(strcmp(all_stu[Min].stu_num, all_stu[j].stu_num) >0){
Min = j;
}
}

if(Min != i){
Student temp = all_stu[i];
all_stu[i] = all_stu[Min];
all_stu[Min] = temp;
}
}

strcat(newfile, ins);
strcat(newfile, ".txt");
fp = fopen(newfile, "w");
for(i=0; i<num; i++){
fwrite(&all_stu[i], sizeof(Student), 1, fp);
}
fclose(fp);

fp = fopen(newfile, "r");
while(fread(&stu, sizeof(Student), 1, fp)==1){
Print(stu);
}

fclose(fp);
}

void passwordVerify()
{
char password[20]={0};
int i=5;
printf("\n\n");
printf("====================欢迎使用学生返校信息管理系统====================\n\n");

while(i>0){
printf("请输入登录密码:");
scanf("%s",&password);
if(strcmp(password,"123456")!=0){
--i;
printf("密码输入错误,请重新输入,您还有%d次机会\n",i);
}
else{
printf("密码输入正确!");
break;}
if(i==0){
exit(0);}
}
}
void chooseMenu(){
int flag;
char c='y';
while(c=='y'){
printf("请输入您需要的操作(按5请求帮助): \n");
flag=0;
scanf("%d",&flag);
getchar();
if(flag==1){ //录入
WriteStuInfo();
}
else if(flag==2){ //查找
Search();
}
else if(flag==3){ //修改
Alter();
}
else if(flag==4){ //排序
print_Sort();
}
else if(flag==5){ //导航
Instruction();
}
else if(flag==6){ //退出系统
exit(0);
}
else {
printf("输入有误!请重新输入!\n ");
continue;
}
printf("是否继续使用该系统(y/n):");
scanf("%c",&c);
}
}

int main()
{ passwordVerify();
Instruction();
system("pause");
return 0;
}

C++面向对象基础

职员类

构造函数

set get 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;

//定义一个职员类
class Employee{
//属性与方法

public: //公共方法

//构造函数 有多个构造函数后
//默认的空构造函数 会被覆盖 建议加上
Employee(){}
Employee(string name, string company, int age);

//Set方法
void setName(string name);
void setCompany(string company);
void setAge(int age);

//Get方法
string getName();
string getCompany();
int getAge();

void introduce();
private:
//私有属性 在类的外部不可直接调用
//注意!不管是接口还是属性 还是方法
//C++中 不明确指出public还是protected的
//默认是“private”!!!!

string Name; //姓名
string Company; //所就职的公司
int Age; //年龄
};

//利用域名符:: 实现相应的方法
//注意:实现相应方法的形参 必须对应相应的函数声明
//注意:使用this指针时 内部使用-> 在主函数中的对象 使用.
Employee::Employee(string name, string company, int age){
//this指针 代表当前任意被调用的这个对象
this->Name = name;
this->Company = company;
this->Age = age;
}

void Employee::setName(string name){
this->Name = name;
}

string Employee::getName(){
return this->Name;
}

void Employee::setCompany(string company){
this->Company = company;
}

string Employee::getCompany(){
return this->Company;
}

void Employee::setAge(int age){
this->Age = age;
}

int Employee::getAge(){
return this->Age;
}


void Employee::introduce(){
cout << "Name->" << Name << "," << "Company->"
<< Company << ",Age->" <<Age<<endl;
}

int main()
{
string name = "Vincent";
string company = "Tecent";
int age = 21;

//利用构造函数 new一个新的职员对象
Employee e1 = Employee(name, company, age);
e1.introduce();

return 0;
}

实现虚拟接口

职员具有实现接口的功能

1.定义一个接口(Virtual 虚拟方法)

1
2
3
4
class AbstractEmployee{
public:
virtual void AskForPromotion()=0;
};

2.声明某个类实现 :这个AbstractClass

1
2
3
4
5
6
7
8
class Employee:AbstractEmployee{
public:
//.....公共方法
//将接口中的方法 作为实现这个方法的类的成员函数
void AskForPromotion();
private:
//.....私有属性
};

3.具体实现函数

1
2
3
void Employee::AskForPromotion(){
//具体方法
}

程序员(Employee类的子类 继承Employee)

1.程序员类具有自己特有的构造函数&成员函数

1
2
3
4
5
6
7
8
9
10
11
12
13
class Developer: Employee{
public:
//别忘了默认的构造函数 以及声明程序员类特有的构造函数
Developer(){}
Developer(string name, string company, int age, string fav);
//继承Employee的同时 Developer类具有Employee的公共方法

//Set函数与Get函数 是Developer独有的方法
void setFavProgLang(string language);
string getFavProgLang();
private:
string FavProgLang; //最喜欢的编程语言
};

2.实现这个构造函数以及成员函数(:Empl… 表示由其父类来实现前三个参数)

1
2
3
4
5
Developer::Developer(string name, string company, int age, string fav)
:Employee(name, company, age)
{
this->FavProgLang = fav;
}

注意:父类中的Name,Company,Age 在其子类Developer中都是不可获取的(Inaccessible)
因为,这些属性都是private 私有的,在类外任何地方都不能获取!
除非我们修改这些属性的修饰符 修改成protected

SpringMVC学习笔记(所有代码FROM SIKI学院)

SpringMVC是什么?

Spring MVC又叫SpringWebMVC是一个轻量级的基于请求响应的表现层框架。它是Spring框架的一部分。SpringMVC与Struts2都可以替代原始Servlet技术。

为什么要使用SpringMVC?

Spring Web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。

1、SpringMVC是极具代表性的MVC框架对初学者学习很有帮助;
a)模型(Model)封装了应用程序数据,通常它们将由Bean对象组成;
b)视图(View)负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出;
c)控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染;

2、与Spring框架无缝集成;
3、对Servlet轻度封装,框架小巧轻便性能好;
4、可使用注解式开发,编码简洁;
5、便于测试;
6、具有本地化、国际化、类型转换、数据验证等功能;
7、使用人群十分广泛,在现在的企业招聘中属于java程序员必备技能之一;

我能从这门课中学到什么?

1、SpringMVC框架学习:
a)了解SpringMVC框架处理流程;
b)掌握SpringMVC搭建、配置与使用;
c)Spring + SpringMVC + MyBatis 三大框架整合;
d)掌握SpringMVC基本参数与复杂参数绑定;
e)掌握SpringMVC自定义异常处理类、拦截器、图片上传等操作;
f)掌握SpringMVC处理Json格式字符串;

2、SSM框架练习项目:
a)使用整合后的SSM框架完成Steam后台游戏管理和前台游戏列表的Demo;

SpringMVC从哪获取?
以下网址可以获取Spring框架的所有版本,SpringMVC是Spring框架中的一个子包SpringWebMvc
http://repo.spring.io/release/org/springframework/spring/

Part.1 SpringMVC入门:

1、SpringMVC简要处理流程:

在这里插入图片描述

2、HelloSpringMVC:搭建SpringMVC HelloWorld项目

a)导包 –> 02_jar -> spring_jar整理 -> spring_mvc;
b)DispatcherServlet配置和拦截规则 (前端控制器、任务派发器、前端调度器);
c)使用SpringMVC显示页面;
d)使用SpringMVC向前台传递数据;

3、SpringMVC详细处理流程:

在这里插入图片描述

4、DispatcherServlet.properties内Bean对象:

a)HandlerMapping:处理器映射 :将请求映射到Handler上并返回处理器执行链
i.通过HandlerMapping(处理器映射),可以将Web 请求映射到正确的Handler(处理器)也就是Controller上;
ii.DispactherServlet(前端控制器) 将请求交给HandlerMapping,让他检查请求并找到一个合适的HandlerExecutionChain(处理器执行链),这个HandlerExecutionChain 包含一个能处理该请求的Handler;

b)HandlerAdapter:处理器适配器 :执行具体的逻辑业务
i.负责执行DispactherServlet中HandlerExecutionChain的Handler;
ii.从Handler中获取ModelAndView(模型与视图)对象,返回给DispactherServlet;

c)ViewResolver:视图解析器 :解析视图
i.通过视图名称解析视图;
ii.返回视图对象;

d)HandlerExceptionResolver:处理器异常解析,将异常映射到统一错误页面,常见的404页面,不让用户看到具体的错误,友好提示;
e)LocaleResolver:本地化解析,解析客户端信息进行本地化;
f)ThemeResolver:主题解析,实现多风格,类似皮肤效果;
g)RequestToViewNameTranslator:请求到视图名转换器,当view为空时,从request中获取viewName;FlashMapManager:FlashMap管理器,通常应用在重定向场景;

5、SpringMVC Controller简要说明
a)RequestMapping注解使用:
i.多请求;
ii.限定请求方法;
iii.窄化(简化)请求路径;

b)Controller方法返回值:
i.ModelAndView:返回模型和视图
ii.void:使用原生request,response
iii.String:
1.返回视图名 viewName;比较推荐使用
2.转发 forword;
3.重定向 redirect;

iv.自定义类型(JSON) – 需要@ResponseBody注解 -

Part.2 SpringMVC & Spring & MyBatis整合:

1、整合ssm 3大框架

a)导包 -> spring_Jar整理 -> ssm框架整合包
b)配置 -> web.xml
i.读取spring配置文件;
ii.配置springmvc前端控制器;

c)配置 -> applicationContext.xml
i.读取数据库配置文件;
ii.配置数据源连接池;
iii.开启注解扫描;
iv.配置事务核心管理器;
v.开启注解事务;
vi.配置视图解析器;

vii.配置Mybatis:
1.配置sqlSessionFactory;
2.配置别名;
3.配置mapper工厂;

2、准备测试用例

a)准备 – 测试数据:
i.Bean -> 根据个人喜好;
ii.数据库表 -> 根据个人喜好;
b)导入 – 测试数据 -> 学习项目 -> 后台页面
使用整合后的ssm框架,查询数据库测试表,将数据显示到前台

Part.3 SpringMVC参数绑定与数据交互:

1、默认参数绑定:通过id查询游戏信息,并将结果显示在页面上;

a)HttpServletRequest request;
b)HttpServletResponse response;
c)HttpSession session;
d)Model model:将数据存储在request域,前台可以获取;

2、基本参数绑定:通过id删除游戏信息;

a)Integer、int;
b)Float、float;
c)Double、double;
d)Boolean、boolean;
e)String;

3、Bean对象参数绑定:添加游戏;

4、包装类参数绑定:多条件查询,并将结果显示在页面上;
5、解决表单post提交乱码:在web.xml中配置过滤器;

复杂类型参数绑定:

1、Array数组类型的参数绑定:为页面增加多选框,获取选定游戏信息的id,后续逻辑自行选择;
2、List类型的参数绑定:获取所有游戏价格,并且计算总价;

Json数据交互:

Json介绍:http://www.bejson.com/knownjson/aboutjson/
a)导包,配置注解驱动;
b)创建自己的Json对象;
c)发送和接收Json字符串;
d)修改游戏信息,在弹出层内回显数据;
e)使用@RequestBody完成List和数组参数绑定,获取所有游戏的名称,在后台打印;

Part.4 异常处理器与拦截器

1、通过实现HandlerExceptionResolver接口完成异常处理;

a)异常处理器原理;
在这里插入图片描述

b)使用异常处理器捕获运行时异常;
c)使用异常处理器捕获自定义异常;

2、通过注解完成全局异常处理;

a)通过@ControllerAdvice注解使@ExceptionHandler异常处理注解应用到所有使用@RequestMapping的方法上;
b)处理运行时异常:直接打印错误信息;
c)处理自定义异常:将错误信息输出到error页面上;

拦截器Interceptor

1、SpringMvc中的拦截器:

a)SpringMvc拦截器帮我们按照一定规则拦截请求,后根据开发人员自定义的拦截逻辑进行处理;
b)自定义拦截器需要实现HandlerInterceptor接口;
c)自定义的拦截器实现类需要在SpringMvc配置文件中配置;
d)可以配置多个拦截器,配置的顺序会影响到拦截器的执行顺序,配置在前的先执行;
e)HandlerInterceptor有3个接口:
i.preHandle 预处理:在拦截方法前执行;
ii.postHandle 后处理:在拦截方法后执行;
iii.afterCompletion 渲染后处理:在页面渲染后执行;
f)拦截器也体现了AOP思想;
g)拦截器的应用:权限检查,日志记录,性能检测等;

2、拦截器的执行流程图:

在这里插入图片描述

3、拦截器的执行规则;

a)自定义2个拦截器,并在主配置文件中配置好;
b)运行服务进入拦截器,观察执行流程;

4、总结的五条拦截器规则;

a)preHandle预处理:————–根据拦截器定义的顺序,正向执行;
b)postHandle后处理:————-根据拦截器定义的顺序,逆向执行;
c)afterCompletion渲染后处理:—根据拦截器定义的顺序,逆向执行;
d)postHandle预处理:————-所有拦截器都返回成功调用;
e)atterCompletion渲染后处理:—preHandle返回true调用;

5、使用拦截器开发用户登录校验;

a)需要登录才可以访问列表页;
b)如果未登录重定向到登录页面;

6、使用拦截器搭配异常处理器完成用户登录时的异常处理;

a)使用自定义异常处理器捕获登录时异常;
b)如果出现异常,将异常信息发送到登录页面提示;

7、静态资源放行;

a)在web.xml配置DispatcherServlet的url-pattern以扩展名结尾,例如*.do,*.html 等;
b)在web.xml配置default servlet-mapping的url-pattern,以目录形式和扩展名形式;
c)在springmvc.xml中配置mvc:resources/,该方法需要注意以下几点:
i.需要开启mvc:annotation-driven注解驱动;
ii.如果配置了拦截器,需要在拦截器中进行过滤,否则会被拦截;
iii.路径名不要打错 ;

8、RESTful风格开发:一种以URL定位资源的开发风格。使用RESTful开发URL会变得一目了然,更有层次,它不是标准或者协议;

更多关于RESTful风格的介绍网上查查;

使用RESTful前:
http://127.0.0.1/item/save POST 新增物品
http://127.0.0.1/item/delete GET/POST 删除物品
http://127.0.0.1/item/update POST 修改物品
http://127.0.0.1/item/query.do?id=1 GET   根据id查询物品

使用RESTful后:
http://127.0.0.1/item POST 新增物品
http://127.0.0.1/item/1 DELETE 根据id删除物品
http://127.0.0.1/item PUT 修改物品
http://127.0.0.1/item/1 GET   根据id查询物品

RESTful风格开发对Http协议中的基本方法的使用
POST INSERT 增 邮寄一个新的
DELETE DELETE 删 仍了,不要了
GET SELECT 查 获取一个
PUT UPDATE 改 往这个里边放点东西

使用Springmvc实现RESTful风格开发;
a)使用物品id当作请求路径,点击按钮,跳转到具体的页面;
b)当使用ajax时,页面不会跳转,需要到ajax回调中处理;

SPRINGMVC-PROJECT-1

前端请求页面form.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/mylist.do" method="get">
<input type="submit" value="提交">
</form>
</body>
</html>

WEB配置文件 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ssm_spring_mvc</display-name>

<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 读取springmvc配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 拦截规则 -->
<!--1 *.htm *.do *.action 以扩展名方式进行拦截,不拦截静态资源 .jpg .css .js .png 什么情况下都可以使用
2 / 不拦截 jsp 拦截静态资源 .jpg .css .js .png
/* 全都拦截 包括jsp 以及所有静态资源 不推荐使用的-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

SPRINGMVC配置文件 springmvc.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

<!-- 开启注解扫描 基本包下有 bean,controller层.. -->
<context:component-scan base-package="com.sikiedu"></context:component-scan>

<!-- 配置视图解析器 配置viewName 前缀与后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

</beans>

BEAN对象 ItemInfo.java

1
2
3
4
5
6
7
8
9
10
public class ItemInfo {
//id
private String item_id;
//name
private String item_name;
//type
private String item_type;
//price
private String item_price;
}

Controller层 ItemController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

<!-- 注解表示是控制层 通过springmvc注解扫描 -->
<!-- RequestMapping对应前端页面的请求路径 -->
@Controller
@RequestMapping(value="/item/")
public class ItemController {

//显示页面
@RequestMapping(value= {"list.do", "mylist.do"}, method= {RequestMethod.GET, RequestMethod.POST})
<!-- 指定返回类型是ModelAndView 表示最后会跳转页面 -->
public ModelAndView list() {
ModelAndView mav = new ModelAndView();

//传递数据
//准备一些测试数据
ItemInfo info1 = new ItemInfo("1", "王者荣耀", "MOBA", "0") ;
ItemInfo info2 = new ItemInfo("2", "守望先锋", "射击", "198") ;
ItemInfo info3 = new ItemInfo("3", "吃鸡", "射击", "98") ;
ItemInfo info4 = new ItemInfo("4", "魔兽世界", "MMORPG", "0") ;
ItemInfo info5 = new ItemInfo("5", "保卫萝卜", "休闲", "0") ;

List<ItemInfo> itemList = new ArrayList<ItemInfo>();
itemList.add(info1);
itemList.add(info2);
itemList.add(info3);
itemList.add(info4);
itemList.add(info5);

//将游戏列表返回给前台
mav.addObject("itemList", itemList);

mav.setViewName("item_list");

return mav;
}

@RequestMapping(value= {"mylist1.do"}, method= {RequestMethod.GET, RequestMethod.POST})
public ModelAndView list1() {
ModelAndView mav = new ModelAndView();

//传递数据
//准备一些测试数据
ItemInfo info1 = new ItemInfo("1", "王者荣耀", "MOBA", "0") ;
ItemInfo info2 = new ItemInfo("2", "守望先锋", "射击", "198") ;
ItemInfo info3 = new ItemInfo("3", "吃鸡", "射击", "98") ;
ItemInfo info4 = new ItemInfo("4", "魔兽世界", "MMORPG", "0") ;
ItemInfo info5 = new ItemInfo("5", "保卫萝卜", "休闲", "0") ;

List<ItemInfo> itemList = new ArrayList<ItemInfo>();
itemList.add(info1);
itemList.add(info2);
itemList.add(info3);
itemList.add(info4);
itemList.add(info5);

//将游戏列表返回给前台 指定Viewname即显示的页面是哪一个?

mav.addObject("itemList", itemList);
mav.setViewName("item_list");

return mav;
}


//void
@RequestMapping(value="")
public void voidTest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取参数
request.getParameter("");

//转发
request.getRequestDispatcher("").forward(request, response);

//重定向
response.sendRedirect(request.getContextPath() + "/xx.jsp");
}

//String 转发
@RequestMapping("forwardString.do")
public String forwardString() {
return "forward:mylist1.do";
}

//String 重定向
@RequestMapping("redirectString.do")
public String redirectString() {
return "redirect:/form.jsp";
}


//String
@RequestMapping("testList.do")
public String testList(Model model) {
//传递数据
//准备一些测试数据
ItemInfo info1 = new ItemInfo("1", "王者荣耀", "MOBA", "0") ;
ItemInfo info2 = new ItemInfo("2", "守望先锋", "射击", "198") ;
ItemInfo info3 = new ItemInfo("3", "吃鸡", "射击", "98") ;
ItemInfo info4 = new ItemInfo("4", "魔兽世界", "MMORPG", "0") ;
ItemInfo info5 = new ItemInfo("5", "保卫萝卜", "休闲", "0") ;

List<ItemInfo> itemList = new ArrayList<ItemInfo>();
itemList.add(info1);
itemList.add(info2);
itemList.add(info3);
itemList.add(info4);
itemList.add(info5);

//将游戏列表返回给前台
model.addAttribute("itemList", itemList);

return "item_list";
}

}

数据显示页面 item_list.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>游戏管理后台</title>
<meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body class="side_menu_active side_menu_expanded">
<div id="page_wrapper">

<!-- header -->
<header id="main_header">
<div class="container-fluid">
<!--logo-->
<div class="brand_section">
<a href="#"><img src="${pageContext.request.contextPath }/picture/logo01.png" alt="site_logo" width="108" height="40" style="margin-top: 5px"></a>
</div>
<div class="header_user_actions dropdown">
<div data-toggle="dropdown" class="dropdown-toggle user_dropdown">
<div class="user_avatar">
<img src="${pageContext.request.contextPath }/picture/head01.png" width="38" height="38">
</div>
<span class="caret"></span>
</div>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#">个人中心</a></li>
<li><a href="#">注销</a></li>
</ul>
</div>
</div>
</header>

<!-- main content -->
<div id="main_wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-10">
<table class="table table-yuk2 toggle-arrow-tiny" id="footable_demo" data-filter="#textFilter" data-page-size="5">
<thead>
<tr>
<!--描述:商品数据标签-->
<th>ID</th>
<th>游戏名称</th>
<th>类型</th>
<th>原价</th>
</tr>
</thead>
<tbody>
<c:forEach items="${itemList }" var="item">
<tr>
<td>${item.item_id }</td>
<td>${item.item_name }</td>
<td>${item.item_type }</td>
<td>${item.item_price }</td>

<td data-value="1">
<a herf="#" id="edit_btn" class="btn btn-xs btn-info" data-toggle="modal" data-target="#editLayer" onclick="editGoods('${item.item_id}')">修改</a>
<a herf="#" id="del_btn" class="btn btn-xs btn-danger" onclick="deleteGoods('${item.item_id}')">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
<tfoot class="hide-if-no-paging">
<tr>
<td colspan="5">
<ul class="pagination pagination-sm"></ul>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</div>

<!-- edit layer -->
<div class="modal fade" id="editLayer">
<div class="modal-dialog modal-content">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">修改游戏信息</h4>
</div>
<div class="modal-body">
<!--游戏修改详情弹出层表单-->
<form class="form-horizontal" id="edit_item_form">
<!-- 游戏id隐藏域 -->
<input type="hidden" id="edit_item_id" name="item_id"/>
<!-- 游戏名称 -->
<div class="form-group">
<label for="edit_item_name" class="col-sm-2 control-label">游戏名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_item_name" placeholder="游戏名称" name="item_name">
</div>
</div>
<!-- 游戏类型 -->
<div class="form-group">
<label for="edit_item_price" class="col-sm-2 control-label">类型</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_item_price" placeholder="类型" name="item_price">
</div>
</div>
<!-- 游戏原价 -->
<div class="form-group">
<label for="edit_item_price" class="col-sm-2 control-label">原价</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_item_price" placeholder="原价" name="item_price">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary btn-sm" onclick="updateItem()">确认修改</button>
</div>
</div>
</div>
</div>

<!-- add layer -->
<div class="modal fade" id="addLayer">
<div class="modal-dialog modal-content">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">新增游戏</h4>
</div>
<div class="modal-body">
<!--添加游戏弹出层表单-->
<form class="form-horizontal" id="add_item_form">
<!-- 游戏id隐藏域 -->
<input type="hidden" id="add_item_id" name="item_id"/>
<!-- 游戏名称 -->
<div class="form-group">
<label for="add_item_name" class="col-sm-2 control-label">游戏名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="add_item_name" placeholder="游戏名称" name="item_name">
</div>
</div>
<!-- 游戏类型 -->
<div class="form-group">
<label for="add_item_price" class="col-sm-2 control-label">类型</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="add_item_price" placeholder="类型" name="item_price">
</div>
</div>
<!-- 游戏原价 -->
<div class="form-group">
<label for="add_item_price" class="col-sm-2 control-label">原价</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="add_item_price" placeholder="原价" name="item_price">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary btn-sm" onclick="addItem()">确认修改</button>
</div>
</div>
</div>
</div>

<!-- main menu -->
<nav id="main_menu">
<div class="menu_wrapper">
<ul>
<li class="first_level">
<a href="javascript:void(0)">
<span class="icon_document_alt first_level_icon"></span>
<span class="menu-title">游戏管理</span>
</a>
<ul>
<li class="submenu-title">游戏管理</li>
<!-- <li><a href="#" data-toggle="modal" data-target="#addLayer">商品添加</a></li> -->
<li><a href="${pageContext.request.contextPath }/item/list.do">游戏列表</a></li>
</ul>
</li>
</ul>
</div>
<div class="menu_toggle">
<span class="icon_menu_toggle">
<i class="arrow_carrot-2left toggle_left"></i>
<i class="arrow_carrot-2right toggle_right" style="display:none"></i>
</span>
</div>
</nav>
</div>

<script type="text/javascript">
$(function() {
//footable
yukon_footable.goodslist();
//datepicker
yukon_datepicker.p_forms_extended();
})

//修改弹框回显
function toEdit(id) {
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/item/toEdit",
data:{"id":id},
success:function(data) {
$("#edit_item_name").val(data.item_name);
$("#edit_item_type").val(data.item_type);
$("#edit_item_price").val(data.item_price);
},
dataType:"json"
});
}
//确认修改
function updateItem() {
$.post(
"${pageContext.request.contextPath }/item/update.do",
$("#edit_item_form").serialize(),
function(data){
alert("游戏信息更新成功!");
window.location.reload();
});
}

//确认删除
function deleteItem(id) {
if(confirm('确实要删除该游戏吗?')) {
$.post(
"${pageContext.request.contextPath }/item/delete.do",
{"id":id},
function(data){
window.location.reload();
});
}
}

//添加游戏
function addItem() {
$.post(
"${pageContext.request.contextPath }/item/save.do",
$("#add_item_form").serialize(),
function(data){
alert("游戏添加成功!");
window.location.reload();
});
}
</script>
</body>
</html>

SPRINGMVC-PROJECT-2

新增登录拦截器与集成配置文件

登录拦截器LoginIntercaptor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class LoginInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {

//获取请求
String URI = request.getRequestURI();

if(!URI.contains("login")) {
//不是登录请求 拦截
Object user = request.getSession().getAttribute("user");

if(user == null) {
//没有登录 重定向到登录页面 / 请求
response.sendRedirect(request.getContextPath()+"/login/login.do");
return false;
}
}
return true;
}
}

集成配置文件 applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

<!-- 读取配置文件 数据库 -->
<context:property-placeholder location="classpath:db.properties"/>

<!-- 配置数据源 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!-- 开启注解扫描 -->
<context:component-scan base-package="com.sikiedu"></context:component-scan>

<!-- 静态资源放行 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/fonts/" mapping="/fonts/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/picture/" mapping="/picture/**"/>

<!-- 开启注解驱动 -->
<mvc:annotation-driven/>

<!-- 事务核心管理器 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 开启注解事务 -->
<tx:annotation-driven/>

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!-- 配置mybatis -->
<bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.sikiedu.bean"/>
</bean>

<!-- mapper工厂 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sikiedu.mapper"/>
</bean>

<mvc:interceptors>
<!-- 登录验证拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/**/*.css"/>
<mvc:exclude-mapping path="/**/*.js"/>
<mvc:exclude-mapping path="/**/*.png"/>
<mvc:exclude-mapping path="/**/*.tff"/>
<mvc:exclude-mapping path="/**/*.woff"/>
<bean class="com.sikiedu.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>