express路由模块化-总结

现在基本上整个增删改查都有了,但是我们发现所有路由和接口api全部写在app.js里面,现在我们把路由拆分出来,单独建立文件夹,用来存储路由和视图ejs,方便后期的维护

大概目录如下


image.png

路由架构/js
登录路由 --- router-login
商品路由 --- router-product
其他路由 --- router-other
商品页面/ejs
公共页面 --- views-public-header.ejs
登录页面 --- views-login-login.ejs
商品页面 ---- views-product
---商品列表---list.ejs
---商品新增---add.ejs
---商品编辑---edit.ejs
其他页面 --- views-other-other.ejs


image.png

1:先来拆分路由吧
新建一个router文件夹,分别建立login、product文件夹
login中新建login.js实现路由,代码如下

let  express = require('express');
let router = express.Router();  //路由拆分使用
const  app = express();
//这里就不是app.get啦全部用router来接管啦
router.get("/",(req,res)=>{
    res.render("login/login");
});

router.get("/login",(req,res)=>{
    res.render("login/login");
});
//导出去暴露使用
module.exports = router;

2:在app.js中引入使用

//路由封装
var  login=require('./router/login/login.js');
//express的自定义路由Router
//login全部去寻找login这个模块里面 再具体定义就好了
//login/ 
//login/user  
//login/pic
app.use('/login',login);  //去寻找login.js这个里面匹配

效果如下


image.png

ps:类似于在路由前面加了一个前缀/login
对,就是这样理解就对啦,现在我们把登录所有的功能移过来

let  express = require('express');
let router = express.Router();
const  app = express();
var md5=require("md5-node");
//解析post提交的数据 
const  bodyParser = require('body-parser')
router.use(bodyParser.urlencoded({ extended: false }))
router.use(bodyParser.json())

const  ejs = require('ejs');
const session = require("express-session");
//设置cookie参数
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 30*60*1000 },
  rolling:true
}))
//数据库操作
var DB =require('../../module/db.js');

//静态文件服务  容易出错2  是express 
app.use(express.static('public'))

//映射upload为虚拟目录,去upload里面寻找图片
app.use('/upload',express.static('upload'))

router.get("/",(req,res)=>{
    res.render("login/login");
});

router.get("/login",(req,res)=>{
    res.render("login/login");
});

//表单提交的后台接口
router.all('/doLogin',(req,res)=>{
    let username = req.body.username;
    let password = md5(req.body.pwd);
    console.log(`${username}---${password}`);
    //var body= { 'username': 'admin', 'pwd': '123456' };
    console.log(req.body);//{ username: 'admin', pwd: '123456' }
    //数据库操作 
    DB.find("user",{
            username:username,
            pwd:password
    },function(err,data){
        if(data.length>0){
                //console.log("登录成功");
                req.session.userinfo= data[0];
                //ejs 全局设置数据,其他页面可以共用
                //app.locals.userinfo=data[0]; 分开后无法这样使用 
                var  userinfo =req.session.userinfo;
                console.log('userinfo=====>'+userinfo);
                res.redirect("/product/list");
            }else{
                console.log("登录失败");
                res.send("")
            }
    });
});

//退出
router.all("/loginOut",(req,res)=>{
    req.session.destroy((err)=>{
        if(err){
            console.log(err);
        }else{
            res.redirect('/login/');
        }
    })
});

module.exports = router;

ps:这里我遇到了几个小问题,需要注意点
1:所有的app.use和app.post都得改成router.use和router.all,方便接管路由
2:所有的路径问题,静态资源库css、图片路径、接口路径都得修改


image.png

3:session问题,我在这里卡了很久终于解决了


image.png

开始一直报错,找不到userinfo,尝试用redirect传递,发现无法使用没有这个api,然后想着用render这里直接渲染list页面,但是发现又得查询一遍数据库,比较麻烦,后来又想用本地存储存储storage来实现,发现有点麻烦,主要是不想在ejs里面写js代码,后面一步步调试,决定用req来传递,发现登录页面成功后,list页面虽然是include引入了header这个模块,也是可以获取到req里面的对象,所以最后决定直接获取,本来想用 //app.locals.userinfo=data[0]; 分开后无法这样使用,这个自带的locals对象的,发现编译一直报错,找不到,就算用router接管传递也不行,最后放弃,主要是没时间折腾了

最后效果图


image.png

登录模块弄完了,接下来弄商品模块
根据功能,分别拆分接口,新建文件夹存储单独的模块视图ejs,这里用一个product.js来存储所有商品的相关api接口和路由,代码如下

let  express = require('express');
const  app = express();
let router = express.Router();
//图片上传
var multiparty = require('multiparty');
var http = require('http');
//var util = require('util');

//数据库操作
var DB =require('../../module/db.js');

//静态文件服务  容易出错2  是express 
router.use(express.static('public'))
//映射upload为虚拟目录,去upload里面寻找图片
router.use('/upload',express.static('upload'))


router.get("/",(req,res)=>{
    res.send("product  index")
});

//商品列表
router.all("/list",(req,res)=>{     
    DB.find('shop',{},function(err,data){
        //if(data.length>0){
            res.render("product/list",{shopList:data,userinfo:req.session.userinfo});
        //}else{
        //  res.render("productList");
        //}
    });
});


//商品增加
router.all("/add",(req,res)=>{
    res.render("product/add")
});

router.all("/edit",(req,res)=>{
    res.render("product/edit")
});
router.all("/del",(req,res)=>{
    res.send("product/delete")
});






//商品新增接口
router.all("/shopAdd",(req,res)=>{
    var form = new multiparty.Form();
    //配置文件上传目录,后续需要映射虚拟目录才可以显示
    form.uploadDir = "upload";//新建一个upload目录,专门存储上传图片
    
    form.parse(req, function(err, fields, files) {
        //console.log(fields);
        //console.log(files);
        let  shopname= fields.shopname[0];  
        //图片路径 注意是files
        let  shoppic = files.shoppic[0].path;
        let  shopprice = fields.shopprice[0];
        let  shopfee = fields.shopfee[0];   
        let  shopDesc = fields.shopDesc[0];
        //console.log(shopname);
        //console.log(shoppic);
        //console.log(shopprice);
        //console.log(shopfee);
        //console.log(shopDesc);
        //插入数据库
        DB.insert('shop',{
                title:shopname,
                pic:shoppic,
                price:shopprice,
                fee:shopfee
                
            },(err,data)=>{
            //if(!err){
                res.redirect("/product/list")
            //}
        })

    })
    
});


//商品修改初始化页面
router.all("/shopEdit",(req,res)=>{
    //获取id
    let  id =req.query.id;
    console.log(id);
    //查询数据
    DB.find('shop',{_id:new DB.objectId(id)},(err,data)=>{
        //console.log(data[0]);
        //console.log(data);
        //渲染修改视图页面
        res.render('product/edit',{shopList:data[0]})
    })
});

//商品修改接口提交修改
router.all("/doshopEdit",(req,res)=>{
    
    var form = new multiparty.Form();
    //配置文件上传目录,后续需要映射虚拟目录才可以显示
    form.uploadDir = "upload";//新建一个upload目录,专门存储上传图片
    
    form.parse(req, function(err, fields, files) {
        //console.log(fields);
        //先拿到修改的ID,更新使用
        let _id = fields._id[0];
        console.log(_id);
        let  shopname= fields.shopname[0];  
        //图片路径 注意是files
        let  shoppic = files.shoppic[0].path;
        let  shopprice = fields.shopprice[0];
        let  shopfee = fields.shopfee[0];   
        let  shopDesc = fields.shopDesc[0];
        console.log(files);
        //console.log(shoppic);
        //console.log(shopprice);
        //console.log(shopfee);
        //console.log(shopDesc);
        //单独处理图片
        let  orginFileName =files.shoppic[0].originalFilename;
        if(orginFileName){//有修改图片
            var setData={
                title:shopname,
                pic:shoppic,
                price:shopprice,
                fee:shopfee
            }
        }else{  //没有修改图片就不添加
            var setData={
                title:shopname,
                price:shopprice,
                fee:shopfee
            }   
        }
        //删除临时文件
        //fs.unlink(shoppic,(err)=>{console.log(err)});
        
        //根据id修改更新数据库
        DB.update('shop',{"_id":new DB.objectId(_id)},setData
                ,function(err,data){
                    if(!err){
              res.redirect('/product/list');
          }
                }
        );
        

    })
});

//删除文件
router.all("/shopDel",(req,res)=>{
    let _id= req.query.id;
    console.log("_id==="+_id);
    //根据id修改更新数据库
    DB.deleteOne('shop',{"_id":new DB.objectId(_id)}
            ,function(err){
                if(!err){
                    res.redirect('/product/list');  
                    console.log("删除成功");
                }
            }
    );
    
});

module.exports = router;

ps:这个还算顺利,没遇到什么麻烦,基本只要修改接口地址和路径,不会有太大的问题,不过这渲染list页面的时候,需要把登录的userinfo传递过来,否则获取不到登录名哦


image.png

最后按步骤提取add.edit.remove等ejs放到对应目录
最后再来看看app.js,修改完之后,很清爽吧

const  express =require('express');
const  app = express();

const  ejs = require('ejs');

var fs = require("fs");
const session = require("express-session");
//设置cookie参数
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 30*60*1000 },
  rolling:true
}))
//注意这里是字符串   容易出错1 
app.set("view engine",'ejs')
//路由封装
var  login=require('./router/login/login.js');

var  admin = require('./router/admin.js');

var  product = require('./router/product/product.js');

//静态文件服务  容易出错2  是express 
app.use(express.static('public'))
//映射upload为虚拟目录,去upload里面寻找图片
app.use('/upload',express.static('upload'))

//必须放在上面 否则不生效  
app.use((req,res,next)=>{
    console.log(req.url);
    let visUrl = req.url;
    //通过session来做  然后login页个访问接口不需要判断
    if(visUrl == "/login/login" || visUrl == "/login/" || visUrl == "/login/doLogin"){
        console.log("visUrl======"+visUrl);
        next();  //不需要校验 
    }else{
        console.log("userinfo="+req.session.userinfo);
        if(req.session.userinfo && req.session.userinfo.username !=''){
            next();
        }else{
            res.redirect('/login/login');
        }
    }
});



//有session 可以直接访问主页 productList  没有就不能访问

//登录前的中间件判断  没有登录就不能进入主页 productList

//express的自定义路由
//admin  全部去寻找admin这个模块里面 再具体定义就好了 
//admin/user  
//admin/pic
app.use('/login',login);

app.use('/admin',admin)

app.use('/product',product)

app.listen("3333",()=>console.log("server  start"));

这里需要做的就是中间件登录前的判断,没有登录过的用户,无法直接进入商品列表list页面哦
同样这里也要再次定义一下静态文件托管中间件static,删除会报错哦

最后大功告成,加油···

你可能感兴趣的:(express路由模块化-总结)