一、严格模式
1. 严格模式的声明
"use strict";
*目的
使代码更加严谨,为后期的版本做一个铺垫。
*严格模式下的不同点
- 在严格模式下函数里面的this返回的是undefined(禁止关键字this指向全局变量);
- 在严格模式下,外部访问不到eval()中创建的任何变量或函数,为eval赋值也会导致错误(严格模式中 eval和arguments当做关键字,它们不能被赋值和用作变量声明);
- 在严格模式下,变量或函数必须声明后才能够使用;
- 在严格模式中,可以声明块级函数,并且可以在块级作用;
- 在严格模式下,无法删除变量,只有configurable属性为true的对象属性才能够被删除;
- 在严格模式下,对象的属性名不能相同(非严格模式下后面的会覆盖前面的);
- 在严格模式下,函数的形参不能重名,属于语法错误(非严格模式下可以使用arguments[i]获取)
二、对象扩展
var obj = {
'name':'张三',
'age':20
};
var new_obj = Object.create(obj.{
'love':{ // 属性名
'value':'篮球', // 给该属性添加值
'writable':true, // 是否允许更改该属性,默认为false
'configurable':true, // 是否允许删除,默认为false
'enumerable':true // 是否允许迭代/遍历,默认为false
}
});
三、let声明
let声明和var声明是一样的,都是用来定义变量,声明变量的关键字。
格式
let a = 10;
// let 变量名 = 值;
// 和 var 一样
let和var的区别
var :
- var作用域为函数作用域
- var有变量提升
- var声明的变量名可以重复,后面的会覆盖前面的。
let :
- let作用域为块级作用域,一个{}为一个代码块。
- let没有变量提升
- let声明的变量名在一个块级作用域下不能重复
let在for循环里面的使用
for循环的特点
- 在for循环圆括号中的变量 是for语句块作用域的父级作用域
- js引擎会记录for循环上一次的内容,将其赋值给下一轮
- for循环每一次循环都相当于生成了一个新的块级作用域
四、const常量声明
常量是指不变化的量,它一旦声明赋值后,其值就无法进行更改
目的
是为了在团队开发中,定义一个不允许别人更改定义的内容。
// 常量的声明
const PI = 3.141592654; // 常量的命名字母都是大写
常量命名的规则
- 由字母、数字、下划线和$组成,不能以数字开头;
- 不能使用关键字和保留字;
- 见名知意;
- 常量名的字母最好都用大写,单词之间使用下划线分隔,用于和变量区分开来。
常量的特点
-
常量作用域为块级作用域;
-
常量声明时在一个作用域下常量名不能重复;
-
常量值一旦确定,后期无法进行修改。
五、解析赋值
**概念:**es6允许按照一定模式,将数组或者对象里面的值,解析到变量中,这个过程叫解析赋值。
数组解析
格式:
var [变量名1,变量名2,变量名3.....] = [值1,值2,值3,.....]
1.完全解析:解析的数组长度和变量名数量一致,一一对应
// 1. 完全解析:解析的数组长度和变量名数量一致,一一对应
var arr = [1,2,3];
var [a,b,c] = arr;
console.log(a,b,c); // 1 2 3
var [a,b,c] = [4,5,6];
console.log(a,b,c); // 1 2 3
2.不完全解析
① 当解析的数组的长度大于变量数量时
// 2. 不完全解析
// 1. 当数组的长度大于变量数量时
var [a,b] = [3,4,5];
console.log(a,b); // 3 4
//当想取0和2上的值时,使用缺省值
var [a,,b] = [3,4,5];
console.log(a,b); // 3 5
② 当解析的数组长度小于变量数量时
// 2. 当解析的数组长度小于变量数量时
var [a,b,c] = [3,4];
console.log(a,b,c); // 3 4 undefined
// 设置默认值
var [a,b,c=6] = [3,4];
console.log(a,b,c); // 3 4 6
对象解析
格式:
var {'key1':变量名1,'key2':变量名2,...} = {'key1':123,'key2':456,..}
-
对象的完全解析
// 1. 对象的完全解析:key值和对象的key值一一对应 var {'name':a,'age':b} = {'name':'张三','age':18}; console.log(a,b); // 张三 18 // 当key值和变量名一致时,可以简写为 var {name,age} = {'name':'张三','age':18}; console.log(name,age); // 张三 18
-
对象的不完全解析
// 2. 对象的不完全解析:key值和对象的key值没有一一对应 var {'uName':a,'uAge':b} = {'name':'张三','age':18}; console.log(a,b); // undefined undefined // 设置默认值 var {'uName':a='李四','uAge':b=20} = {'name':'张三','age':18}; console.log(a,b); // 李四 20
函数的形参解析赋值
可以在函数的形参内对数组和对象进行解析赋值
// 数组
function fn([a,b]){
console.log(a + b);
}
var arr = [1,2];
fn(arr); // 3
// 对象
function fn2({uName,uAge}){
console.log(uName,uAge);
}
var obj = {
'uName':'张三',
'uAge':20
};
fn2(obj); // 张三 20
字符串的解析
-
按照对象进行解析
// 1. 按照对象进行解析 var str = 'hello world'; var {'length':len} = str; // 返回字符串的长度 console.log(len); // 11
-
按照数组进行解析
// 2. 按照数组进行解析 var [a,b,c,d,e] = '12345'; console.log(a,b,c,d,e); // 1 2 3 4 5
六、模板字符串
var title = '标题';
var str = `<div class="title">${title}</div>`;
console.log(str); // <div class="title">标题</div>
day02
一、箭头函数
格式:
let fn = () => {}
// 例
let fn = (形参1,形参2) => {
代码块;
};
// 当代码块只有一句话时,可以省略{}
let fn = (a) => console.log(a);
fn('哈'); // 哈
let fn = (a,b) => a + b; // 可以将return省略
console.log(fn(1,2)); // 3
箭头函数的特点
-
简单,便捷。
-
箭头函数没有自己的this,在声明this时会捕获上层的this供自己使用,
this一旦被捕获,将无法进行修改,即bind,call和apply无法修改箭头函数的this指向
二、三点(…)运算符
1. 作为参数使用(rset参数)
在es6中,可以将多余的实参转换成一个数组进行使用
// 在形参前加三个点...代表该形参为rset参数,接受多余的实参
function fn(a,...value){
console.log(a,value);
}
fn(1,2,3,4,5,6,7); // 1 [2,3,4,5,6,7]
注:rset参数必须写在形参的最后面,否则会报错
2. 作为拓展运算符使用
它可以将能够遍历的变量进行拆解
// 三点的扩展运算符,把数组或者类数组对象展开成一系列逗号隔开的值序列,它好比rset参数时候的逆运算。
// 数组
var arr = [1,2,3,4,5];
console.log(...arr); // 1 2 3 4 5
// 对象 // 对象不能进行遍历,但是可以用三点运算符对对象进行继承
var obj1 = {
'name':'张三'
}
var obj2 = {
...obj1,
'age':20
}
console.log(obj2); // {'name':'张三','age':20}
// 字符串
var str = 'hello';
console.log(...str); // h e l l o
console.log([...str]); // ['h','e','l','l','o']
三、es6新增数据类型Symbol
Symbol是基础数据类型,它的作用类似于一种唯一标识性的ID
1. 通过调用Symbol()函数来创建一个Symbol实例
var sym = Symbol();
2. 为Symbol实例添加一个描述信息
var sym = Symbol('sybmol info');
3. Symbol是基础数据类型
var sym = Symbol();
console.log(typeof sym); // symbol
4. Symbol实例的值是唯一的
var sym1 = Symbol();
var sym2 = Symbol();
console.log(sym1 == sym2); // false
console.log(sym1 === sym2); // false
5. 应用场景
防止对象的属性名被覆盖的情况
6. 特点:
symbal数据类型不能和任何数据类型进行比较或者运算,包括字符串拼接。
四、set容器和map容器
set容器和map容器为es6新增的数据结构
es5内有Array和object这两种数据结构
set的特点:
- 无序且不可重复,value的集合体,无法通过下标取值;
- set容器过滤数组中的重复内容
array的特点:
- 有序,可以通过下标取值;
- 值可以重复,不过滤数组元素的值。
定义一个set容器
let set = new Set(['张三','张三','李四','王五']);
console.log(set); // Set(3) {"张三", "李四", "王五"}
// 利用set不能重复的特性对数组进行去重
var arr = [1,1,1,2,2,2,3,3,3,4,4,4,1,1];
var set2 = new Set(arr);
console.log(set2); // Set(4) {1, 2, 3, 4}
// 利用三点运算符将set转为array
var arr = [...set2];
console.log(arr); // [1,2,3,4]
set的一些方法
set容器可以使用forEach循环遍历
var set = new Set([1,2,3,4]);
console.log(set); // Set(4) {1, 2, 3, 4}
// set.add(value); 添加值到set容器内
set.add(5);
console.log(set); // {1, 2, 3, 4, 5}
// set.size 获取set容器的大小
console.log(set.size); // 5
// set.delete(value) 删除set容器的值
set.delete(3);
console.log(set); // Set(4) {1, 2, 4, 5}
// set.has(value); 判断set容器内是否存在该值
console.log(set.has(6)); // false
console.log(set.has(5)); // true
// set.clear(); 清空set容器
set.clear();
console.log(set); // Set(0) {}
2. map
创建一个map容器
/*
// 格式:
let map = new Map([
['key','value']
]);
*/
var map = new Map([
['name','张三'],
['age','李四']
]);
console.log(map); // Map(2) {"name" => "张三", "age" => "李四"}
map容器内的一些方法
map容器可以使用forEach循环遍历
var map = new Map([
['name','张三'],
['age','李四']
]);
// map.set(key,value) 添加一个值
map.set('hobby','篮球');
console.log(map); // Map(3) {"name" => "张三", "age" => "李四", "hobby" => "篮球"}
// map.get(key) 通过key值获取值
console.log(map.get('name')); // 张三
// map.has('key') 查找是否存在该key值
console.log(map.has('name')); // true
// map.delete('key'); 通过key值删除键值对
map.delete('name');
console.log(map); // Map(2) {"age" => "李四", "hobby" => "篮球"}
// map.clear(); 清空map容器
map.clear();
console.log(map); // Map(0) {}
3. forEach
set和map都带有forEach方法
五、Iterator迭代器
在es6里面新增了iterator迭代器,iterator迭代器又叫遍历器,主要遍历集合数据集合 类型(array object set map)
每个容器使用的遍历器:
- Array: for…in 循环遍历 / forEach循环遍历 / for
- Object: for…in 循环遍历
- Set容器:forEach()循环遍历
- Map容器:forEach()循环遍历
iterator遍历器给数据提供了统一的接口访问机制.(接口:制定规范)
// 执行原理
function iter(arr) {
//定义数组索引 默认从0开始读取
let index = 0;
return {
//返回定义一个next()方法
'next': function () {
if (index < arr.length) {
return { value: arr[index++], done: false };
} else {
//循环遍历完输出的结构格式
return { value: "undefined", done: true };
}
}
}
}
let arr = [1, 2, 3, 4];//使用iterator接口机制循环遍历数组里面的内容
let arriter = iter(arr);
console.log(arriter.next());//第一次读取的值 返回数据的格式
array、set、map下有默认的Symbol.iterator方法返回一个迭代器
// 数组:
let arr = [4,5,6];
let newiter = arr[Symbol.iterator]();
console.log(newiter.next()); //{ value: 4, done: false }
// Set容器:
let set = new Set(["战三","男",30]);
let newiter = set[Symbol.iterator]();
console.log(newiter.next()); //{ value: "战三", done: false }
// Map容器:
let map = new Map();
map.set("name","小花");
let newiter = map[Symbol.iterator]();
console.log(newiter.next()); //{ value: (2) […], done: false }
对象默认没有Symbol.iterator接口机制,需要手动实现
var obj = {
'name':'张三',
'age':20
}
obj[Symbol.iterator] = function*(){
var keys = Object.keys(this); //获取对象的key
for(i in keys){
yield [keys[i],this[keys[i]]];
}
}
var new_iter = obj[Symbol.iterator]();
console.log(new_iter.next());
console.log(new_iter.next());
console.log(new_iter.next());
拥有Symbol.iterator接口的值,都可以使用for of 循环,该循环机制是iterator的语法糖
/*
格式:
for(变量名 of 被遍历的数据){
console.log(变量名); // 遍历出来的是被遍历的数据的值
}
*/
六、generator 函数
-
generator 函数是一个函数,只是这个函数比较特殊这个函数,声明function关键字和函数名中间有一个*号.
-
generator 函数调用也比较特殊,他不会返回return的返回值,generator 函数返回的是一个iterator数据.而return是可以终止iterator循环,使的done为true。这个return返回的值会作为iterator里面的value的值.
-
generator 函数,内部定义不同状态(数据,变量)
当第一次调用next时,读取generator 函数里面第一个数据。并且在这里暂停,直到下次调用next时,从上次暂停位置,向下读取下一个内容值.直到遇到return或者函数执行完毕时,返回的值为{ value: undefined, done: true }
例:
function * gen(){
console.log("第一次执行");
yield "1";
console.log("第二次执行");
yield "2";
console.log('第三次执行');
}
let g = gen();
console.log(g.next());//第一次执行 { value: "1", done: false }
console.log(g.next());//第二次执行 { value: "2", done: false }
console.log(g.next());//第三次执行 { value: undefined, done: true }
**注:**当调用yield 的值时,没有任何的返回值,返回的永远是一个undefined。
function * gen(){
let a = yield "2";
//console.log(a);
yield a;
}
let g = gen();
console.log(g.next());
console.log(g.next())//{ value: undefined, done: false }
day 03
Promise函数
一:Promise函数
在es6中新增了Promise函数,这个函数是一个异步操作.主要解决回调函数,层层回调(回调地狱).
回调函数:
一个函数的返回值,会作为另外一个函数参数.
function A(d,callback){
let a = callback;
console.log(a);
console.log(d+a);//4 1 1 1
}
function B(c){
return -c;
}
A(4,B(3))
二 : Promise 格式 :
Promise三种状态:
当只是实例化promise这个方法时,会返回一个:pending
Pending 状态——– 初始化状态
resolved(fulfilled) 状态——–成功回调状态
rejected 状态———失败返回状态
let promise = new Promise((resolve,reject)=>{
resolve(“成功”)
})
promise.then((data)=>{
})
console.log(promise)
当程序实例化时就会得到pending状态(挂起 程序执行中),程序执行结束 程序成功(fulfilled) ,程序执行结束,程序失败(rejected).
程序执行中从Pending状态不会自动转换到fulfilled状态和rejected状态.
执行代码逻辑时,判断代码正常的成功状态,主动调用resolve这个方法.使的Pending状态转换为fulfilled状态.反之:判断代码执行过程是错误的状态,主动调用reject方法,使的Pending状态转换为rejected。
then里面内部有2个事件回调函数:onfulfilled 和 onrejected
当你的状态为fulfilled,他自动执行onfulfilled 事件回调函数
当你的转态为 rejected ,他自动执行onrejected 事件回调函数
三 : 错误信息捕获:
err方法和catch方法都会自动触发onreject事件回调函数.
Jquery:
//Ajax 数据请求
$.ajax({
url:”交互的地址(这个地址可以是接口地址,也可以是后端的交互地址)”
type:”get/post”, get:显式提交 post隐式提交
dataType:”json”, //json数据格式 jsonp跨域
data:{ 交互数据
},
success:function(data){
},
error:function(err){
}
})
四 : promise 链式
当promise 里面手动调用了resolve方法 此时的状态fulfilled他会把这个内容返回给第一个promise里面的第一个then,并且 调用第一个then里面的回调方法,当回调方法执行完之后,他会把这个 回调完成的结构,默认为resolve方法 状态,后面的所有的then都是成功的执行状态.
五 : async函数
//格式:
async function fn(){
await://返回的是一个异步操作,同常是promise函数,await只能是在async 关键字函数里面进行修饰,不能再其他任何内容下去使用修饰。
}
特点:
(1) : async:修饰函数关键字
(2) :只要是这个关键字修饰的函数,返回是promise函数
(3) : 默认返回的状态是fulfilled状态(不需要手动去调用),除非代码内部有错误。
day 04
面向对象
一:面向对象
1:面向过程:
获取按钮控件
var btn = document.getElementById("btn");
给按钮绑定一个点击事件
btn.addEventListener("click",function(event){}
获取标签控件
let h = document.getElementById("h1");
更改标签颜色
h.style.color = "red";
2:对象唯一性
对象里面的内容实质看着相同,但是对象是一个唯一性的.
3:javascript 对象里面的属性和方法
let obj = {
name:"李四", //属性
fn:function() //对象方法
{
return "20"
}
}
console.log(obj.fn());
4:面向对象
let arr = Array() //创建一个Array对象
**Array:类** 他实质是没有任何功能,他主要作用,是构造一个对象,类里面可以定义 属性和方法(Array类就是一个容器,他只负责装,不负责使用)
arr :对象 他就拥有实质的功能,他是被类构造出来的。类里面定义的属性和方法,在这里就可以使用.
(1) :声明一个类,使用关键字class来声明
//(类名:遵守命名规则:首字母通常是大写,多个单词直接使用驼峰命名规则)
class Car{
//定义属性
title=”这是法拉利”//类里面定义属性
//定义方法
fn() //方法名{}
}
let c = new Car()
//注意:规范在类中定义方法时,不能用任何的修饰符。比如function
(2) :使用constructor关键字定义一个构造方法.他是内置的方法.
作用:当类被实例化时,这个构造方法会自动调用;自动执行.构造方法初始属性和方法.
(3) :在类定义静态的属性和静态的方法
static 属性名 = 值 //定义静态的属性
static 方法名(){} //定义静态的方法
static //这个关键字修饰的属性或者是方法,它是不属于对象的,而是属于类的.
(4) :继承关键字是extends,子类继承了父类,那么子类就拥有了父类的属性和方法包括构造方法.
子类要想构造方法里面新增新的内容。那么必须要先实现父类的构造方法. 需要使用super实现父类的构造方法
子类从新定义父类的方法,那么这个子类的方法叫重写(或者叫覆盖)
二 : Node.js开发
Node.js:node他即是开发一门开发的语言,又是服务器.
Node后端语言,做数据交互。
Node.js是一个能够在服务器端运行JavaScript的开放源代码、跨平台JavaScript运行环境。事件驱动、非阻塞和异步I/O
Node.js模块和包
a.模块
Node.js官方提供了很多模块,这些模块分别实现了一种功能,如操作文件模块fs,构建http服务模块的http等,每个模块都是一个JS文件,当然也可以自己编写模块。
b.包
包可以将多个具有依赖关系的模块组织在一起,封装多个模块,以方便管理。Node.js采用了CommonJS规范,根据CommonJS规范规定,一个JS文件就是一个模块.
三 : Node.js安装
1:安装成功之后:需要打开一个cmd指令
在 cmd中输入 node 获取是node -v
出现node的版本。这个是安装成功node.js
2:node.js安装成功,但是在cmd中输入指令node
获取是node -v指令还是提示不是内部命令或者是外部命令.
这个时候需要重启。在开启cmd在进入node
3:走到2的过程中还是提示不是内部命令或者是外部命令.
需要手动配置电脑的环境变量.
计算机—->属性—->高级系统设置—–>环境变量—–>把你刚刚安装的node.js路径复制到系统path变量中
重新开启一个cmd 在输入node 或者是node -v
4:javascript和node差异
1) Node和javascript运算宿主不同,node基于谷歌的V8的引擎。而javascript是基于浏览器.
2) Node 是遵守commonJs规范,他可以做文件流,二进制文件流,网络流等,这是javascript不具备的功能.
而javascript有BOM和DOM对象,这个是node.js不具备的功能.但是不能再node.js里面去写docment alert()
3) node和javascript都遵循ECMAscript标准,只是一个是后端,一个是前端.
5:cmd基本的指令
第一个方式:开启cmd
Win里面输入cmd。进入到cmd的窗口.
默认系统盘的地址:C:\Users\Administrator>
第二个方式:
找到目录地址,把上面目录的路径情况:输入cmd
进入到当前目录地址.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nHGUAEY9-1611110479608)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA9D8.tmp.jpg)]
第三种方式:
按住shift建,点击鼠标右键,在此处打开命令窗口:
直接定位到当前所操作的目录.
切换盘符:磁盘的盘符名
f: 回车
cd 目录名 进入到该目录下
cd … 返回上一层目录结构
dir:查看该目录下的详细的内容
cls :清屏
6:运行后端代码
文件的后缀名.js
1:使用cmd:定位到要运行的文件的目录结构下去运行该文件 node 文件.js
2:在编辑器里面有个终端:直接定位到该目录下的:
运行node.js代码:使用调试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ga187ExJ-1611110479613)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA9D9.tmp.jpg)]
下载运行node.js插件 code Runner
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7MBMdc4-1611110479616)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA9DA.tmp.jpg)]
7:node后端语言
把一个内容交互到浏览器中:在浏览器中输入:127.0.0.1:3000交互数据到浏览中
127.0.0.1<=======>localhost 本机域名地址
(1)把后端的内容响应到浏览器中进行显示:
第一种方式:
//需要模块服务:
//加载或者引入模块 http
//http 模块主要是创建服务,有了这个服务之后,才能把后端的数据交互响应到浏览器中.
const http = require(“模块名”);
//创建服务
//req:请求
//res:响应
let server = http.createServer((req,res)=>{
})
//监听端口:
server.listen(端口,”绑定的地址”,()=>{
})
第二种方式:
//加载http模块服务
const http = require(“http”);
//创建一个服务
let server = new http.Server();
//交互数据
//req 请求
//res 响应
server.on(“request”,(req,res)=>{})
server.listen(端口) //简写的方式:默认绑定的地址就127.0.0.1
server.listen(端口,”绑定的地址”,()=>{})
8:IO异步操作流
(对于文件操作 写入和输出)
let fs = require("fs"); //主要对系统文件操作
//读取文件里面内容
/*
第一个参数:读取文件目录地址
第二个参数是设置编码格式 utf8
第三个参数是:回调函数
(err,data)
err:返回读取目录的路径是否正确,如果没有错误返回一个null
如果有错误,会返回一个错误的地址
data:获取读到 文件里面的内容值
*/
fs.readFile("./1.txt","utf8",(err,data)=>{
console.log(err);
console.log(data);
})
day 05
一 . 模块
1:核心模块
let fs = require(“fs”) //对系统文件进行操作
let http= require(“http”)//对数据交互服务器
//事件订阅:(有了这个事件订阅事件模块,可以自定义事件)
let events = require("events"); //事件模块
var emitter = new events.EventEmitter();//有了这个事件方法才可以自定义一些事件.
//on() 触发多次事件
//emit() 监听事件
//once:触发一次
2:自定义模块
Es5里面没有模块,他是需要用<script src=""></script> 进行加载.
Node为了管理模块,引入了CommonJs规范.
一个js文件就是一个模块.
文件里面的属性和方法,是私有的。外部文件是不能直接访问使用,外部文件要想去访问这个模块文件,那么这个模块文件就需要把里面的属性和方法暴露出来.这里的暴露格式(导出内容)指的就是遵守了CommonJs规范定义.
格式1:使用exports暴露
1:暴露属性
// exports.属性名 = 值
// exports.方法名 = ()=>{ };
格式2:使用module.exports
1:暴露属性
// module.exports.属性名 = 值
// mo/dule.exports.方法名 = ()=>{ };
暴露多个内容:
module.exports = { }
加载模块
核心模块加载:
let fs = require(“fs”)
自定义模块加载:
let m = require(“./模块名”)
注意: 加载核心模块,加载模块时不能有任何的路径地址./ …/ 加载核心模块不能有文件的后缀名.
自定义模块加载:必须要有路径地址./ …/,自定义模块加载可以要文件的后缀名,也可以省略.
模块加载原理:
function(exports,require,module,__filename,__diename){
//exports : 将变量或者方法向外暴露
//require: 模块引入
//module: 模块的本身
//__filename: 得到当前模块的完整的路径
// __diename: 得到当前完整的项目的目录的路径
}
module.exports和exports暴露的区分???
1) exports暴露的内容,exports只是一个收集者,将收集的属性和方法会赋值给module.exports
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSQlL5MZ-1611110479620)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps757E.tmp.jpg)]
2) 先暴露module.exports 是否改变了值的地址的指向.
module.exports会去改变原来的地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VpNlTaMz-1611110479623)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps757F.tmp.jpg)]
3)先暴露exports 在暴露module.exports 是否改变了值的地址的指向
如果module.exports有自己定义对象内容指向.那么exports收集的属性和方法
将丢弃.使用自己定义的
4)在同一地址暴露内容.后面的覆盖前面的
注意:一个模块文件,只能允许出现一个方式暴露
3:第三方模块
2020年7月17日
2020/7/17
time-stamp 时间包
1:初始化包
(生成一个配置文件.可以看见有关于下载的所有包的信息)
格式1:
npm init 每个配置项都是自己手动进行配置 可以识别项目的根目录可以是中文名
格式2:
npm init -y 一键生成所有的配置项。注意:项目的根目录名不能是中文名字
2:下载:
npm i time-stamp
在项目中加载使用
let timestmp = require("time-stamp");
console.log(timestmp("YYYY/MM/DD"));
//YYYY:年 MM:月 DD:日
基本指令:
**npm -v 查看npm的版本**
• npm version 查看所有模块的版本
• npm init 初始化项目(创建package.json)
• npm i/install 包名 安装指定的包 @版本号,不加版本默认为最新
• npm i/install 包名 –save 安装指定的包并添加依赖
• npm i/install 包名 -g 全局安装(一般都是一些工具)
• npm i/install 安装当前项目所依赖的包
• npm s/search 包名 搜索包
• npm r/remove 包名 删除一个包
淘宝镜像安装
npm install -g cnpm –registry=https://registry.npm.taobao.org
设置了镜像可以使用:
cnpm i time-stamp
也可以使用:
npm i time-stamp
二 . Fs模块(主要操作系统文件)
let fs = require(“fs”);
//Buffer模块(缓冲区) 内置的模块(不需要引入)
存储内容是以二进制存储,读取时以16进制读取的.
在Buffer里面汉字占用3个字节,英文占用1个/*let b = new Buffer.from(“abcdefg”);
//console.log(b.toString());
let b1 = Buffer.alloc(10);//10字节大小内容
b1.write("qwer");
console.log(b1.toString());
let str = "我是小明a";
let b = Buffer.from(str);
console.log(b.length);//13
console.log(str.length)//5
fs模块几种写入方式:
格式1(同步写入):
let fs = require(“fs”)
//第一个参数:需要打开一个文件,文件地址.
//当文件不存在时,你运行该文件时,默认定位在根目录下自动创建该文件,并且把刚刚写入的内容会写入到该文件下.
//第二个参数:以什么方式写入
//r:只读
//w:覆盖写入
//a:追加写入
let fd = fs.openSync(“/打开一个文件地址”,”a”);
fs.writeSync(fd,”写入的内容”,”utf8”);
格式2:
//第一个参数:打开一个文件地址
//第二个参数:以什么方式写入
//r:只读 w:覆盖写入 a:追加写入
//第三个参数:回调函数
//err:指的是打开的文件地址是否错误
//fd :文件地址没有错误,文件就会赋值给fd参数
fs.open(__dirname+"/3.txt","a",(err,fd)=>{
if(!err){
fs.write(fd,"这是格式2",(err)=>{
if(err){
console.log("写入失败")
}else{
console.log("写入成功")
}
})
}
})
格式3:
//第一个参数:打开文件地址
//第二个参数:写入的内容
//第三个参数:设置以什么方式写入和设置编码格式{flag:"a",encoding:"utf8"}
//第4个参数:回调函数
//err:返回成功或者失败
fs.writeFile(__dirname+"/4.txt","这是格式3写入的内容",{flag:"a",encoding:"utf8"},(err)=>{
if(err){
console.log("写入失败");
}else{
console.log("写入");
}
})
格式4:
//第一个参数:写入文件地址
//第二个参数:以什么方式写入{flags:"a"}
let ws = fs.createWriteStream(__dirname+"/5.txt",{flags:"a"});
ws.write("格式41")
流式读取和写入:
//读取一个流文件
let rd = fs.createReadStream(__dirname+"/沙漠骆驼.mp3");
//写入一个文件中
let ws = fs.createWriteStream(__dirname+"/abcd.mp3");
//一个流式文件写入到另一个文件中,那么必须要触发一个data事件
rd.on("data",(data)=>{
ws.write(data)
})
记忆:
1)文件读取和写入:
//第一个参数:读取文件地址
//第二个参数:回调函数
//err:返回路径是否正确
//data:读取文件里面的内容
fs.readFile(__dirname+"/1.jpg",(err,data)=>{
if(!err){
//第一个参数:写入文件地址
//第二个参数:写入的内容
//第三个参数:回调函数
//err:返回是否正确
fs.writeFile(__dirname+"/mm.jpg",data,(err)=>{
if(err){
console.log("写入失败")
}else{
console.log("写入成功")
}
})
}
})
2)读取目录的详细信息
//第一个参数:读取目录地址
//第二个参数:回调函数
//err:读取的目录是否正确
//files:读取该目录下的详细内容 并且返回的是一个数组
fs.readdir(__dirname+"/ceshi",(err,files)=>{
console.log(files);
})
3) :判断是文件还是目录
//stats.isFile() 判断是否是文件
//stats.isDirectory()判断是否目录
fs.stat(__dirname+"/ceshi/c",(err,stats)=>{
console.log(stats.isFile());//false
console.log(stats.isDirectory());
})
4)文件操作
(1):删除一个文件
//fs.unlink() 只能删除文件,不能删除目录.
fs.unlink(__dirname+"/ceshi/c",(err)=>{
if(err){
console.log("删除失败")
}else{
console.log("删除成功");
}
});
(2) :删除目录
//fs.rmdir()删除目录(但是只能删除空的目录)
fs.rmdir(__dirname+"/ceshi/c",(err)=>{
if(err){
console.log("删除失败")
}else{
console.log("删除成功");
}
})
(3)剪切功能 但是不能跨磁盘操作
fs.rename(__dirname+"/ceshi/a/6.txt",__dirname+"/ceshi/b/6.txt",(err)=>{
if(err){
console.log("剪切失败")
}else{
console.log("剪切成功");
}
})
(4):创建目录
fs.mkdir(__dirname+"/ceshi/abc",(err)=>{
if(!err)
{
console.log("创建成功");
}
})
day 06
一:path模块
(对系统文件路径操作)
__dirname //获取当前项目的完整路径
__filename //获取当前模块的完整的路径
let path = require(“path”)
path.basename(path) //返回路径地址的最后一部分
path.dirname(path) //返回的是路径部分的项目根目录地址
path.basename(path,”文件的后缀”) //返回的是文件的名字部分
Path.basename.win32()//兼容系统的写法
path.extname() //获取文件的扩展名(文件的后缀名)
path.join() //将路径片段用/作为定界符链接起来
path.parse() //将一个路径进行解析到对应的参数中
path.resolve() //将一个路径转换为绝对地址
path.isAbsolute()//判断路径是否是一个绝对路径
path.normalize() //转换路径统一化,路径是'/' '\'把这样所有路径都解析为'\'
二:url模块
(对路径进行解析)
let url = require(“url”);
//解析地址到对应的参数值里面:
let {URL} = require(“url”);
let url = “c:/Users/Administrator/0511/day6/?username=admin&password=123”
let pathurl = new URL(url);
2:使用url下parse方法解析,解析字符串的地址内容
let url = require(“url”);
//第一个参数:解析的字符串的路径地址
//第二个参数:将解析路径中query属性值变成对象 默认是false不做解析
//第三个参数:默认false 设置为true,他会自动识别路径地址的http开头还是https开头.
url.parse(“path路径”,true,true)
三:认知(路由)
路由:指的是地址路由进行切换对应的内容.
127.0.0.1:3000/student 地址栏输入地址,进入到student页面下内容
127.0.0.1:3000/tercher 地址栏输入地址,进入到 tercher页面下内容
规划路由:
127.0.0.1:3000/student
127.0.0.1:3000/tercher
记忆:
req.url() //获取地址栏的输入的值,默认没有给地址栏参数值.获取的是一个/ 等价于获取的是127.0.0.1:3000,如果有参数值,获取的是地址栏给定的参数值.
req.body() //获取表单post提交的数据内容值
req.query()//获取表单提交地址栏的值
req.params() //获取地址栏参数值
四:加载静态资源文件
(实现动态方式)
127.0.0.1:3000 默认加载静态网页的首页页面
静态的资源文件已动态的方式加载:这是为了页面数据交互.最终页面的数据提交和交互到数据库中.
/*
127.0.0.1:3000 加载首页页面
*/
let http = require("http");
let url = require("url");
let path = require("path");
const fs = require("fs");
let server = http.createServer((req,res)=>{
let pathname = url.parse(req.url).pathname;
//console.log(pathname); // / <==> 127.0.0.1:3000
//默认加载首页页面
if(pathname == "/")
{
pathname = "/index.html";
}
//获取文件的后缀名
let extname = path.extname(pathname);//.html
//加载文件
fs.readFile(__dirname+"/static"+pathname,(err,data)=>{
let mian = getmian(extname);
res.writeHead(200,{"Content-type":mian})
res.end(data);
})
})
function getmian(extname)
{
switch(extname)
{
case ".html":
return "text/html";
case ".css":
return "text/css";
default:
return "text/plain" //既可以解析js (json,ajax) 也可以解析图片类型
}
}
server.listen(3000);
五:express(框架) 轻量级应用web框架
优点:
1:快速的开发
2:后期对项目迭代维护更新比较方便
3:有利于团队的开发
响应数据内容:
可以设置中间件来响应 HTTP 请求。
定义了路由表用于执行不同的 HTTP 请求动作。
可以通过向模板传递参数来动态渲染 HTML 页面。
缺点:
需要由第三方的中间件去支撑
使用express框架:
下载:express
1:先初始化项目
npm init -y
2:下载express框架
npm i express –save-dev
3:加载express框架
let express = require(“express”);
//创建一个应用服务
let app = express();
//规划路由 127.0.0.1:3000
app.get(“/”,(req,res)=>{
res.send(“响应数据到浏览器中”);
})
app.listen(3000,”127.0.0.1”,()=>{ })
六:特殊路由匹配
特殊路由匹配 里面正则规则
?:匹配字符0个或者1个.匹配?前面的字符内容
+:匹配字符1个或者多个,匹配+前面的字符内容
*:匹配0个或者多个,匹配*所在的位置.
():整体匹配
/a/ :只要有匹配的字符内容,匹配成功
/abc$/ :以字符结尾 匹配成功.
七:规划二级路由
// 127.0.0.1:3000/user/login
// 127.0.0.1:3000/user/reg
//Router()这个方法既可以规划路由,也可以规划二级路由
let express = require("express");
let router = express.Router();
八:内置中间件
(功能作用:加载静态资源文件)
静态资源文件:img css js
模板:html
let express = require(“express”);
let app = express();
app.use(express.static(“./加载静态资源文件路径”))
九:中间件
中间件的分类:
应用层中间件(router)
错误中间件
内置中间件(重点)
自定义中间件
第三方中间件(重点)
规划路由:有2种方式定义 get post
app.get(“/login”,(req,res)=>{ })
app.post(“/login”,(req,res)=>{ })
表单里面提交方式get 和post
<form action="" method="GET">
//action:后端和前端数据交互地址
//method:提交方式,默认是get提交方式
//http://127.0.0.1:3000/login?username=admin&password=123&
get:
1:提交的内容数据可以在地址栏看见
2: 提交的数据不安全
3:提交的数据有大小限制
//http://127.0.0.1:3000/login
post:
1:提交的数据内容在地址栏不可见的
2:提交的数据比较安全
3:提交的数据内容基本没有大小的限制
什么时候用get:
加载页面
数据的查询
什么时候用post:
提交的数据
提交内容到数据库中
提交方式:中间件 all
优点:不管提交的是什么方式,他都接收数据内容.
缺点:数据不安全
day 07
中间件
新的文件目录要用到任何包,都得初始化一次,都得重新下载。直接把原来的包根目录直接拷贝,也可以不用在重新下载。注意:如果你用的指令:是cnpm下载。你不能拷贝。都要重新下载.
1:中间件分类
应用层中间件
let express = require(“express”);
let router = express.Router();
//错误中间件
//格式1:
app.use((req,res,next)=>{
res.status(404).send(“提示”)
})
//格式2:下载错误处理中间件 http-errors
//下载错误中间件
npm i http-errors
//加载中间件
let createerror = require(“http-errors”);
//使用中间件进行配置
app.use((req,res,next)=>{
createerror(404,”提示信息”)
})
自定义中间件
//中间定义
app.use((req,res,next)=>{
req.c = new Date();
next();
})
app.get("/",(req,res)=>{
console.log(req.c);
})
内置中间件(重点)
let express = require(“express”);
let app = express();
app.use(express.static(“./加载静态资源文件”))
第三方中间件(重点)
1)获取表单提交数据内容
//下载:body-parser
npm i body-parser --save-dev
//加载body-parse
let bodyparser = require(“body-parser”);
//使用中间件配置
/*
extended:false 将表单提交内容解析为字符串或者数组(通常使用,是为了数据安全性)
extended:true 将表单提交的数据解析为任何数据类型
*/
app.use(bodyparser.urlencoded({extended:false}));
2) 临时存储数据(缓存)
cookie:临时存储(缓存)
1:存储在客户端(浏览器端临时存储数据)
2:他存储的数据不安全
3:读取数据内容比较快
登录拦截:
//下载cookie-parser
npm i cookie-parser
//加载cookie-parser
let cookie = require(“cookie-parser”);
//使用中间件配置:
app.use(cookie())
//Cookie存储值:
res.cookie(“标签名”,存储的值)
//获取cookie的值:
req.cookies.标签名
3) 临时存储(缓存)
Session:
1: 存储的数据在服务端
2: 存储的数据比较安全
3: 他缓存的时间依赖于cookie
Cookie一般用于数据不怎么安全的,建议使用cookie.
Session一般用于数据比较安全的内容.建议使用session
登录拦截:
//下载session
npm i express-session
//加载session
Let session = require(“express-session”);
//使用中间件配置
app.use(session({
secret:"abasdsdfwqerwq",//对session使用相关的cookie签名
resave:true,//强制session保存在session store中
saveUninitialized:false,//是否保存未初始化的会话任务
cookie:{
maxAge:1000*60*3//过期时间
}
}))
//存储session的值:
req.session.标签名 = 存储的值
//获取session的值
req.session.标签名
2.验证码库房:直接调取验证码
//下载svg-captcha
npm i svg-captcha
//加载:svg-captcha
let svgCaptcha = require(“svg-captcha”);
//svg-captcha:配置使用
const captcha = svgCaptcha.create();//创建一个验证码
res.cookie("code", captcha.text); // 把真正的验证码保存到cookie上,用于下面接口的调用
res.type("svg"); // 告诉浏览器, 这里返回的是图片的数据
res.send(captcha.data); // 提取验证码图片的data数据返回给前端
Ejs 模板包
模板引擎:(自己框架底层封装的一套模板语法,主要是对页面渲染和数据交互)
Pug
Ejs(重点)
…等等
特点:
1:快速的开发
2:项目维护和迭代比较方便
3:有利于团队之间的开发
//下载pug模板引擎
npm i pug
//配置模板引擎:
app.set(“view engine”,”pug”);
//加载视图文件
app.set(“views”,”./加载视图文件地址”)
//下载ejs模板引擎
npm i ejs
//配置模板引擎:
app.set(“view engine”,”ejs”);
//加载视图文件
app.set(“views”,”./加载视图文件地址”)
//渲染视图页面:
res.render(“加载页面的地址”,{标签名:”值”})
//注意:加载页面的地址可以要后缀,也可以不要后缀名.
页面中输出单个数据内容:
<%=标签名%>
页面中用逻辑数据判断:
<%for(){%>
// 输出内容
<%=输出内容%>
<%}%>
保留html网页使用ejs模板引擎:
day 08
一:获取地址栏传输的参数值
格式:
app.get(“/index/:标签名”,(req,res)=>{
req.params.标签名
})
二:获取文件域的内容(模块)
//1:下载formidable
npm i formidable
//2:加载formidable
let formidable = require(“formidable”);
let form = formidable.IncomingForm();//获取表单提交文件域的内容
form.uploadDir = path.normalize(__dirname+"/tmpdir");
//把原来的虚拟路径,更改到当前项目路径下。
//第一个参数:请求数据 req
//第二个参数:回调函数
//(err,fileds,files)
//err:上传内容成功或者失败
//fileds:获取文本域提交数据内容
//files:获取文件域上传内容信息
form.parse(req,(err,fileds,files)=>{
console.log(files);
})
1:express框架
安装1:
//npm i express --save-dev
let express = require(“express”);
let app = express();
格式2:
安装express项目生成器:
express项目的生成器:
作用: 用来生成express项目, 项目里包含了(文件+文件夹+配置代码+基础代码)
使用:
npm i express-generator -g (工具类的模块,要安装到全局)
express –view=ejs myapp 使用ejs模板引擎生成一个项目结构
express命令是安装了express-generator模块到global上才有的这个命令, –view指定模板引擎, myapp是项目工程文件夹的名字(注意不能写中文或特殊符号
回车执行以后, 会在当前目录中, 生成myapp一整套文件夹+文件+代码的配置, 还有package.json记录了当前基础项目需要的所有包
cd myapp 然后 npm install 然后 npm run start启动此项目 (默认端口3000)
启动的入口: bin/www 文件 (并非是app.js)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D66iLcHh-1611110479628)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps249F.tmp.jpg)]
bin–>www 是启动项目(入口文件)
public->存放静态资源文件
routes->定义路由程序文件
views->存放静态文件(html ejs)
app.js->文件加载
express项目的生成器:
作用: 用来生成express项目, 项目里包含了(文件+文件夹+配置代码+基础代码)
使用:
npm i express-generator -g (工具类的模块,要安装到全局)
express –view=ejs myapp 使用ejs模板引擎生成一个项目结构
express命令是安装了express-generator模块到global上才有的这个命令, –view指定模板引擎, myapp是项目工程文件夹的名字(注意不能写中文或特殊符号
回车执行以后, 会在当前目录中, 生成myapp一整套文件夹+文件+代码的配置, 还有package.json记录了当前基础项目需要的所有包
cd myapp 然后 npm install 然后 npm run start启动此项目 (默认端口3000)
启动的入口: bin/www 文件 (并非是app.js)
模块化的理解
1.什么是模块?
将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
2.为什么使用模块及模块化?
模块及模块化
以module.exports和require来说
(1):达到代码重用性,避免全局变量的污染
模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,
分别反映其内部特性。
模块化是一种处理复杂系统分解为更好的可管理模块的方式。
模块化的进化过程
Global污染——> namespace模式——>IIFE模式 (记录笔记)
全局
* 全局function函数模式: 将不同的功能封装成不同的全局函数
-
问题: Global被污染了, 很容易引起命名冲突
namespace( 命名空间 )
* namespace模式: 简单对象封装
* 作用: 减少了全局变量 解决命名冲突
* 问题: 不安全(数据不是私有的, 外部可以直接修改)
iife- IIFE模式: 匿名函数自调用(闭包) 立即执行函数 ()()
- IIFE : immediately-invoked function expression(立即调用函数表达式)
- 作用: 数据是私有的, 外部只能通过暴露的方法操作
*编码: 将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口 - 问题: 如果当前这个模块依赖另一个模块怎么办(顺序问题)?
iife增强(引入依赖)
- 现代模块实现的基石
3.引入多个
(1)请求过多
首先我们要依赖多个模块,那样就会发送多个请求,导致请求过多
(2)依赖模糊
我们不知道他们的具体依赖关系是什么,也就是说很容易
因为不了解他们之间的依赖关系导致加载先后顺序出错。
(3)难以维护
以上两种原因就导致了很难维护,很可能出现牵一发而动全身的情况导致项目出现严重的问题。
模块化固然有多个好处,然而一个页面需要引入多个js文件,
就会出现以上这些问题。而这些问题可以通过模块化规范来解决,
下面介绍开发中最流行的Commonjs, AMD, ES6, CMD规范
4.模块化的好处(记忆)
避免命名冲突(减少命名空间污染)
更好的分离, 按需加载
更高复用性
高可维护性
每个模块都有特定的功能!
5.模块化规范
1.CommonJS
(1)概述
Node 应用由模块组成,采用 CommonJS 模块规范。
每个文件就是一个模块,有自己的作用域。
在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
在服务器端,
模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
(2)特点
所有代码都运行在模块作用域,不会污染全局作用域。
模块可以多次加载,但是只会在第一次加载时运行一次,
然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。
要想让模块再次运行,必须清除缓存。
模块加载的顺序,按照其在代码中出现的顺序。
(3)基本语法
暴露模块:module.exports = value 和module.exports.name = value 和 exports.xxx = value
module.exports和exports区别???
引入模块:require(xxx),
如果是第三方模块,xxx为模块名;
如果是自定义模块,xxx为模块文件路径./ ../
(4)模块的加载机制
//CommonJS模块的加载机制是,require()输入的是被输出exports的值的拷贝。
//也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
自动会生成函数
function(exports,require,module,__dirname,__filename)
{
}
这点与ES6模块化有重大差异
一:node模块打包生成在服务器端实现
(5)服务器端实现
(6)浏览器端实现(借助Browserify)
第一步:规范文件目录结构
dist:打包之后生成文件目录
src:将打包的程序存放的目录
index.html
第二步:安装browserify插件
全局: npm install browserify -g
工具类 安装的路径
C:\Users\sam\AppData\Roaming\npm\包名
第三步:在安装局部
局部: npm install browserify --save-dev
-save 的意思是将模块安装到项目目录下,
并在package文件的dependencies(依赖)节点写入依赖。
-save-dev 的意思是将模块安装到项目目录下,
并在package文件的devDependencies(开发环境的依赖)节点写入依赖。
第四部:打包
打包:browserify src/app.js > dist/bundle.js
browserify打包的命令
语法是:
browserify 源文件路径>打包到的文件路径
browserify src/app.js> dist/bundle.js
2.AMD Asynchronous Module Definition 异步模块定义
CommonJS规范加载模块是同步的,也就是说,
只有加载完成,才能执行后面的操作。
AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,
模块文件一般都已经存在于本地硬盘,所以加载起来比较快,
不用考虑非同步加载的方式,所以CommonJS规范比较适用服务器端。
但是,如果是浏览器环境,要从服务器端加载模块,
这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。
此外AMD规范比CommonJS规范在浏览器端实现要来着早。
RequireJS是一个工具库,主要用于客户端的模块管理。它的模块管理遵守AMD规范,
RequireJS的基本思想是,通过define方法,将代码定义为模块;
通过require方法,实现代码的模块加载。
AMD模块定义的方法非常清晰,不会污染全局环境,
能够清楚地显示依赖关系。AMD模式可以用于浏览器环境,并且允许非同步加载模块,
也可以根据需要动态加载模块。
requirejs的网址
https://github.com/requirejs/requirejs.git
https://webscripts.softpedia.com/script/Development-Scripts-js/Other-Libraries/RequireJS-65561.html
3.CMD Common Module Definition 模块定义规范。 模块的基本书写格式和基本交互规则。
CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。
CMD规范整合了CommonJS和AMD规范的特点。在 Sea.js 中,
所有 JavaScript 模块都遵循 CMD模块定义规范。
下载sea.js, 并引入
官网: http://seajs.org/
github : https://github.com/seajs/seajs
Sea.js 推崇一个模块一个文件,遵循统一的写法
define(id?, deps?, factory)
因为CMD推崇
一个文件一个模块,所以经常就用文件名作为模块id
CMD推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写
factory是一个函数,有三个参数,function(require, exports, module)
require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口:require(id)
exports 是一个对象,用来向外提供模块接口
module 是一个对象,上面存储了与当前模块相关联的一些属性和方法
module.exports
4.ES6模块化
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,
以及输入和输出的变量。
CommonJS 和 AMD 模块,都只能在运行时确定这些东西。
比如,CommonJS 模块就是对象,输入时必须查找对象属性。
var obj = require() obj.
module.exports
(1)ES6模块化语法
export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
export:暴露模块 import:引入
html
<script type="module">
import {a,b,c} from "./a"
</script>
(2) ES6-Babel-Browserify使用教程
使用Babel将ES6编译为ES5代码,使用Browserify编译打包js。
第一步:npm init -y 初始化package.json文件
①定义package.json文件
②安装babel-cli, babel-preset-es2015和browserify
第二步:
npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev
npm install browserify --save-dev
preset 预设(将es6转换成es5的所有插件打包)
babel文档网址:
https://segmentfault.com/a/1190000008491089
第3步:创建.babelrc文件
③定义.babelrc文件
{
"presets": ["es2015"]
}
④定义模块代码
⑤ 编译并在index.html中引入
使用Babel将ES6编译为ES5代码(但包含CommonJS语法) :
babel Es6文件路径 -d Es5路径
第4步:
配置package.json文件
下scripts标签里面加入:
"dist": "babel src -d dist"
在cmd命令运行:
npm run dist 把src文件导入到dist文件下面
第5步:
使用Browserify编译js :
(2)browserify dist/main.js -o dist/bundel.js
第6步:
(3)index.html文件中引入bundle.js
三、总结
CommonJS规范主要用于服务端编程,加载模块是同步的,这并不适合在浏览器环境,
因为同步意味着阻塞加载,浏览器资源是异步加载的,因此有了AMD CMD解决方案。
AMD规范在浏览器环境中异步加载模块,而且可以并行加载多个模块。
不过,AMD规范开发成本高,代码的阅读和书写比较困难,模块定义方式的语义不顺畅。
CMD规范与AMD规范很相似,都用于浏览器编程,依赖就近,延迟执行,
可以很容易在Node.js中运行。不过,依赖SPM 打包,模块的加载逻辑偏重
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,
完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
day 09
模块化
(1):Commonjs 语法打包
module.exports = value 和module.exports.name = value 和 exports.xxx = value
第一步:规范文件目录结构
dist:打包之后生成文件目录
src:将打包的程序存放的目录
index.html
第二步:安装browserify插件
全局: npm install browserify -g
第三步:在安装局部
局部: npm install browserify --save-dev
-save 的意思是将模块安装到项目目录下, 并在package文件的dependencies(依赖)节点写入依赖。
-save-dev 的意思是将模块安装到项目目录下,并在package文件的devDependencies(开发环境的依赖)节点写入依赖。
第四步:打包
打包:browserify src/app.js > dist/bundle.js
第五步: index.html页面加载bundle.js文件
(2):AMD(RequireJS工具库)
作用:
AMD:主要解决依赖关系.(加载先后顺序).
主要用到的是RequireJS工具库。用这个工具库实现依赖关系
定义方法:
第一个参数暴露的名字
第二个参数回调函数:
定义功能方法
define([“”],function(){ })
(3):CMD(Sea.js工具库)
作用:
CMD:主要解决依赖关系.(加载先后顺序).
主要用到的是Sea.js工具库。用这个工具库实现依赖关系
格式:
define(function(require, exports, module){
//require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接
//exports 是一个对象,用来向外提供模块接口
//module 是一个对象,上面存储了与当前模块相关联的一些属性和方法
})
(4) :Es6模块打包
ES6模块暴露方式:
**暴露变量:**
export var name = 值
暴露方法:
export function fn(){ }
加载文件:
import {暴露内容,暴露内容} from "./a" //加载a文件模块
1) 规范文件结构
//dist:打包之后生成文件目录
//src:将打包的程序存放的目录
//index.html
2)初始化项目包
npm init -y
3)下载相关的包
//npm install browserify -g 已经安装过,就不需要再安装(只需安装一次)
//npm install babel-cli -g 已经安装过,就不需要再安装 (只需安装一次)
//npm install babel-preset-es2015 --save-dev
//npm install browserify --save-dev
4) 创建.babelrc文件(和打包的目录同层)
③定义.babelrc文件
{
“presets”: [“es2015”]
}
5)配置package.json文件
package.json文件下scripts标签里面加入:
“dist”: “babel src -d dist”
npm run dist 把src文件导入到dist文件下面
6)打包
browserify dist/main.js -o dist/bundel.js
7)在index.html中引入bundel.js
Webpack打包:
Demo1:打包ES6模块
第一步:规范文件结构
webpackDemo
- src 源文件
-app.js入口文件
- dist 打包生成的文件
—bundle.js打包生成的js
- index.html
- webpack.config.js -->webpack配置文件
- package.json
第二步:下载webpack@3
npm install webpack@3 -g
npm uninstall webpack@3 :卸载安装的文件
第三步:打包命令
webpack 源文件 目标文件
webpack ./src/app.js ./dist/bundle.js
Demo2:简化打包的命令,配置出口和入口文件
第一步:目录结构下新建一个webpack.config.js文件
webpackDemo
|- src 源文件
|-app.js入口文件
|- dist 打包生成的文件
|—bundle.js打包生成的js
|- index.html
|- webpack.config.js -->webpack配置文件
|- package.json
第二步:配置webpack.config.js文件出口和入口
let path = require("path");
module.exports = {
//path.resolve 将相对路径的片段解析为绝对路径
//规定入口文件 c:/demo1/src/app.js
entry: path.resolve('./src/app.js'), //将要打包的文件地址
//出口
output:{
//出口的路径
path:path.resolve(__dirname,"./dist"), //打包之后生成路径地址
//输出文件的名字
filename:"bundle.js"
}
};
Demo3打包css文件
第一步:文件目录结构规范
webpackDemo
|- src 源文件
|-app.js入口文件
|- dist 打包生成的文件
|—bundle.js打包生成的js
|- index.html
|- webpack.config.js -->webpack配置文件
|- package.json
第二步:在src目录下创建一个css文件
Style.css
创建完成之后:下载style-loader css-loader
npm i style-loader css-loader -D
第三步:
app.js中引用用到的样式;
require(’./style.css’);
或者
import css from “./style.css”
注意:加载后缀名不能省略
第四步:
//在webpack.config.js里配置loader放在output大括号结束,后面
module: {
//规则
rules: [{
//以.css为后缀名的文件 style.css
test: /\.css$/,
//使用style-loader css-loader
//loader的执行顺序是从右到左
use: ['style-loader','css-loader']
/*
css 解析css文件
style 动态的创建style标签 塞进去
*/
}]
}
如:以下图片
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y752630g-1611110479630)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps8A32.tmp.jpg)]
第五步:使用webpack进行打包
Demo4:打包css中图片
第一步:文件目录结构规范
webpackDemo
|- src 源文件
|-app.js入口文件
|- dist 打包生成的文件
|—bundle.js打包生成的js
|- index.html
|- webpack.config.js -->webpack配置文件
|- package.json
第二步:下载url-loader file-loader
npm i url-loader file-loader -D
第三步:配置webpack.config.js文件
webpack.config.js中 (放在rules配置css下面)
{
test: /\.(png|jpg|gif)$/, //正则匹配png.gifjpg的图片
use: [{
loader: 'url-loader',
options: {
limit: 400*1024 //小于8192的进行打包 图片大小
}
}]
},
day 10
1:压缩js文件
第一步:下载webpack@3到本地项目中
npm i –save-dev webpack@3.1.0
第二步:webpack.config.js文件中新添加一个插件
//加载webpack插件
var webpack = require("webpack");
plugins:[
//对js进行压缩
new webpack.optimize.UglifyJsPlugin(),
]
第三步:使用webpack 进行打包
在回到dist目录下去查看bundle.js有没有进行压缩
2:压缩css文件
第一步:下载extract-text-webpack-plugin@3.0.2
npm i –save-dev extract-text-webpack-plugin@3.0.2
第二步:安装压缩 css 文件的插件
npm install –save-dev optimize-css-assets-webpack-plugin@3.2.0
第三步:在 webpack.config.js 中配置这两个插件.
加载这2个插件:
const ExtractTextPlugin = require('extract-text-webpack-plugin') // css文件单独打包
const OptimizeCssplugin = require('optimize-css-assets-webpack-plugin') // 压缩css文件
在webpack.config.js文件中
```js
//放到rules 把之前第一个rules下的更改了.
{
test: /.css$/,
use: ExtractTextPlugin.extract({
fallback: ‘style-loader’,
use: ‘css-loader’
})
},
//在plugins里面加入配置单独打包生成css文件还有一个是压缩css
plugins:[
new webpack.optimize.UglifyJsPlugin(),
//单独打包 生成的路径的
new ExtractTextPlugin(“style.css”),
//压缩
new OptimizeCssplugin()
]
“`
第四步:使用webpack进行压缩
3:处理小图标(新建文件,不要在原来的文件上进行操作)
第一步:规范目录结构
webpackDemo
|- src 源文件
|-app.js入口文件
|- dist 打包生成的文件
|—bundle.js打包生成的js
|- index.html
|- webpack.config.js -->webpack配置文件
|- package.json
第二步:初始化项目包
npm init -y
第三步:下载webpack-spritesmith 处理小的图标
npm install webpack-spritesmith@1.0.0 –save-dev
第四步:webpack@3到项目本地中
npm install webpack@3 –save-dev
第五步:下载html-webpack-plugin@3.2.0插件
npm i –save-dev html-webpack-plugin@3.2.0
**目的:**提供 html-webpack-plugin 生成依照的模块文件index.template.html
第六步:配置webpack.config.js
let path = require("path");
const WebpackHtmlPlugin = require('html-webpack-plugin')
const SpritesmithPlugin = require("webpack-spritesmith");
module.exports = {
//path.resolve 将相对路径的片段解析为绝对路径
//规定入口文件 c:/demo1/src/app.js
entry: path.resolve('./src/app.js'), //将要打包的文件地址
//出口
output: {
//出口的路径
path: path.resolve(__dirname, "./dist"), //打包之后生成路径地址
//输出文件的名字
filename: "bundle.js"
},
plugins: [
new SpritesmithPlugin({
//目标的小图片
src: {
//小图标的路径
cwd: path.resolve(__dirname, 'src/icons'),
//后缀名是png
glob: '*.png'
},
//生成文件的设置 生成两种东西 雪碧图 css
target: {
//生成雪碧图(大图的)文件存放路径
image: path.resolve(__dirname, 'dist/sprite/sprite.png'),
//生成的css路径
css: path.resolve(__dirname, 'dist/sprite/sprite.css')
},
//样式文件中 雪碧图的写法
apiOptions: {
cssImageRef: "./sprite.png"
},
//雪碧图生成的写法
spritesmithOptions: {
//如果排列及外边距
algorithm: "top-down", //从上到下 默认是横着的
padding: 2 //每个小图标之间的间隙
}
}),
//html-webpack-plugin
//自动生成html 并自动引用生成的css文件,以模板生成新的html
new WebpackHtmlPlugin({
//模板
template: "index.html",
//生成新的文件 所在路径
//注意:前边生成的雪碧图和css样式表 sprite
filename: "./sprite/a.html" //该路径参照根目录下模板index.html引入css的路径
})
]
};
配置好了之后:在到根目录下的index.html文件中
在根目录下的index.html中
```html
“`
在到src目录下创建一个app.js文件
document.getElementById('one').classList.add('icon-1')
document.getElementById('two').classList.add('icon-2')
document.getElementById('three').classList.add('icon-3')
用webpack打包 打包成功之后到dist目录下sprite目录下打开a.html 进行查看.
Mysql数据库:(免费开源)
数据库:存储数据,永久存储(持久化存储的数据)。
数据库:
– 关系型数据库
• MySQL、Oracle、DB2、SQL Server ……
• 关系数据库中全都是表
– 非关系型数据库
• MongoDB、Redis ……
• 键值对数据库
• 文档数据库MongoDB
关系型数据库和非关系型数据库区别???
关系型数据库 : 存储数据全都是表来存储数据
非关系型数据库 : 键值对数据库
day 11
通过DOS连接mysql
连接命令:
mysql -h 127.0.0.1 -u root -p
mysql 是登录MySql软件的命令,-h表示需要登录MySql软件的IP地址,-u表示登录Mysql软件的用户名,-p表示登录mysql软件的密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6806MR2Z-1611110479631)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0DE.tmp.jpg)]
DDL语句:
创建数据库的语法形式:
create database 数据库名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLPTgND4-1611110479633)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0DF.tmp.jpg)]
查看数据库的命令:
show databases;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eM9TPICe-1611110479635)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0EF.tmp.jpg)]
选择数据库:
use 数据库名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8H1dz68-1611110479637)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F0.tmp.jpg)]
删除数据库:
drop database 数据库名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oTwhFFpf-1611110479639)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F1.tmp.jpg)]
创建表格:
create table 表名(age INT,username VARCHAR(20));
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uNDybDS1-1611110479640)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F2.tmp.jpg)]
查看数据表信息:
describe 表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7hXY588P-1611110479642)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F3.tmp.jpg)]
查看表详细定义:
show create table 表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXmwPIp6-1611110479644)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F4.tmp.jpg)]
删除表:
drop table 表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBEnoxxL-1611110479646)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC0F5.tmp.jpg)]
验证删除是否成功
可以使用查看表的详情来证明,如果报错就是已经删除了
describe 表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TsyHF9Bz-1611110479648)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC106.tmp.jpg)]
修改表名:
alter table 旧表名 rename 新表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fu4oJcXq-1611110479650)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC107.tmp.jpg)]
验证数据表名是否修改成功:
desc 数据表名;
如果不存在则会报错:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGUyMdV5-1611110479653)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC108.tmp.jpg)]
如果存在会显示数据表的内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtJvStJm-1611110479654)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC109.tmp.jpg)]
增加字段:
alter table 表名 add 属性名 属性类型;
alter table user add age int(10);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ESysu7w-1611110479656)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC11A.tmp.jpg)]
在表的第一个位置增加字段:(通过first关键字)
alter table 表名 add 属性名 属性类型 first;
alter table user add password varchar(100) first;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pYzBmUfJ-1611110479659)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC12A.tmp.jpg)]
在表的指定字段之后增加字段:(添加在age之后)
alter table 表名 add 属性名 属性类型 after 属性名;
alter table user add phone int(20) after age;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KImvyBDb-1611110479662)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC13B.tmp.jpg)]
删除字段:
alter table 表名 drop 属性名;
alter table user drop password;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UCzP9cxm-1611110479664)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC15B.tmp.jpg)]
检查数据表:
describe 数据表名;/ desc 数据表名;
describe user;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f4xjwElg-1611110479665)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC15C.tmp.jpg)]
修改字段(修改字段类型):
alter table 表名 modify 属性名 属性类型;
alter table user modify age varchar(20);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NLkJqD1q-1611110479668)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC16D.tmp.jpg)]
修改字段的名字:
alter table 表名 change 旧属性 新属性 属性类型;
alter table user change age ages int(20);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a62pepre-1611110479670)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC16E.tmp.jpg)]
同时修改字段的名字和属性:
alter table 表名 change 旧属性名 新属性名 属性类型;
alter table user change ages age varchar(10);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGwUtBTq-1611110479671)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC16F.tmp.jpg)]
修改字段的顺序
alter table 表名 modify 属性名1 数据类型 after 属性名2;
alter table user modify age varchar(10) after username;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RIEkpSgz-1611110479673)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC17F.tmp.jpg)]
alter table 表名 modify 属性名 数据类型 first;(把指定字段放到第一位)
alter table user modify age varchar(10) first;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccYpG8su-1611110479675)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC180.tmp.jpg)]
数据类型:
整数类型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crAfs7Is-1611110479677)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC191.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Blc0GHdH-1611110479679)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC192.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAFYuyKM-1611110479681)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC193.tmp.jpg)]
浮点数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-me3UQMQz-1611110479683)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1A3.tmp.jpg)]
日期类型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJ1RfAsC-1611110479685)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B4.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfcRukl9-1611110479686)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B5.tmp.jpg)]
字符串:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AwrT6qzn-1611110479688)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B6.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Szn0TXf8-1611110479690)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B7.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWyfAEpG-1611110479694)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B8.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4p37HhkL-1611110479696)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1B9.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z2qNZ8pC-1611110479698)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1BA.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fn01lbBd-1611110479700)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1BB.tmp.jpg)]
操作表的约束:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4BTOPFJu-1611110479704)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1DB.tmp.jpg)]
如果表中字段用not null 约束条件,保证所有记录中该字段都有值。如果用户插入的记录中,该字段为空值,则数据库管理系统会报错
Sql语句:
create table 表名(属性 数据类型 not null);
create table t_det(dname varchar(10) not null);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tqbTQxOz-1611110479706)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1DC.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6KMaUV4-1611110479708)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1ED.tmp.jpg)]
设置字段的默认值:
create table 表名( 属性 数据类型 default 默认值 );
create table t_det2(age varchar(10) default '20');
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hbq3pax8-1611110479710)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1FD.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2bhqGYW-1611110479712)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1FE.tmp.jpg)]
设置主键:
当想数据库中的唯一标识所记录时,可以使用主键来进行约束
create table 表名(属性名 数据类型 primary key);
create table t_det3(id int primary key);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jE7WQZRq-1611110479714)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC1FF.tmp.jpg)]
设置字段值自动增加:
该字段的数据类型必须是整数类型;
create table 表名(属性名 int primary key auto_increment);
create table t1(id int primary key auto_increment);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5xOObqLH-1611110479716)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC210.tmp.jpg)]
数据操作DML语句:
一、查:(单表查询)
查找所有字段:
SELECT * FROM 表名;
SELECT:查询
*:所有的数据
FROM:到那个地方去查询数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Hb8mgKS-1611110479718)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC211.tmp.jpg)]
或者是输入所有字段的属性名,如果需要改变字段显示的顺序,只需要调整select关键字的顺序即可;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vMlH15c-1611110479720)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC212.tmp.jpg)]
查询指定字段:
select 字段1,字段2 from 表名;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQ1JPL7v-1611110479721)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC213.tmp.jpg)]
条件查询:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BrhhKIpt-1611110479724)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC224.tmp.jpg)]
1. 单条件数据查询:
select 属性 from 数据表名where 查询条件;
where:条件(筛选) 子查询条件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FergDqMR-1611110479725)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC225.tmp.jpg)]
2. 多条件数据查询:
select 字段 from 数据表 where 多个条件;
select name from student_table where class='1'&&score>60;
&&:且 也可以使用 and
|| :或者 也可以使用 or
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBw8PtbF-1611110479728)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC226.tmp.jpg)]
3. BETWEEN AND关键字范围查询:
1)符合范围的数据记录查询:
SELECT 字段 FROM 数据表名 WHERE 查询字段BETWEEN 60 AND 100;
查询成绩在60-100之间的,返回姓名
SELECT name FROM student_table WHERE score BETWEEN 60 AND 100;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXsm4EKT-1611110479730)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC236.tmp.jpg)]
2)查询不符合条件的内容:
SELECT name FROM student_table WHERE score NOT BETWEEN 60 AND 100;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UZj7vHSm-1611110479732)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC237.tmp.jpg)]
4. 带IN关键字查询:
1)在集合中数据记录查询
查询具体的内容:例学生成绩为90,60的返回name;
select 属性名 from 数据表 where 条件1 or 条件2;
select name from student_table where score=90 or score=60;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0S9qaBg-1611110479733)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC238.tmp.jpg)]
select 属性 from 表 where 属性 IN (条件1,条件2);
select name from student_table where score IN (90,60);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FEwbAvxg-1611110479735)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC239.tmp.jpg)]
2)不在集合中数据记录查询:
例:成绩不在90,60的其他学生
select 属性from 数据表 where 属性NOT IN (条件1,条件2....);
select name from student_table where score NOT IN (90,60);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gNt4qTCw-1611110479737)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC23A.tmp.jpg)]
5. 带like关键字的模糊查询:
1) 带有“%”通配符的查询:
例:查找90-99分的学生:
SELECT 属性FROM 数据表 WHERE 属性LIKE '关键字%';
SELECT name FROM student_table WHERE score LIKE '9%';
搜索关键字% 是以搜索关键字开头的,只要满足。都查询出来
%搜索关键字% 只要包含搜索关键字,只要满足,都查询出来
%搜索关键字 是以搜索关键字结尾的,只要满足,都查询出来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b9W3almp-1611110479739)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC24B.tmp.jpg)]
例:查找除90-99分的学生:
SELECT name FROM student_table WHERE NOT score LIKE '9%';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75sd2szh-1611110479741)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC24C.tmp.jpg)]
2) 带有”_”通配符的查询:
例:成绩中第二位为9的学生:
SELECT name FROM student_table WHERE score LIKE '_9%';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YprjFQaA-1611110479743)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC24D.tmp.jpg)]
例:成绩中第二位除了为9的学生:
SELECT name FROM student_table WHERE NOT score LIKE '_9%';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdubukJC-1611110479745)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC24E.tmp.jpg)]
6. 排序:
在多数情况下,查找到的结果是默认顺序,我们可以在查询时给其进行排序:
通过ORDER BY 来实现:
SELECT 属性 FROM 表名 WHERE 属性ORDER BY 条件1 [ASC|DESC];
ASC标识按升序的顺序进行排序,DESC表示按照降序的顺序进行排序;
1) 按照单字段排序:
例:学生成绩升序进行排序; 注意排序只是针对于数字类型数据
SELECT * FROM student_table ORDER BY score ASC; 默认是asc 升序
Select * from student_table ORDER BY score Desc desc倒序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IW5PIgJq-1611110479747)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC26E.tmp.jpg)]
由于mysql 关键字ORDER BY 默认就是升序排序,可以修改成:
SELECT * FROM student_table ORDER BY score;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wVjgphCd-1611110479749)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC26F.tmp.jpg)]
例:学生成绩升序进行降序序;
SELECT * FROM student_table ORDER BY score DESC;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aPLo3ymu-1611110479751)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC270.tmp.jpg)]
2) 多字段排序:
例:先班级按升序排序,成绩按降序排序:
SELECT * FROM student_table ORDER BY class ASC,score DESC;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPPLlC9V-1611110479753)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC281.tmp.jpg)]
\7. 限制数据记录查询数量:
使用关键字LIMIT来实现:
SELECT 属性,属性... FROM 表名 WHERE 属性 LIMIT 起始条件,显示的行数
1)不指定初始位置:
1.1)显示记录数小于查询结果:
例:查找成绩小于60 的学生显示两条:
SELECT * FROM student_table WHERE score<60 LIMIT 2;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eUxiN83I-1611110479754)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC282.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXVMDamU-1611110479756)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC283.tmp.jpg)]
1.2)显示记录数大于查询结果
例:查找成绩小于60的学生显示结果10条;但是不够10条就显示出仅有的条数;
SELECT * FROM student_table WHERE score<60 LIMIT 10;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1McgsIaX-1611110479758)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC293.tmp.jpg)]
2)指定初始位置:
2.1)LIMIT关键字还经常与ORDER BY关键字一起使用,即先对查询结果进行排序,然后显示其中部分数据记录;
寻找大于60分,按照班级排序,从0开始显示5条;
SELECT * FROM student_table WHERE score>60 ORDER BY class LIMIT 0,5;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAbD79cX-1611110479762)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC294.tmp.jpg)]
实现第二次操作,从第6条记录开始显示,共显示5条记录;
SELECT * FROM student_table WHERE score>60 ORDER BY class LIMIT 5,5;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6j4t3vHx-1611110479764)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2A5.tmp.jpg)]
8. 统计函数和分组数据记录查询
统计函数分别为:
1)COUNT():实现统计表中记录的平均值
2)AVG():实现计算字段值的平均值
3)SUM():实现计算字段值的总和
4)MAX():实现查询字段值的最大值
5)MIN():现在查询字段值的最小值
8.1)统计数据记录条数:
统计数据表中的总数据:不管是不是空值都会返回
SELECT COUNT(*) number FROM student_table;
select COUNT(*) as 别名 from student
As:关键字 取别名 那个属性要取别名,就在那个属性的后面取别名
As 别名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jRMK7oE7-1611110479765)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2A6.tmp.jpg)]
对指定字段的统计:会忽略控制
SELECT COUNT(score) number FROM student_table;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GOI9XHPl-1611110479768)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2A7.tmp.jpg)]
8.2)统计计算平均值:
算所有成绩的平均数:
SELECT AVG(score) average FROM student_table;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYkeSlqw-1611110479769)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2C7.tmp.jpg)]
算所有不小60的成绩的平均值:
SELECT AVG(score) average FROM student_table WHERE NOT score<60;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SFefCSvZ-1611110479771)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2C8.tmp.jpg)]
8.3)统计计算求和:
计算成绩的总和:
SELECT SUM(score) sumvalue FROM student_table;
SELECT SUM(score) FROM student_table;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLEeVoox-1611110479773)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2C9.tmp.jpg)]
8.4)统计计算最大值和最小值:
查询成绩的最高成绩和最少成绩:
SELECT MAX(score) maxval,MIN(score) minval FROM student_table;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zQETTS87-1611110479774)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2DA.tmp.jpg)]
8.5)可以几个函数同时使用:
SELECT AVG(score),SUM(score), MAX(score),MIN(score) FROM student_table;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ftij1g6T-1611110479776)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2DB.tmp.jpg)]
8.6)分组查询:
例:以班级为关键字进行查询:
SELECT * FROM student_table GROUP BY class;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XFioexWL-1611110479778)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2DC.tmp.jpg)]
8.7)分组数据查询-实现统计功能分组查询
想显示每个分组中的字段,可以通过函数GROUP_CONCAT()来实现,该函数可以实现显示每个分组中的指定字段值
例:按班级分组,并且将每个班级的name返回
SELECT class,GROUP_CONCAT(name) FROM student_table GROUP BY class;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlJNadBv-1611110479780)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2EC.tmp.jpg)]
例:按班级分组,并且将每个班级的name,并且返回对应的数量;
SELECT class,GROUP_CONCAT(name) name,COUNT(name) number FROM student_table GROUP BY class;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ubiM0efu-1611110479784)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2ED.tmp.jpg)]
8.8)实现句子限定分组:
例:按班级分类,并且求出平均成绩:
SELECT class,AVG(score) FROM student_table GROUP BY class;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChTQJENu-1611110479786)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2EE.tmp.jpg)]
二、增:
使用INSERT INTO 语句来实现插入数据记录
1. 插入完整数据记录:
INSERT INTO 表名(属性1,属性2,属性3) VALUES (值1,值2,值3);
INSERT INTO student_table(class,name,score) VALUES ('3','憨憨',21);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifDP8veX-1611110479789)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2EF.tmp.jpg)]
INSERT INTO student_table VALUES (12,'3','憨憨',21);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ofk8Fgh-1611110479791)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC2F0.tmp.jpg)]
注意:第二种写法,要按照数据表的顺序来写
2. 插入指定字段:
INSERT INTO student_table(class,name) VALUES(3,'lucky');
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QVv1kL2k-1611110479793)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC301.tmp.jpg)]
3. 插入多条数据:
INSERT INTO 表名 VALUES (值1,值2,值3,值4),(值1,值2,值3,值4),(值1,值2,值3,值4);
INSERT INTO student_table VALUES (15,2,'a1',93),(16,1,'a2',78),(17,3,'b1',56);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ueLciEOu-1611110479796)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC302.tmp.jpg)]
INSERT INTO student_table(class,name) VALUES (2,'a11'),(1,'a21'),(3,'b11');
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWPBgnKt-1611110479797)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC303.tmp.jpg)]
三、改(更新):
通过UPDATE来实现:
1.更新指定数据记录:
例:将a1的成绩改成66;
UPDATE student_table SET score=66 WHERE name=“a1”;
Update 表名 set(设置) 字段名=”设置值” where id=1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvtbMbJP-1611110479799)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC304.tmp.jpg)]
2. 更新所有数据记录:
例:成绩小于60,把名字改为不及格;
UPDATE 数据表 SET 被修改属性=值 WHERE 修改条件
UPDATE student_table SET name=‘及格’ WHERE score>60;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H9J2j6YD-1611110479801)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC314.tmp.jpg)]
四、删除:
1. 删除指定数据记录:
例:删除成绩为56的学生:
DELETE FROM 表名 WHERE 条件;
DELETE FROM student_table WHERE score=56;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2mfeuTc-1611110479802)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC315.tmp.jpg)]
2. 删除所有数据记录:
例:删除成绩为60以下的学生;
DELETE FROM student_table WHERE score<60;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vg1KKKuk-1611110479804)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC316.tmp.jpg)]
删除表中所有数据:
DELETE FROM student_table;
五、查(多表查询):
表连接分为内连接和外连接,它们之间的最主要区别是:内连接仅选出两张表中互相匹配的记录,而外连 接会选出其他不匹配的记录。我们常用的是内连接。
外连接有分为左连接和右连接,具体定义如下: 左连接:包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录 右连接:包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录
内连接查询:
通过sql语句INNER JOIN…ON来实现
1) 两个数据表查询:
SELECT * FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号
例子:根据member中uid获取购物车对应的信息:
SELECT * FROM shopcar INNER JOIN member ON shopcar.uid=member.uid;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0zG4wz6-1611110479805)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsC327.tmp.jpg)]
INNER JOIN 连接三个数据表的用法:
SELECT * FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号
INNER JOIN 连接四个数据表的用法:
SELECT * FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号)
INNER JOIN 表4 ON Member.字段号=表4.字段号
INNER JOIN 连接五个数据表的用法:
SELECT * FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号)
INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表5 ON Member.字段号=表5.字段号
day 12
项目文档
一:使用express框架生成器生成项目结构
npm i express-generator -g (工具类的模块,要安装到全局) 只要安装一次。不要重复安装.
express –view=ejs myapp 使用ejs模板引擎生成一个项目结构
express命令是安装了express-generator模块到global上才有的这个命令, –view指定模板引擎, myapp是项目工程文件夹的名字(注意不能写中文或特殊符号
回车执行以后, 会在当前目录中, 生成myapp一整套文件夹+文件+代码的配置, 还有package.json记录了当前基础项目需要的所有包
cd myapp 然后 npm install 然后 npm run start启动此项目 (默认端口3000)
启动的入口: bin/www 文件 (并非是app.js)
你要把之前启动的项目停掉:
定位到当前项目的根目录结构下:npm run start
二:项目目录结构:operator(sqlStr)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLHRklpa-1611110479807)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps3465.tmp.jpg)]
routes:定义规划路由层
Ctrl+c 终止程序 输入y
在重新输入npm run start
utils:
Db.js 封装的数据库的方法
awaitTo.js 封装一个promase方法
(1):封装mysql数据库
下载数据库:
npm i mysql --save-dev
(2) :用类封装
class Db{
//定义一个静态方法 链接数据库封装
static connect2(){
//在当前对象下新增一个属性名
this.con = mysql.createConnection(config);
this.con.connect(err=>{
if(err){
console.log("链接失败");
return;
}else{
console.log("链接成功");
}
})
}
//封装promise 异步处理sql语句
//sqlStr sel语句
static operator(sqlStr){
//返回一个promise
let p = new Promise((resolve,reject)=>{
this.con.query(sqlStr,(err,result)=>{
if(err){
reject(err)
}else{
resolve(result)
}
})
})
}
//数据库中做备份数据内容
day 13
下载插件:测试接口
*REST Client*
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w67rly4u-1611110479810)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps7CFB.tmp.jpg)]
这个插件安装成功之后:一定要重新启动你的编辑器
在项目的根目录下新建一个文件:后缀名必须是.http
myApi.http
//注册接口
(1):生成验证码
1.下载 svg-captcha
npm i svg-captcha
2:加载svg-captcha let svgCaptcha = require(“svg-captcha”);
3:生成验证码
规划一个路由
app.get(“/regcode”,async(req,res)=>{
const captcha = svgCaptcha.create();
//创建一个验证码
res.cookie("code", captcha.text);
// 把真正的验证码保存到cookie上,用于下面接口的调用
res.type("svg");
// 告诉浏览器, 这里返回的是图片的数据
res.send(captcha.data);
// 提取验证码图片的data数据返回给前端
})
(2):cookie-parser(安装项目时自带有这个插件,不需要再下载。和配置,直接使用.)
Cookie 存储值的使用:
res.cookie(“标签名”,存储的值)
Cookie获取值的使用
req.cookies.标签名
(3):规划注册路由
router(“/register”,async(req,res)=>{
//数据库添加 获取文本框输入的数据内容
})
body-parser 解析表单提交数据内容(获取文本框输入的值)
这个插件不需要再下载和配置,直接使用.
下载node-uuid插件(随机生成内容)
npm i node-uuid
加载node-uuid
let uuid = require(“node-uuid”).v1();//安装v1随机生成内容值
注册的重构:
需要把静态的资源文件和静态文件拷贝到
md5 是给注册是密码进行加密 (生成加密的一个方式)
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<script src="http://www.gongjuji.net/Content/files/jquery.md5.js"></script>
登录接口:
router.post("/login",async(req,res)=>{
if(req.cookies.code.toUpperCase() == req.body.userCode.toUpperCase())
{
let [err,data] = await Dbconfig.querys(`select * from member where username='${req.body.username}' and password='${req.body.password}'`);
res.send(Success(data,"登录成功"));
}else
{
res.send(MError("你输入的用户名或者密码错误,验证码错误"));
}
})
重构登录页面:
补充知识点:
1. token
jwt是用来生成token,token是用来存储用户信息,添加购物车或者是到购物车页面,需要权限判断。使用token来做权限判断
2. 使用中间件:jsonwebtoken
1) 下载:jsonwebtoken
npm i jsonwebtoken
2) 引入:const jwt = require(“jsonwebtoken”)
3) 在用户登录成功之后,获取用户信息,生成token:(后端)
// 生成对应的token,第一个参数用户信息,第二参数是签名,第三个参数时间
const token = jwt.sign(obj, "secret", { expiresIn: 60 * 60 * 1000 * 48 });
4) (前端)登录成功之后,获取到后端返回的token值,进行本地存储localstorage
localStorage.setItem(“token”, token)
5) (前端)在购物车页面获取本地存储的token值,在添加购物车的时候,传递给后端:注意,要在请求头中进行传值
localStorage.getItem(“token”);
传值需要设置请求头:
headers: {
“Authorization”: token //此处放置请求到的用户token
},
6) (后端)在添加购物车的接口中,在请求头中获取Authorization中token,然后进行解析;
// 第二个参数的签名和设置token的签名要一致
let data = jwt.verify(token, “secret”);
7) 用户信息和商品信息同时提交到数据库。。。
https://console.cloud.tencent.com/domain 解析域名的地址
https://cloud.tencent.com 腾讯云平台地址
项目的部署到线上:
腾讯云:
1:登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3f1tJ4uu-1611110479813)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CA6.tmp.jpg)]
2:选择cvm
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gQO62ihr-1611110479814)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CA7.tmp.jpg)]
3:选择操作系统centOs 7.6 64位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B6G1WlBj-1611110479815)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CA8.tmp.jpg)]
4:进入控制台
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dg3C5rkS-1611110479817)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CA9.tmp.jpg)]
5:选择自己的区域
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jblahuSp-1611110479819)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CAA.tmp.jpg)]
6:更多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QXRviN57-1611110479820)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CAB.tmp.jpg)]
7:设置控制密码:
用户名:root
密码:1996.song
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEeEB5sT-1611110479822)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CAC.tmp.jpg)]
8:设置完成密码 需要点击登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uNaulQc3-1611110479824)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CBD.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-09kUYahW-1611110479826)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CBE.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33oHqA8f-1611110479829)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CBF.tmp.jpg)]
10:需要安装面板系统
\1. 在黑窗口中 运行
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qkTzKmxp-1611110479831)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CC0.tmp.jpg)]
记住面板的地址: http://188.131.135.82:8888/6235ae73
面板用户名: ozaqczt3
面板的密码: 104453d8
11:需要通过上面面板地址 进入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jZ0oiVVs-1611110479832)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CC1.tmp.jpg)]
12:安装软件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prcwbjBW-1611110479834)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CC2.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C3ZrEX4F-1611110479836)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CC3.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G8FWKSBv-1611110479838)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CC4.tmp.jpg)]
13:安装完成所有的软件
先在本地导出数据库到项目中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGE9AsYT-1611110479839)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD4.tmp.jpg)]
14:把本地的项目上传到服务器中
数据库用户名:root
数据库密码:f7f0ba7480629b0f
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MyruMPUQ-1611110479841)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD5.tmp.jpg)]
在到你本地项目中:修改数据库配置文件.把数据库的密码进行修改。
15:把本地的项目上传至服务器上(需要把本地的项目压缩成压缩包,在进行上传)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iPSxUKGC-1611110479843)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD6.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aUAlmsgj-1611110479844)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD7.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AapoEWD0-1611110479846)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD8.tmp.jpg)]
16:配置数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDF1irI6-1611110479847)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CD9.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybvQvPzu-1611110479849)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CDA.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcxUeiDo-1611110479850)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CDB.tmp.jpg)]
需要配置域名: 188.131.131.243(自己申请服务器时分配的端口域名)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwEJbiwi-1611110479852)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CEC.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MLA2wli3-1611110479854)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CED.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIZfEjHe-1611110479855)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CEE.tmp.jpg)]
需要返回到文件目录结构下:
修改数据库配置文件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b62iZVJn-1611110479857)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CEF.tmp.jpg)]
数据库用户名:xiaou
数据库密码:34c4bfd7d70f1e03
更新完成之后:
在回到配置域名:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aQhZf5A7-1611110479859)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CF0.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OkybP6SA-1611110479861)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CF1.tmp.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2AN3D24e-1611110479863)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps2CF2.tmp.jpg)]
到浏览器中:输入188.131.131.243 域名进行访问
e-uuid”).v1();//安装v1随机生成内容值
**注册的重构:**
需要把静态的资源文件和静态文件拷贝到
md5 是给注册是密码进行加密 (生成加密的一个方式)
```html
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<script src="http://www.gongjuji.net/Content/files/jquery.md5.js"></script>
登录接口:
router.post("/login",async(req,res)=>{
if(req.cookies.code.toUpperCase() == req.body.userCode.toUpperCase())
{
let [err,data] = await Dbconfig.querys(`select * from member where username='${req.body.username}' and password='${req.body.password}'`);
res.send(Success(data,"登录成功"));
}else
{
res.send(MError("你输入的用户名或者密码错误,验证码错误"));
}
})
重构登录页面:
补充知识点:
1. token
jwt是用来生成token,token是用来存储用户信息,添加购物车或者是到购物车页面,需要权限判断。使用token来做权限判断
2. 使用中间件:jsonwebtoken
1) 下载:jsonwebtoken
npm i jsonwebtoken
2) 引入:const jwt = require(“jsonwebtoken”)
3) 在用户登录成功之后,获取用户信息,生成token:(后端)
// 生成对应的token,第一个参数用户信息,第二参数是签名,第三个参数时间
const token = jwt.sign(obj, "secret", { expiresIn: 60 * 60 * 1000 * 48 });
4) (前端)登录成功之后,获取到后端返回的token值,进行本地存储localstorage
localStorage.setItem(“token”, token)
5) (前端)在购物车页面获取本地存储的token值,在添加购物车的时候,传递给后端:注意,要在请求头中进行传值
localStorage.getItem(“token”);
传值需要设置请求头:
headers: {
“Authorization”: token //此处放置请求到的用户token
},
6) (后端)在添加购物车的接口中,在请求头中获取Authorization中token,然后进行解析;
// 第二个参数的签名和设置token的签名要一致
let data = jwt.verify(token, “secret”);
7) 用户信息和商品信息同时提交到数据库。。。
https://console.cloud.tencent.com/domain 解析域名的地址
https://cloud.tencent.com 腾讯云平台地址
项目的部署到线上:
腾讯云:
1:登录
[外链图片转存中…(img-3f1tJ4uu-1611110479813)]
2:选择cvm
[外链图片转存中…(img-gQO62ihr-1611110479814)]
3:选择操作系统centOs 7.6 64位
[外链图片转存中…(img-B6G1WlBj-1611110479815)]
4:进入控制台
[外链图片转存中…(img-Dg3C5rkS-1611110479817)]
5:选择自己的区域
[外链图片转存中…(img-jblahuSp-1611110479819)]
6:更多
[外链图片转存中…(img-QXRviN57-1611110479820)]
7:设置控制密码:
用户名:root
密码:1996.song
[外链图片转存中…(img-XEeEB5sT-1611110479822)]
8:设置完成密码 需要点击登录
[外链图片转存中…(img-uNaulQc3-1611110479824)]
[外链图片转存中…(img-09kUYahW-1611110479826)]
[外链图片转存中…(img-33oHqA8f-1611110479829)]
10:需要安装面板系统
\1. 在黑窗口中 运行
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh
[外链图片转存中…(img-qkTzKmxp-1611110479831)]
记住面板的地址: http://188.131.135.82:8888/6235ae73
面板用户名: ozaqczt3
面板的密码: 104453d8
11:需要通过上面面板地址 进入
[外链图片转存中…(img-jZ0oiVVs-1611110479832)]
12:安装软件
[外链图片转存中…(img-prcwbjBW-1611110479834)]
[外链图片转存中…(img-C3ZrEX4F-1611110479836)]
[外链图片转存中…(img-G8FWKSBv-1611110479838)]
13:安装完成所有的软件
先在本地导出数据库到项目中
[外链图片转存中…(img-MGE9AsYT-1611110479839)]
14:把本地的项目上传到服务器中
数据库用户名:root
数据库密码:f7f0ba7480629b0f
[外链图片转存中…(img-MyruMPUQ-1611110479841)]
在到你本地项目中:修改数据库配置文件.把数据库的密码进行修改。
15:把本地的项目上传至服务器上(需要把本地的项目压缩成压缩包,在进行上传)
[外链图片转存中…(img-iPSxUKGC-1611110479843)]
[外链图片转存中…(img-aUAlmsgj-1611110479844)]
[外链图片转存中…(img-AapoEWD0-1611110479846)]
16:配置数据库
[外链图片转存中…(img-LDF1irI6-1611110479847)]
[外链图片转存中…(img-ybvQvPzu-1611110479849)]
[外链图片转存中…(img-qcxUeiDo-1611110479850)]
需要配置域名: 188.131.131.243(自己申请服务器时分配的端口域名)
[外链图片转存中…(img-uwEJbiwi-1611110479852)]
[外链图片转存中…(img-MLA2wli3-1611110479854)]
[外链图片转存中…(img-pIZfEjHe-1611110479855)]
需要返回到文件目录结构下:
修改数据库配置文件:
[外链图片转存中…(img-b62iZVJn-1611110479857)]
数据库用户名:xiaou
数据库密码:34c4bfd7d70f1e03
更新完成之后:
在回到配置域名:
[外链图片转存中…(img-aQhZf5A7-1611110479859)]
[外链图片转存中…(img-OkybP6SA-1611110479861)]
[外链图片转存中…(img-2AN3D24e-1611110479863)]
到浏览器中:输入188.131.131.243 域名进行访问