静态资源:

都写死了的资源,如 css,html

解析规则:

所有路由中间件都在一个数组中,js 引擎会按照代码先后顺序添加路由中间件

当请求发送到服务器时,服务器获取当前的请求信息(请求方式、请求路由路径)

遍历数组,找到第一个匹配请求路由路径请求方式必须完全一致)到的路由或者中间件,执行其回调函数

意味着: 声明多个同名路由时,始终解析第一个

如果没找到,返回一个状态码为 404 的响应, Cannot GET / xxx    或者  Cannot POST / xxx

中间件 middleware

当有多个路由做同一件事情,这时就会交给中间件去完成

本质上就是一个函数 (request, response, next)=>{}

express 框架 实现服务器    完全是由 路由 和 中间件 组成的

需要调用 next() 方法,才会接下来处理下面的中间件或者路由,否则卡住了

  • app.use(express.static('./public'));    //默认调用next

接受请求,通过分析参数,找到了 public 对应资源就返回响应

将该文件夹下所有静态资源暴露出去

例如: 文件夹有

public/index.html

public/css/index.css

就可在浏览器访问

127.0.0.1:3000/index.html

127.0.0.1:3000/css/index.css

  • app.use(express.urlencoded({extended: true}));    //默认调用next

解析 请求体 数据,结果数据挂载到 req.body 上

  • 实例分析: 
  • // 1. 导入 express 模块
    const express = require('express'); // 2. 创建 app 应用对象
    const app = express(); // 3. 写业务逻辑:处理请求,返回响应 /**** 配置内置 中间件 (express 自带) ****/
    // 将该文件夹下所有静态资源暴露出去
    // 接受请求,通过分析参数,找到了 public 对应资源就返回响应
    app.use(express.static('./public')); // public 下有 index.html css/index.css
    // 可在127.0.0.1:3000/index.html css/index.css // 解析请求体数据,结果数据挂载到 req.body 上
    app.use(express.urlencoded());
    // 默认调用 next()
    /**** 以上两个一般结合使用 ****/ // 中间件默认能接收并处理所有请求
    // 需要调用 next() 方法,才会接下来处理下面的中间件或者路由,否则卡住了
    app.use((request, response, next)=>{
    next(); // 调用下一个中间件或者路由
    });
    /**************************************/
    // route 路由的组成: app.请求方式('/路由路径', 句柄函数);
    app.get('/login', (request, response)=>{
    console.log(request.body);
    response.send('Login Page Response!');
    }); app.post('/register', (request, response)=>{
    console.log(request.query);
    response.send('Register Page Response!');
    }); // 4. 监听端口号:一个端口号 有且只能运行 一个程序
    app.listen(3000, err=>console.log(err?err:'服务器启动成功 : http://127.0.0.1:3000'));

登录/注册实例

  • 什么时候用 get ,什么时候用 post?

get 请求 只有 请求字符串,

post 请求 既有 请求字符串,又有 表单数据 form-data

1. 凡是涉及到用户的隐私数据,就用 post,相对安全

2. 其他就用 get

  • 业务逻辑

1. 导入 exoress 框架

2. 注册路由

由于默认访问不到静态资源,所以1引入中间件,暴露静态资源

默认不能解析 请求体 ,则2引入中间件,解析 请求体 数据(优先级低于上一中间件,避免多余分析)

获取用户提交的表单数据        req.body

对数据进行正则验证(验证数据的规范)

检查用户名是否存在

连接数据库

User.findOne();

保存在数据库中

User.create();

无论 失败/成功 都要返回

3. 登录路由

4. 设置端口号,启动服务器监听

  • 初次尝试,源代码

package.json

  • {
    "name": "node_express",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
    "express": "^4.16.4",
    "mongoose": "^5.4.0"
    }
    }

/route/register.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>用户注册</title> <link rel="stylesheet" type="text/css" href="css/index.css"/>
    </head> <body>
    <div id="outer_box" class="register">
    <h2>用户注册</h2>
    <form action="http://localhost:3000/register" method="post">
    <div class="clothes">
    <label for="input_name">用&nbsp;户&nbsp;名</label>
    <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
    </div> <div class="clothes">
    <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
    <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
    </div> <div class="clothes">
    <label for="input_repwd">确认密码</label>
    <input id="input_repwd" type="password" name="user_repwd" placeholder="请再次输入密码" />
    </div> <div class="clothes">
    <label for="input_email">注册邮箱</label>
    <input id="input_email" type="text" name="user_email" placeholder="请输入邮箱地址" />
    </div> <div class="clothes">
    <button class="register btn" type="submit">注册</button>
    <a class="btn" href="http://localhost:3000/login">
    <button type="button">登录</button>
    </a>
    </div>
    </form>
    </div> <script type="text/javascript" src="../index.js"></script>
    </body>
    </html>

/route/login.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>用户登录</title> <link rel="stylesheet" type="text/css" href="css/index.css"/>
    </head> <body>
    <div id="outer_box" class="login">
    <h2>用户登录</h2>
    <form action="http://localhost:3000/login" method="post">
    <div class="clothes">
    <label for="input_name">用&nbsp;户&nbsp;名</label>
    <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
    </div> <div class="clothes">
    <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
    <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
    </div> <div class="clothes">
    <a class="btn" href="http://localhost:3000/register">
    <button type="button">注册</button>
    </a>
    <button class="login btn" type="submit">登录</button>
    </div>
    </form>
    </div> </body>
    </html>

/route/css/index.css

  • body {
    width: 100%;
    height: 100%; color: #000;
    background: #b9c2a4;
    background-size: cover; /* 指定背景图片大小 */
    } /*************************************************/
    #outer_box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #1a45c3;
    } #outer_box.login {
    color: #9e098b;
    } #outer_box.register {
    color: #1a45c3;
    } #outer_box>h2{
    padding-bottom: 40px;
    margin-left: -50px;
    } .clothes {
    width: 260px;
    display: flex;
    justify-content: space-between;
    margin: 20px 0;
    font-size: 18px;
    line-height: 32px;
    } .clothes>label{
    width: 80px;
    text-align: center;
    } .clothes>input{
    width: 170px;
    height: 32px;
    } button {
    width: 100%;
    height: 100%; font-size: 16px;
    background-color: #c4ceda;
    cursor: pointer;
    } .clothes .btn{
    width: 64px;
    height: 32px;
    margin: 0 20px;
    } .clothes button.register{
    background-color: #1a45c3;
    color: #fff;
    } .clothes button.login{
    background-color: #9e098b;
    color: #fff;
    }

/db/connectDB.js

  • const mongoose = require('mongoose');
    
    const promiseConnect = new Promise((resolve, reject)=>{
    mongoose.connect('mongodb://localhost:27017/user_database', {useNewUrlParser:true})
    mongoose.connection.once('open', err=>{
    if(err){
    console.log(err);
    reject(err);
    }else{
    resolve(true);
    };
    });
    }); module.exports = promiseConnect;

/db/tableModel.js

  • const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    const studentsSchema = new Schema({
    "userName": {
    "type": String,
    "default": "test"
    },
    "userPassword": {
    "type": String,
    "default": "123456"
    },
    "userEmail": {
    "type": String,
    "unique": true
    },
    "createTime": {
    "type": Date,
    "default": Date.now()
    }
    }); const studentsModel = mongoose.model("user_info", studentsSchema); module.exports = studentsModel;

index.js

  • const express =  require('express');
    const promiseConnect = require('./db/connectDB.js');
    const userInfoModel = require('./db/tableModel.js'); promiseConnect.then(async result=>{
    if(result){
    isConeected = true;
    };
    }).catch(err=>console.log(err)); const app = express(); /*********************** 中间件 **********************/
    // 暴露路由 login.html register.html
    app.use(express.static('route')); // 默认调用 next(); // 将 用户输入的数据 挂载到 请求体 request.body 上
    app.use(express.urlencoded({extended: true})); // 默认调用 next(); /************************ get ***********************/
    app.get('/', (request, response)=>{
    response.redirect('./login.html');
    }); app.get('/login', (request, response)=>{
    response.redirect('./login.html');
    }); app.get('/register', (request, response)=>{
    response.redirect('./register.html');
    }); /************************ post ***********************/ let isConeected = false;
    let canBeCreated = false;
    let createSuccess = false; let logined = false; app.post('/register', async (request, response)=>{
    if(isConeected){
    let uName = request.body['user_name'];
    let uPwd = request.body['user_pwd'];
    let urePwd = request.body['user_repwd'];
    let uEmail = request.body['user_email'];
    userInfo = {
    "userName": uName,
    "userPassword": uPwd,
    "userEmail": uEmail
    }; canBeCreated = false;
    createSuccess = false;
    someThingWrong = false; console.log('\n------------------注册--------------------');
    if(urePwd !== uPwd){
    console.log("(づ╥﹏╥)づ[两次输入不一致`]");
    response.redirect('./register.html');
    return ;
    }else if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
    console.log("(づ╥﹏╥)づ[用户名不合法`]");
    response.redirect('./register.html');
    return ;
    }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
    console.log("(づ╥﹏╥)づ[密码不合法`]");
    response.redirect('./register.html');
    return ;
    }else if(!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(uEmail))){
    console.log('(づ╥﹏╥)づ[邮箱不合法`]');
    response.redirect('./register.html');
    return ;
    }else{
    canBeCreated = true;
    const badEmail = await userInfoModel.findOne({"userEmail": uEmail});
    if(badEmail){
    console.log('(づ╥﹏╥)づ[邮箱已存在`]');
    response.redirect('./register.html');
    return ;
    };
    }; const fond = await userInfoModel.findOne({"userName": uName});
    if(!fond && canBeCreated){
    await userInfoModel.create(userInfo);
    createSuccess = true;
    console.log('(o゜▽゜)o☆[注册成功!]☆');
    }else{
    console.log('(づ╥﹏╥)づ[用户名已存在`]');
    };
    }; if(createSuccess){
    response.redirect('./login.html');
    }else{
    response.redirect('./register.html');
    };
    }); app.post('/login',async (request, response)=>{
    if(isConeected){
    let uName = request.body['user_name'];
    let uPwd = request.body['user_pwd'];
    userInfo = {
    "userName": uName,
    "userPassword": uPwd
    }; logined = false; console.log('\n------------------登录--------------------');
    if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
    logined = false;
    // 用户名不存在
    }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
    logined = false;
    // 密码错误
    }; const findName = await userInfoModel.findOne({"userName": uName});
    const findPwd = await userInfoModel.findOne({"userPassword": uPwd});
    if(findName && findPwd){
    logined = true;
    };
    }; console.log(logined?'(o゜▽゜)o☆[登录成功!]☆':'(づ╥﹏╥)づ[用户名或密码错误`]');
    response.redirect('./login.html');
    }); /**************** 监听 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\nHunting Happy!'));

 


改进后,源代码

package.json

  • {
    "name": "node_express",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
    "express": "^4.16.4",
    "mongoose": "^5.4.0"
    }
    }

templates/login.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>用户登录</title> <link rel="stylesheet" type="text/css" href="css/index.css"/>
    </head> <body>
    <div id="outer_box" class="login">
    <h2>用户登录</h2>
    <form action="http://localhost:3000/login" method="post">
    <div class="clothes">
    <label for="input_name">用&nbsp;户&nbsp;名</label>
    <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
    </div> <div class="clothes">
    <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
    <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
    </div> <div class="clothes">
    <a class="btn" href="http://localhost:3000/register">
    <button type="button">注册</button>
    </a>
    <button class="login btn" type="submit">登录</button>
    </div>
    </form>
    </div>
    </body>
    </html>

templates/register.html

  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>用户注册</title> <link rel="stylesheet" type="text/css" href="css/index.css"/>
    </head> <body>
    <div id="outer_box" class="register">
    <h2>用户注册</h2>
    <form action="http://localhost:3000/register" method="post">
    <div class="clothes">
    <label for="input_name">用&nbsp;户&nbsp;名</label>
    <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
    </div> <div class="clothes">
    <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
    <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
    </div> <div class="clothes">
    <label for="input_repeat_pwd">确认密码</label>
    <input id="input_repeat_pwd" type="password" name="user_repeat_pwd" placeholder="请再次输入密码" />
    </div> <div class="clothes">
    <label for="input_email">注册邮箱</label>
    <input id="input_email" type="text" name="user_email" placeholder="请输入邮箱地址" />
    </div> <div class="clothes">
    <button class="register btn" type="submit">注册</button>
    <a class="btn" href="http://localhost:3000/login">
    <button type="button">登录</button>
    </a>
    </div>
    </form>
    </div>
    </body>
    </html>

templates/css/index.css

  • @charset "utf-8";
    
    * {
    margin: 0px;
    padding: 0px;
    } .clearfix {
    zoom:;
    } .clearfix:before,
    .clearfix:after {
    content: "";
    display: table;
    clear: both;
    } .unSelectedAble {
    /* 内容不可以被选中 */
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    } body {
    width: 100%;
    height: 100%; color: #000;
    background: #b9c2a4;
    background-size: cover; /* 指定背景图片大小 */
    } /*************************************************/
    #outer_box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #1a45c3;
    } #outer_box.login {
    color: #9e098b;
    } #outer_box.register {
    color: #1a45c3;
    } #outer_box>h2{
    padding-bottom: 40px;
    margin-left: -50px;
    } .clothes {
    width: 260px;
    display: flex;
    justify-content: space-between;
    margin: 20px 0;
    font-size: 18px;
    line-height: 32px;
    } .clothes>label{
    width: 80px;
    text-align: center;
    } .clothes>input{
    width: 170px;
    height: 32px;
    } button {
    width: 100%;
    height: 100%; font-size: 16px;
    background-color: #c4ceda;
    cursor: pointer;
    } .clothes .btn{
    width: 64px;
    height: 32px;
    margin: 0 20px;
    } .clothes button.register{
    background-color: #1a45c3;
    color: #fff;
    } .clothes button.login{
    background-color: #9e098b;
    color: #fff;
    }

db/index.js

  • const mongoose = require('mongoose');
    
    module.exports = new Promise((resolve, reject)=>{
    mongoose.connect('mongodb://localhost:27017/user_database', {useNewUrlParser:true})
    mongoose.connection.once('open', err=>{
    if(err){
    console.log(err);
    reject(err);
    }else{
    resolve('数据库已连接');
    };
    });
    });

models/index.js

  • const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    const fieldSchema = new Schema({
    "userName": {
    "type": String,
    "unique": true,
    "required": true
    },
    "userPassword": {
    "type": String,
    "unique": true,
    "required": true
    },
    "userEmail": {
    "type": String,
    "unique": true,
    "required": true
    },
    "createTime": {
    "type": Date,
    "default": Date.now()
    }
    }); module.exports = mongoose.model("user_info", fieldSchema);

index.js

  • const express =  require('express');
    const promiseConnect = require('./db');
    const userInfoModel = require('./models'); const app = express(); /*********************** 中间件 **********************/
    // 暴露路由 login.html register.html
    app.use(express.static('templates')); // 默认调用 next(); // 将 用户输入的数据 挂载到 请求体 request.body 上
    app.use(express.urlencoded({extended: true})); // 默认调用 next(); /************************ get ***********************/
    app.get('/', (request, response)=>{
    response.redirect('./login.html');
    }); app.get('/login', (request, response)=>{
    response.redirect('./login.html');
    }); app.get('/register', (request, response)=>{
    response.redirect('./register.html');
    }); /************************ post ***********************/
    let logged = false ;
    promiseConnect.then(async result=>{
    console.log(result); app.post('/register', async (request, response)=>{
    const {
    user_name:uName,
    user_pwd:uPwd,
    user_repeat_pwd:urePwd,
    user_email:uEmail,
    } = request.body; /**** 解构赋值 ****/
    // let uName = request.body['user_name'];
    // let uPwd = request.body['user_pwd'];
    // let urePwd = request.body['user_repeat_pwd'];
    // let uEmail = request.body['user_email'];
    userInfo = {
    "userName": uName,
    "userPassword": uPwd,
    "userEmail": uEmail
    }; let errInfo = {}; if(urePwd !== uPwd){
    errInfo.repeatPassword = '两次输入不一致';
    };
    if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
    errInfo.name = '用户名不合法';
    };
    if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
    errInfo.password = '密码不合法';
    };
    if(!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(uEmail))){
    errInfo.email = '邮箱不合法';
    }; const badEmail = await userInfoModel.findOne({"userEmail": uEmail});
    if(badEmail){
    errInfo.emailRegistered = '邮箱已被注册';
    }; if(errInfo.repeatPassword || errInfo.name || errInfo.password || errInfo.email){
    response.send(errInfo);
    return;
    }; const fond = await userInfoModel.findOne({"userName": uName});
    if(fond){
    response.send({"error":'用户名已被注册'});
    }else{
    await userInfoModel.create(userInfo);
    response.send({"success":'注册成功'});
    };
    }); app.post('/login',async (request, response)=>{
    logged = false;
    let uName = request.body['user_name'];
    let uPwd = request.body['user_pwd'];
    userInfo = {
    "userName": uName,
    "userPassword": uPwd
    }; if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
    logged = false; // 用户名不存在
    }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
    logged = false; // 密码错误
    }; const findName = await userInfoModel.findOne({"userName": uName});
    const findPwd = await userInfoModel.findOne({"userPassword": uPwd});
    if(findName && findPwd){
    logged = true;
    }; response.send(logged?{"success":'登录成功'}:{"error":'用户名或密码错误'});
    });
    }).catch(err=>console.log(err)); /**************** 端口号 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\nHunting Happy!'));

Node.js_express_中间件 middleware_登录/注册实例源代码的更多相关文章

  1. Vue学习之路之登录注册实例代码

    Vue学习之路之登录注册实例代码:https://www.jb51.net/article/118003.htm vue项目中路由验证和相应拦截的使用:https://blog.csdn.net/wa ...

  2. vue-cli——vue-resource登录注册实例

    前言 使用vue-resource请求接口非常方便,在使用前需安装vue-resource依赖并在入口文件main.js中声明. 实例功能简述 本实例只有简单的两个模块:登录和注册,主要演示如何用vu ...

  3. 2.node.js (二)服务器登录注册 与 包的发布

    get: 不安全 小 2k 数据会在地址栏上显示 从服务器获取 快 post: 相对安全 https 大 1G 不会 向服务器发送 慢 get:直接解析url地址 借助 url模块 var urlOb ...

  4. ASP.NET简单登录注册实例

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  5. node+mysql+express实现登录/注册/修改密码/删除用户 接口

    实现用户的注册.登录.修改密码.删除用户操作 用到的数据库:nodecms:表:user 目录结构: db目录下存放数据库操作语句: userSQL.js 用户有关的操作语句 router目录 接口路 ...

  6. Node.js_express_浏览器存储技术 Cookie(服务器将少量数据交于浏览器存储管理)

    浏览器存储技术 Cookie 服务器将少量数据交于浏览器存储管理 解决 http 无状态协议的问题(无法区分多次请求是否发送自同一客户端) 一个网页一般最多 20个的 cookie,每个 cookie ...

  7. Node.js_express_服务器渲染页面 ejs

    服务器渲染页面 ejs 高效的 js 模版引擎 将数据提前渲染到页面上, 再将渲染好的页面返回响应给浏览器 提高首页加载速度 SEO 提前处理,提高加载速度 下载 ejs 包 npm install ...

  8. Node.js_express_临时会话对象 session

    临时会话对象 session 也是用来 解决 http 无状态协议的问题(无法区分多次请求是否发送自同一客户端) npm install express-session npm install con ...

  9. Nodejs学习总结 -Express 登录注册示例(二)

    项目创建后,我们来做个登录注册实例,详细操作步骤如下. 1.新建项目demo ,具体操作步骤参考上一章内容 https://www.cnblogs.com/Anlycp/ 2.添加mysql和sess ...

随机推荐

  1. Git 分支(一)简介&创建分支

    理解Git暂存区 文件.git/index是一个包含文件索引的目录树,像是一个虚拟的工作区.在这个虚拟工作区的目录树中,记录了文件名和文件的状态信息.以便快速检测文件的变化.              ...

  2. SpringBoot系列: 制作Docker镜像的全过程

    本文主要参考了 https://segmentfault.com/a/1190000016449865 , 感谢作者的付出. 另外,  在本文中, 演示了Windows+Maven+Docker To ...

  3. Beamer 中的页面链接

    \documentclass[]{beamer} \usetheme{Madrid} \usenavigationsymbolstemplate{} \title{Main Title} \autho ...

  4. 淘宝网站上的 HTTP 缓存问题两则

    在阅读本文前推荐你先阅读我的前两篇文章< 扼杀 304,Cache-Control: immutable>和<关于缓存和 Chrome 的“新版刷新”>:下面要说的两个问题是在 ...

  5. Java部分概念理解

    第1部分 方法 1.1 方法基本概念 1) 方法:用于封装一段特定功能代码,尽可能一个方法至只实现一个基本功能,相当于C语言中的函数: 2) 方法可以多次调用: 3) 避免代码冗余,便于维护,便于团队 ...

  6. AS中的minSdkVersion、compileSdkVersion、targetSdkVersion、buildTools及tools关系和区别

    1.参考文章关于compileSdk.minSdk.targetSdk的文章 http://chinagdg.org/2016/01/picking-your-compilesdkversion-mi ...

  7. 同步Name到Comment 及 同步 Comment 到Name

    在 PowerDesigner执行命令  Tools->Execute Commands->Edit/Run Scripts 代码一:将Name中的字符COPY至Comment中 Opti ...

  8. Python列表中查找某个元素的索引(多个)

    enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中. 以下是 enumerate() 方法的语法: e ...

  9. Vue相关目录

    cli入门-项目搭建 组件 Router路由 生命周期 数据监听 cli搭建web服务介绍 vuex和axios介绍

  10. 【原创】Linux基础之查看linux发行版以及内核版本

    redhat查看发行版 # cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 查看内核版本 # uname -aLinux $h ...