资讯专栏INFORMATION COLUMN

vue+express+mongoose项目构建

SKYZACK / 1586人阅读

摘要:注仅做记录使用又不舍得删除推荐使用相关资料很多的运行环境构建基于全局安装安装过程略配置的淘宝镜象全局安装官方脚手架工具官网文档创建项目基于模板创建创建配置按需,我除了安装之外其他都选了运行与打包测试安装依赖包运行打包配

注(2018-2-12):仅做记录使用,又不舍得删除,推荐使用koa2,koa2相关资料很多的~

1. 运行环境构建(基于macOS Sierra 10.12.4)

全局安装node(v6.9.4)

安装过程略

配置cnpm(npm的淘宝镜象)

sudo npm install -g cnpm --registry=https://registry.npm.taobao.org`

全局安装vue官方脚手架工具vue-cli(vue官网文档)

cnpm install --global vue-cli

2. 创建项目

基于 webpack 模板创建

vue init webpack tifi-music

创建配置按需,我除了安装router之外其他都选了no

运行与打包测试

cd tifi-misic
//安装依赖包
cnpm i
//运行
npm run dev
//打包
npm run build

3. 配置express

在项目根目录下创建server.js文件,内容如下

//用于获取路径
const path = require("path")
//用于读写文件流
const fs = require("fs")
const express = require("express")
//无需cnpm安装,因为是express的中间件bodyParser
//用于解析客户端请求的body中的内容,内部使用JSON编码处理,url编码处理以及对于文件的上传处理.
//bodyParse可以接受客户端ajax提交的json数据,以及url的处理,不使用这个中间件将导致无法接收客户端的json数据
const bodyParser = require("body-parser")
//需要cnpm安装,cookieParser中间件用于获取web浏览器发送的cookie中的内容.
//在使用了cookieParser中间件后,代表客户端请求的htto.IncomingMessage对象就具有了一个cookies属性
//该属性之为一个对象的数组,其中存放了所有web浏览器发送的cookie,每一个cookie为cookies属性值数组中的一个对象.
const cookieParser = require("cookie-parser")
//serve-favicon中间件用于请求网站的icon用法如下
//express().use(favicon(__dirname + "/public/images/favicon.ico"))
const favicon = require("serve-favicon")
//morgan中间件是日志中间件,用于node的日志输出
//进阶用法见http://www.cnblogs.com/chyingp/p/node-learning-guide-express-morgan.html
const logger = require("morgan")
//获取后端路由.我设置在根目录下的server文件,读取下面的index.js
const routes = require("./server/router")
//用于管理配置的插件.统一管理后端服务端口和数据库连接地址等,默认配置在config目录下的default.js中
const config = require("config-lite")
//compression 中间件用于压缩和处理静态内容
//例子:app.use(express.static(path.join(__dirname, "public")))
const compression = require("compression")
//实例化express对象,用于连接中间件
const app = express()


app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

app.use(compression({ threshold: 0 }))
app.use("/api", routes)


app.use(express.static(path.resolve(__dirname, "./dist")))
// 因为是单页应用 所有请求都走/dist/index.html
app.get("*", function(req, res) {
    const html = fs.readFileSync(path.resolve(__dirname, "./dist/index.html"), "utf-8")
    res.send(html)
})
app.listen(config.port, function () {
    console.log(`Server running in port ${config.port}`)
})

解决npm run dev时即开发模式下跨域问题
打开根目录下的config目录下的index文件,配置proxyTable如下:

proxyTable: {
    "/api": {
        //这里的target填服务端的端口的接口地址
        target: "http://localhost:3000/api/",
        changeOrigin: true,
        pathRewrite: {
            "/api": ""
        }
    }
}

创建router
server.js文件中写了const routes = require("./server/router")
这里require的路径就是我们需要创建router的路径
在根目录下创建server文件夹,并在其目录下创建router.js文件,内容如下:

//express的路由中间件,引入等待从controller中添加路由
const router = require("express").Router()
//引入node的文件路径模块path和文件处理模块fs
const path = require("path")
const fs = require("fs")
//读取controller文件下的所有控制器,为了实现动态读取控制器,有空再研究更好的写法
const controllers = fs.readdirSync(path.resolve(__dirname, "./controller"))
//遍历获取到的文件,动态添加express的路由信息:url、type、response即请求路径、请求方式、响应处理函数
controllers.forEach((file) => {
    //获取到具体到控制器
  let controller = require("./controller/" + file)
    //遍历控制器携带的信息
  for (let o in controller) {
        //获取请求路径,未取到则取默认路径 为"/"+文件名(不包括后缀)
    let url = controller[o].url ? controller[o].url : ("/" + o)
        //获取请求方式,未取到则取默认方式 为"get"
    let type = controller[o].type ? controller[o].type : "get"
        //响应处理函数,未取到则使用默认的处理
    let response = controller[o].response ? controller[o].response : (req, res) => {
      res.json({
        success: false,
        info: "没有处理响应的无效路由"
      })
    }
        //设置路由信息
    router[type](url, response)
  }
})
//使用动态设置好的路由
router.use(router)
//输出路由
module.exports = router

创建controller
router.js文件中写了获取同级目录controller下的所有文件
所以我们只需要在server文件夹下的controller中创建一个user的控制器
即创建user.js文件,内容如下:

const userName = [{
    name: "测试用户名0"
  },
  {
    name: "测试用户名1"
  }
]
//"输出待添加的路由信息对象
//每个对象中可设置三个属性:url、type、response(不设置的话均做了默认处理)
module.exports = {
  users: {
    response: (req, res) => {
      res.json(userName)
    }
  },
  reg: {
    type: "post",
    response: (req, res) => {
      res.json("reg")
    }
  }
}

运行express

前面文件创建完成之后,要运行express首先安装依赖包

cnpm i cookie-parser morgan serve-favicon morgan config-lite –save-dev

另外修改文件时需要频繁的重启服务器,全局安装nodemon可以实现自动重启

cnpm install -g nodemon 

然后配置package.json中的scripts添加start命令

"scripts": {
    "dev": "node build/dev-server.js",
    "build": "node build/build.js",
    "start": "nodemon server.js"
}

执行npm run build打包项目用于生产环境

最后命令行里输入node start就可以运行了,命令行输出Server running in port 3000表示express成功启动了,浏览器访问http://localhost:3000/api/users看到输出的测试数据就是成功配置好express了

配置mongoose

安装mongodb并启动(过程省略)

安装mongoose

cnpm install mongoose --save-dev

连接mongodb

编写入口:在server文件下新建一个文件夹名为db,并在其下新建一个文件db.js,内容如下:

//引入node的文件路径模块path和文件处理模块fs
const path = require("path")
const fs = require("fs")
const mongoose = require("mongoose")


// mongodb 连接?
mongoose.connect("mongodb://localhost/tifi-music")
// 此处防止 node.js - Mongoose: mpromise 错误
mongoose.Promise = global.Promise;
let db = mongoose.connection;
db.on("error", console.error.bind(console, "Connect error"))
db.once("open", function() {
    console.log("Mongodb started successfully")
})
//声明待添加的model对象
let model = {}
//读取方式和router一样
const schemas = fs.readdirSync(path.resolve(__dirname, "./model"))
schemas.forEach((file) => {
    //设置数据库表名为读取到的文件名(去除后缀名)
    let name = file.substring(0,file.lastIndexOf("."))
    //获取到的对象就是数据库字段
    let schema = require("./model/" + file)
    //使用mongoose.Schema和mongoose.model完成对数据库表和字段的创建
    model[name] = mongoose.model(name, mongoose.Schema(schema))
})
//输出model对象
module.exports = model

编写model:也在db文件夹下新建一个文件夹名为model,并在其下新建user.js,内容如下:

module.exports = {
  //设计数据库字段,先简单的设置一些常用的字段
  name: String,
  phone: String,
  email: String,
  password: String,
  createTime: Date
}

修改controller:修改controller文件下单user.js为:

//"引入mongoose的model
const model = require("../db/db")
//加密用户的密码
const sha1 = require("sha1")
//mogodb会自动的为我们添加_id字段,类型为objectid,我们要把它转换成创建该用户的时间
const objectIdToTimestamp = require("objectid-to-timestamp")


module.exports = {
  //获取所有用户
  users: {
    response: (req, res) => {
      model.User.find({}, (err, doc) => {
        if (err) console.log(err)
        res.send(doc)
      })
    }
  },
  //用户注册
  reg: {
    type: "post",
    response: (req, res) => {
      console.log(req.body);
      let userRegister = new model.User({
        email: req.body.email,
        password: sha1(req.body.password),
      })
      // 将 objectid转换为用户创建时间,使用是的UTC国际标准时间
      userRegister.createTime = objectIdToTimestamp(userRegister._id)

      //查询邮箱是否已存在于数据库
      model.User.findOne({
        email: (userRegister.email)
          .toLowerCase()
      }, (err, doc) => {
        if (err) console.log(err)
        if (doc) {
          res.json({
            success: false,
            info: "该邮箱已被注册"
          })
        } else {
          userRegister.save(err => {
            if (err) console.log(err)
            console.log(new Date(), "register success")
            res.json({
              success: true,
              data: {
                email: userRegister.email
              }
            })
          })
        }
      })
    }
  }
}

运行mongoose与测试查询与插入

确定连接mongod成功,如果之前配置好nodemon的话,控制台会有Mongodb started successfully

测试插入数据,打开postman进行post请求,成功之后如下图:

![图片描述][3]
- 测试查询数据,打开[postman][2]进行get请求,成功之后如下图:
![图片描述][5]
- 如果前面都成功了,说明已经成功的连接了mongoose,说明全部的基础建设已经搞好了,可以进行下一步的开发了!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82401.html

相关文章

  • 初尝node.js + Express + MongoDB + Vue.js 项目构建(2)

    摘要:使用内在模块发送响应数据监听端口终端打印如下信息使用框架本项目使用的框架来起服务器。数据库中文档每一行的数据的数据结构和基本一样,所有存储在集合中的数据都是格式,是一种类的一种二进制形式的存储格式,简称。 前言 经过上一篇经济基础构建的完成,那么现在正式开始码代码吧! 项目架构 showImg(https://segmentfault.com/img/bVNkQM?w=322&h=58...

    kevin 评论0 收藏0
  • 初尝node.js + Express + MongoDB + Vue.js 项目构建(2)

    摘要:使用内在模块发送响应数据监听端口终端打印如下信息使用框架本项目使用的框架来起服务器。数据库中文档每一行的数据的数据结构和基本一样,所有存储在集合中的数据都是格式,是一种类的一种二进制形式的存储格式,简称。 前言 经过上一篇经济基础构建的完成,那么现在正式开始码代码吧! 项目架构 showImg(https://segmentfault.com/img/bVNkQM?w=322&h=58...

    zhisheng 评论0 收藏0
  • 在线考试系统(vue2 + elementui + express4 + MongoDB)

    摘要:在实际开发过程中发现,考试系统各个表集合都是需要关联,这种非关系型数据库,做起来反而麻烦了不少。数据中既有试卷的信息,也有很多题目。题目都属于该试卷,改试卷又属于当前登录系统的老师即创建试卷的老师。 这是我毕业项目,从0到1,前后台独立开发完成。功能不多,在此记录,温故而知新!项目github地址:https://github.com/FinGet/Exam ,博客地址:https:/...

    warmcheng 评论0 收藏0
  • 基于 Vue2+Node+mongoDB 的前后端分离全栈练手小项目

    摘要:本文源码简介之前刚入门并做好了一个简而全的纯全家桶的项目,数据都是本地模拟请求的详情请移步这里为了真正做到数据库的真实存取,于是又开始入门了并以此来为之前的页面写后台数据接口。 本文源码:Github 简介: 之前刚入门vue并做好了一个简而全的纯vue2全家桶的项目,数据都是本地 json 模拟请求的;详情请移步这里:vue-proj-demo 为了真正做到数据库的真实存取,于是又...

    jay_tian 评论0 收藏0

发表评论

0条评论

SKYZACK

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<