Node+Express+MongoDB(mongoose)+ReactJS-全栈笔记

Full stack

文章目录

  • Full stack
    • Node JS
      • 安装
      • 在命令行测试安装效果
      • VSCode 安装node插件
      • NodeJS之 条件语句
      • NodeJS之 循环语句
      • 本部分代码段的文件结构
      • NodeJS之 输入输出
      • NodeJS之 文件管理
        • 读文件和写文件
        • 列出目录文件和创建新的目录
        • 练习1
        • 导出并导入模块
        • 事件发射器和事件监听器
        • 练习2
    • Express
      • 安装
      • 本部分代码段文件结构
      • 创建一个express网站
      • 添加组件 nodemon
        • 练习3
      • 创建一个express服务器
        • 练习4
      • 基本的HTTP知识
      • Postman
      • 带参数的GET路由
      • 带参数的POST路由
        • 练习5
      • 链请求变量
        • 练习6
      • 项目生成器
        • 练习7
    • ECMAScript6(ES6)
      • 简单语法
        • let
        • const
        • 箭头函数
        • 练习8
        • for/of 循环
      • 高级语法
        • JS类
        • JS Promises
        • 参数的默认值
        • 函数rest参数
        • 练习9
      • Array 数组
        • Array.find()
        • Array.findIndex()
        • 练习10
    • mongoDB
      • 安装
      • 添加到环境变量
      • 文档数据库的概念
      • 主要的命令行命令
      • MongoDb Compass
        • 练习11
      • 链接NodeJS
        • 练习12
      • RESTful API
        • 创建具有正确文件架构的网站
    • ReactJS

本文对应代码

Node JS

安装

在命令行测试安装效果

VSCode 安装node插件

NodeJS之 条件语句

if() {
     }
else if{
     }
else {
     }

switch (expr) 
{
       
	case 'Oranges’:
		break;
	default:
}

NodeJS之 循环语句

While

For

Do while

Foreach


本部分代码段的文件结构

|-- node
    |-- demoModules.js
    |-- events.js
    |-- file1.txt
    |-- files.js
    |-- modules.js
    |-- text.js
    |-- demoDir1
    |   |-- good.txt
    |   |-- index.html
    |   |-- name.js
    |-- demoDir2

NodeJS之 输入输出

//text.js

//process是全局变量,可以不写,但是写出来,编译器会有提示,比较方便
const process = require('process');

//process.stdin是输入,我的理解是,这就相当于一个管子,一开始没有打开
//其下的.on就是打开管子,name就是输入进去data,控制台输出以下
//想要真正的输出,就是其下的.pipe,管子输出来
//只有用其.destroy才能关闭管子,否则一直处于打开状态
//以上都是个人理解。
process.stdin.on('data',function(name){
     
    console.log(`Hello ${
       name}`);
    process.stdin.destroy();
});
process.stdin.pipe(process.stdout);

NodeJS之 文件管理

读文件和写文件

//files.js

//引入文件包
const fs = require('fs')

data = 'hello';
//将数据data写入文件file.txt并
//控制台输出'The file has been saved!'
fs.writeFile('file1.txt',data,(error) =>{
     
    if(error) throw error;
    console.log('The file has been saved!');
});

//读取文件file1.txt,并存入局部变量data,并控制台输出内容。
fs.readFile(__dirname+'/file1.txt','utf-8',(error, data)=>{
     
    if(error) throw error;
    console.log(data);
});

列出目录文件和创建新的目录

//files.js

//列出目录文件
fs.readdir(__dirname+'/demoDir1',(error,files)=>{
     
    if(error) throw error;
    files.forEach((file)=>{
     
        console.log(file);
    });
})

//创建新的目录
fs.mkdir(__dirname+'/demoDir2',{
     recursive: true},(error)=>{
     
    if(error) throw error;
});

练习1

向用户询问文件名
如果当前文件夹中没有该名称的文件,请询问用户要在文件中写入什么并创建文件。
否则,打印“文件内容为:”并打印文件内容

导出并导入模块

//modules.js
//自定义一个模块
module.exports = {
     
    log: function(data){
     
        console.log('data: '+data);
    },
    sayHello: function(){
     
        console.log("Hello Hebut");
    }
};
//demoModules.js
//导入模块
const demo = require(`${
       __dirname}/modules`);

demo.log('test');
demo.sayHello();

事件发射器和事件监听器

//events.js
//引入包
const EventEmitter = require('events');

//新建一个事件发生器
let eventEmiter = new EventEmitter();

//打开
eventEmiter.on('event',(data)=>{
     
    console.log(`Event catched: ${
       data}`);
});

console.log(`give me data`);
process.stdin.on('data',function(data){
     
    eventEmiter.emit('event',data);//事件触发
    process.stdin.destroy();
});

练习2

合适的价格游戏
计算机选择一个随机数,用户必须猜测该数字是多少
如果用户输入错误,则计算机会告诉用户密码是否更大或更小
新增功能:
允许用户选择难度级别(0-10、0-100、0-1000之间)
允许用户重新启动游戏
将用户分数保存在文件中


Express

安装


本部分代码段文件结构

|-- express
    |-- index.js
    |-- package-lock.json
    |-- package.json
    |-- node_modules
    	|--...

创建一个express网站

//在控制台对应目录下输入如下代码,并填入必要信息。
//1.npm init
//2.npm install express

你的目录> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (express) demo
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author: soMagics
license: (ISC)
About to write to C:\Users\Administrator.Bili-2020VAUJYO\Desktop\fullstack\express\package.json:  

{
     
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "soMagics",
  "license": "ISC"
}


Is this OK? (yes)
你的目录> npm install express
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN demo@1.0.0 No description
npm WARN demo@1.0.0 No repository field.

+ express@4.17.1
added 50 packages from 37 contributors and audited 50 packages in 6.59s
found 0 vulnerabilities

    
//然后在本目录下创建index.js

添加组件 nodemon

//控制台
//添加组件 nodemon
你的目录> npm install nodemon
//package.json
//添加语句"start": "nodemon index.js"(注意上一行末尾要加逗号。)

{
     
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon index.js"
  },
  "author": "soMagics",
  "license": "ISC",
  "dependencies": {
     
    "express": "^4.17.1",
    "nodemon": "^2.0.7"
  }
}
//控制台
//启动项目
//注:Ctrl+C终止项目
你的目录> npm start

练习3

创建一个express项目
创建一个index.js文件
将nodemon添加到项目
运行

创建一个express服务器

//index.js
//引入包
var Express = require('express');

//定义app,和端口号
var app = new Express();
var port = 3000;

//根目录路由,get方法
//res.send():传送HTTP响应
app.get("/",(req,res)=>{
     
    console.log(req);
    res.send('I got it');
});

//监听端口号,打开
app.listen(port,()=>{
     
    console.log(`listening on port ${
       port}`);
})
//控制台
你的目录> npm start

打开网页 www.localhost:3000

请读者自己查看效果。

练习4

为您的express服务器创建3个路由:(/,/ about-us,/ blog)

基本的HTTP知识

request包括五部分

基本的HTTP变量:GET,POST,PUT,DELETE

Postman

安装 略

使用方法 略

带参数的GET路由

//index.js
//打开网页的/students/后面可以写任意字符(就本状态而言)
app.get('/students/:id',(req,res)=>{
     
    console.log('Get a student by its id');
    res.send();
});

重启npm

打开网页 www.localhost:3000/students/1

请读者自己查看效果。

带参数的POST路由

//cmd
你的目录>npm install body-parser
//index.js
//引入包
var bodyParser = require('body-parser');

//url编码
var urlEncodeParser = bodyParser.urlencoded({
     extended:false});

//在postman里测试
app.post('/students',urlEncodeParser,(req,res)=>{
     
    console.log('Creat a student');
    console.log(req.body.id);
    res.send();
});

重启npm

postman改为POST方法,在body栏中,选x-www-form-urlencoded,添加键值对id:123。

请读者自己查看效果。(效果在控制台)

练习5

创建GET和POST的student路由
将学生保存在文件中

链请求变量

可用于简化代码

//index.js

app.route("/students")
    .get((request,response)=>{
     
        let params = request.params;
        console.log(params.id);
        response.send("");
    })
    .put(urlEncodeParser,(request,response)=>{
     
        let params = request.body;
        console.log(params.id);
        response.send("");
    })
    .post(urlEncodeParser, (request,response)=>{
     
        let params = request.body;
        console.log(params.id);
        response.send("");
    });

读者可用postman测试异同。

练习6

重写您的路由并添加PUT请求。

项目生成器

|-- myapp
    |-- package-lock.json
    |-- myWebApp
        |-- app.js
        |-- package-lock.json
        |-- package.json
        |-- bin
        |   |-- www
        |-- public
        |   |-- images
        |   |-- javascripts
        |   |-- stylesheets
        |       |-- style.css
        |-- routes
        |   |-- index.js
        |   |-- users.js
        |-- views
        |   |-- error.jade
        |   |-- index.jade
        |   |-- layout.jade
        |-- node_modules
        	|--...
//cmd

新的目录>npm install express-generator –g
//生成一个默认网页
新的目录>express myWebApp 
新的目录>npm install 
新的目录>cd myWebApp 
新的目录/myWebApp>npm install cookie-parser
新的目录/myWebApp>npm install debug
新的目录/myWebApp>npm install express
新的目录/myWebApp>npm install http-errors
新的目录/myWebApp>npm install jade
新的目录/myWebApp>npm install morgan
新的目录/myWebApp>npm start

然后打开网页 http://localhost:3000/

和 http://localhost:3000/users 查看效果。

练习7

使用项目生成器

创建一条路由,以允许您创建学生(使用名字,姓氏和生日)

您必须为学生自动生成一个ID

创建一条通过学生ID获得学生的路由

创建一条路由获取所有学生

将学生保存在文件中


ECMAScript6(ES6)

简单语法

let

代码块内有效

不能重复声明

for 循环计数器很适合用 let

不存在变量提升

var x = 10;
// Here x is 10
{
      
    let x = 2;
    // Here x is 2
}
// Here x is 10

const

const 声明一个只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。

ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

var x = 10;
// Here x is 10
{
      
    const x = 2;
    // Here x is 2
}
// Here x is 10 

箭头函数

// ES5
var x = function(x, y) {
     
    return x * y;
}

// ES6
const x = (x, y) => x * y;
const x = (x, y) => {
      return x * y };

练习8

把你的“正确价格游戏”用箭头函数改写一下。

for/of 循环

for (variable of iterable) {
     
    // code block to be executed
}


//examples
var cars = ["BMW", "Volvo", "Mini"];
var x;

for (x of cars) {
     
    document.write(x + "
"
); }

高级语法

JS类

class Car {
     
  	constructor(name, year) {
     
   	this.name = name;
   	this.year = year;
  	}
}

let myCar1 = new Car("Ford", 2014);

JS Promises

Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。

A Promise is a JavaScript object that links “Producing Code” and “Consuming Code”.

“Producing Code” can take some time and “Consuming Code” must wait for the result.

//语法
let myPromise = new Promise(function(myResolve, myReject) {
     
    // "Producing Code" (May take some time)
    
    myResolve(); // when successful
    myReject();  // when error
});

// "Consuming Code" (Must wait for a fulfilled Promise).
myPromise.then(
    function(value) {
      /* code if successful */ },
    function(error) {
      /* code if some error */ }
);
//例子
let myPromise = new Promise(function(myResolve, myReject) {
     
    setTimeout(function() {
      myResolve("I love You !!"); }, 3000);
});

myPromise.then(function(value) {
     
    document.getElementById("demo").innerHTML = value;
});

参数的默认值

function myFunction(x, y = 10) {
     
    // y is 10 if not passed or undefined
    return x + y;
}
myFunction(5); // will return 15 

函数rest参数

ES6中新增加了rest参数(形式为...变量名)。所谓的rest,顾名思义就是获取剩余的参数,函数中所有多余的参数都会放进数组中然后赋值给这个rest参数。

function foo(...args){
     
    console.log(args);
}

foo(1,2,3,4,5,6);   //[1,2,3,4,5,6]

练习9

创建一个函数,该函数将使用所有作为参数传递的单词来构成一个句子

Array 数组

Array.find()

**find()**方法返回传递测试的数组中的第一个元素的值(作为函数提供)。

**find()**方法为数组中的每个元素执行一次函数:

  • 如果它找到函数返回true值的数组元素,则**find()**返回该数组元素的值(并且不检查其余值)
  • 否则返回undefined

注意: **find()**不执行空数组的函数。

注意: **find()**不会更改原始数组。

var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);

function myFunction(value, index, array) {
     
    return value > 18;
} 

Array.findIndex()

**findIndex()**方法返回传递测试的数组中的第一个元素的索引(作为函数提供)。

**findIndex()**方法为数组中的每个元素执行一次函数:

  • 如果找到函数返回true值的数组元素, **findIndex()**返回该数组元素的索引(并不检查其余值)
  • 否则返回-1

注意: **findIndex()**不会为没有值的数组元素执行函数。

注意: **findIndex()**不会更改原始数组。

var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);

function myFunction(value, index, array) {
     
    return value > 18;
} 

练习10

保存最佳成绩
仅在排行榜中显示得分高于3的得分

mongoDB

安装

添加到环境变量

文档数据库的概念

每个对象都另存为JSON文档

主要的命令行命令

//cmd

//进入mongodb
你的目录>mongo
MongoDB shell version v4.4.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session {
      "id" : UUID("44164d33-5663-4f16-86d3-0a83615b20f4") }
MongoDB server version: 4.4.6
---
The server generated these startup warnings when booting:
        2021-05-21T13:24:55.236+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>
            
//创建数据库
>use DATABASE_NAME
//查看所有数据库(新的数据库不会显示,除非写了内容)
>show dbs
//显示当前数据库(默认为test)
>db
//插入数据
>db.DATABASE_NAME.insert({
     "key":"value"})
//删除数据库
//在要删除的数据库下输入
>db.dropDatabase()

//创建集合
//注:在 MongoDB 中,你可以不创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
//name: 要创建的集合名称
//options: 可选参数, 指定有关内存大小及索引的选项
	//capped (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。
	//size (可选)为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。
	//max (可选)指定固定集合中包含文档的最大数量。
>db.createCollection(name, options)
//查看集合
>show collections
//或者
>show tables
//实例 创建固定集合 mycol,整个集合空间大小 6142800 B, 文档最大个数为 10000 个。
>db.createCollection("mycol", {
      capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
//删除集合
>db.collection.drop()

//插入文档
//文档的数据结构和 JSON 基本一样。
//所有存储在集合中的数据都是 BSON 格式。
//BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。
>db.COLLECTION_NAME.insert(document)
//插入文档 例
>db.col.insert({
     title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})
//更新文档
//query : update的查询条件,类似sql update查询内where后面的。
//update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
//upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
//multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
//writeConcern :可选,抛出异常的级别。
>db.collection.update(
   <query>,
   <update>,
   {
     
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
//删除文档
//query :(可选)删除的文档的条件。
//justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
//writeConcern :(可选)抛出异常的级别。
>db.collection.remove(
   <query>,
   {
     
     justOne: <boolean>,
     writeConcern: <document>
   }
)
//查询文档
//query :可选,使用查询操作符指定查询条件
//projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
>db.collection.find(query, projection)
//易于阅读
>db.col.find().pretty()

MongoDb Compass

安装 略

练习11

使用Compass

新建一个数据库:Use DemoDb

插入一个对象:db.users.insert({“name”:“seb”})

查询:db.users.find({“name”:“seb”})

链接NodeJS

|-- mongoDb
    |-- index.js
    |-- package-lock.json
    |-- node_modules
      	|--...

新建一个目录

//cmd
你的目录>npm install mongoose

在此目录下新建一个js文件,我的是index.js

//index.js
//引入包
const mongoose = require('mongoose');

//建立链接
//demo是数据库名
mongoose.connect('mongodb://localhost:27017/demo', {
     
    useNewUrlParser: true, 
    useUnifiedTopology: true
});

//定义模型:Student模型,name对应的数据类型是字符串。
//可以理解为定义:Student表,name列(string类型)
const Student = mongoose.model('Student', {
      
    name: String 
});

//新建一条学生数据
const student = new Student({
      
    name: 'Seb' 
});
//将这个学生数据保存数据库
student.save().then(() => console.log('seb saved'));
//查询所有student数据
Student.find((error, students) => {
     
    if(error) throw error;
    console.log(students);
});
//cmd
你的目录>node index.js

练习12

使用mongoose创建和检索学生

RESTful API

创建具有正确文件架构的网站

创建这样的文件架构:

这只是一个样例

|-- RESTful
    |-- app.js
    |-- package-lock.json
    |-- package.json
    |-- src
    |   |-- controllers
    |   |   |-- StudentController.js
    |   |-- models
    |   |   |-- db.js
    |   |   |-- Student.js
    |   |-- routes
    |       |-- StudentRoute.js
    |-- node_modules
    	|--...
//cmd
你的目录>npm install express
你的目录>npm install mongoose
你的目录>npm install body-parser
//app.js
//这是入口
var studentRoute = require('./src/routes/StudentRoute')
var db = require('./src/models/db');

//数据库建立连接
db.dbConnect;

//student路由打开和监听
studentRoute.on;
studentRoute.listen;
//db.js
const mongoose = require('mongoose');

//数据库url
var url = 'mongodb://localhost:27017/newdb';

//数据库建立连接对应的函数
const dbConnect = mongoose.connect(url,{
    useNewUrlParser: true,
    useUnifiedTopology: true
});

module.exports = {dbConnect}
//Student.js
var mongoose = require('mongoose');

//数据组成
const studentSchema = new mongoose.Schema({
    studentname:{
        type:String,
        unique:true //字段是否唯一
    },
    password:{
        type:String
    }
})

const student = mongoose.model('student',studentSchema)
module.exports = {student}

//StudentRoute.js
var express = require('express');
var bodyParser = require('body-parser');
var student = require('../models/Student');

var port = 3000;
var urlEncodedParser = bodyParser.urlencoded({extended:false});
var studentRoute = express();

var on = studentRoute.route('/students')
    .get((req,res) =>{
        var students = new student.student({
            studentname:req.params.studentname,
            password:req.params.password
        })
        res.send(students)
    })
    .put(urlEncodedParser,(req,res) =>{
        var students = new student.student({
            studentname:req.body.studentname,
            password:req.body.password
        })
        res.send(students)
    })
    .post(urlEncodedParser,(req,res) =>{
        var students = new student.student({
            studentname:req.body.studentname,
            password:req.body.password
        })
        res.send(students)
    });


var listen = studentRoute.listen(port,(err)=>{
    if(err) throw err;
    console.log(`listening port ${port}`);
})

module.exports = {on,listen}
//StudentController.js
//还不知道要写啥,暂时空着
//cmd
你的目录>npm start

可以用postman验证post,put,get

ReactJS

你可能感兴趣的:(全栈,笔记,node.js,es6,postman)