前记
在学习 vue 的路上从开始看 api 到写了几个小项目后, 对 vue 有了一定的了解, 但是一直没做过全栈类的项目. 这次跟着慕课的视频做了个完整的全栈类项目, 特此一记, 来巩固下知识!
技术
前端
使用 vue-cli 搭建前端基本框架 + vue-router 完成前端路由 + vuex 管理状态
后端
基于 nodejs 使用 express 脚手架生成 express 项目框架 + mongoose 操作数据库
数据库
mongodb 数据库
项目搭建
安装 vue-cli
初始化 vue 项目目录
sudo vue init webpack 项目名称 (由于我是 mac 电脑, 需要 sudo 权限; 项目名必须是小写, 大写字母会报错)
复制代码
写 vue 项目
在未建立后端代码的时候可以使用 webpack 自带的插件进行 mock 数据, 在 build/webpack.dev.conf.js 里面做如下修改, 在接口请求到 / goods 的时候就会请求到我们事先写好的 json 数据了
- //mock 数据
- const goodsData = require('./../mock/GoodsList.json')
- devServer: {
- ...
- before:function (app) {
- // 模拟 mock 数据
- app.get('/goods',function (req,res) {
- res.json(goodsData)
- })
- }
- },
复制代码
安装 express 脚手架
sudo npm i -g express-generator
复制代码
初始化 express 项目目录
进入到项目目录下 express server
复制代码
安装 mongodb 数据库
技术点详解
前端
使用 vue-router 实现前端路由功能
使用 vue-infinite-scroll 插件实现上拉加载功能
使用 axios 来实现前后端通讯
使用 vue-lazyLoad 插件实现图片的懒加载
使用尤大的 currency.js 实现全局过滤器功能
使用 vuex 管理购物车数量
(所用前端技术比较常见, 不是本次记述重点)
后端
安装 mongoose 插件
mongoose 基础入门 https://www.cnblogs.com/xiaohuochai/p/7215067.html
npm i mongoose -S
复制代码
2. 创建 models 文件目录用来存放数据库字段模型(users,goods)
- const mongoose = require('mongoose') // 引入 mongoose
- const schema = mongoose.Schema
- //new 一个 schema 对象, 参数为字段及其类型
- const userSchema = new schema({
- "userId": String,
- "userName": String,
- "userPwd": String,
- "orderList": Array,
- "cartList": [{
- "productId": String,
- "productName": String,
- "salePrice": String,
- "productImage": String,
- "checked": String,
- "productNum": String
- }],
- "addressList": [{
- "addressId": String,
- "userName": String,
- "streetName": String,
- "postCode": Number,
- "tel": Number,
- "isDefault": Boolean
- }]
- })
- // 模型创建之后暴露出来, mongoose.model('模型名称', 模型对象, 数据库集合名(默认会添加 s 可以不填, 否则需要制定数据库创建出来的模型名))
- module.exports = mongoose.model('user', userSchema)
复制代码
3. 创建路由文件
在 routes 文件夹下创建 users.js 和 goods.js 分别对应 / users 和 / goods 路由. 同时需要在 app.js 中进行引用.
- var indexRouter = require('./routes/index');//index 路由
- var usersRouter = require('./routes/users');//users 路由
- var goodsRouter = require('./routes/goods');//goods 路由
- app.use('/', indexRouter);
- app.use('/users', usersRouter);
- app.use('/goods', goodsRouter);
复制代码
4. 连接数据库
- // 引入依赖
- const express = require('express')
- const mongoose = require('mongoose')
- const goods = require('../models/goods')
- const users = require('../models/users')
- const router = express.Router()
- // 连接数据库
- //connect()最简单的使用方式, 就是只要传入 url 参数即可, 如下所示. 连接到本地 localhost 的 db1 服务器
- //mongoose.connect('mongodb://localhost/db1');
- // 如果还需要传递用户名, 密码, 则可以使用如下方式
- //mongoose.connect('mongodb://username:password@host:port/database?options...');
- mongoose.connect('mongodb://140.143.234.88:27017/db_demo')
- // 监听连接状态(已连接)
- mongoose.connection.on('connected', () => {
- console.log('MongoDb connected successful!')
- })
- // 失败
- mongoose.connection.on('err', () => {
- console.log('MongoDb connected fail!')
- })
- // 断开连接
- mongoose.connection.on('disconnected', () => {
- console.log('MongoDb disconnected!')
- })
复制代码
5. 编写获取产品列表接口(mongoose 查询用法)
- router.get('/list', (req, res, next) => {
- const page = parseInt(req.param('page')) // 获取页码参数
- const pageSize = parseInt(req.param('pageSize')) // 获取一页有多少条数据参数
- const sort = req.param('sort') // 获取排序参数
- const priceLevel = req.param('priceLevel') // 获取价格区间
- const skip = (page - 1) * pageSize // 计算跳过多少条
- let params = {} // 查询参数
- let startPrice = '', endPrice =''
- if (priceLevel != 'all') {
- switch (priceLevel) {
- case '0':
- startPrice = 0
- endPrice = 100
- break
- case '1':
- startPrice = 100
- endPrice = 500
- break
- case '2':
- startPrice = 500
- endPrice = 1000
- break
- case '3':
- startPrice = 1000
- endPrice = 5000
- break
- }
- params = {
- salePrice: {
- $gt: startPrice,
- $lt: endPrice
- }
- }
- }
- const goodsModel = goods.find(params).skip(skip).limit(pageSize) // 查询后跳过多少条限制一页多少条, 返回计算后的模型
- goodsModel.sort({'salePrice': sort}) // 对模型进行排序
- goodsModel.exec((err, doc) => {
- if (err) {
- res.json({
- status: -1,
- msg: err.message
- })
- } else {
- res.json({
- status: 0,
- msg: '',
- result: {
- count: doc.length,
- list: doc
- }
- })
- }
- })
- })
复制代码
6. 编写加入购物车接口(mongosse 增加数据用法)
- router.post('/addCart', (req, res, next) => {
- const userId = req.cookies.userId
- const productId = req.body.productId
- let userProductId = ''
- // 查询 user 表
- users.findOne({userId: userId}, (err1, userDoc) => {
- if (err1) {
- res.json({
- status: -1,
- msg: err.message
- })
- } else {
- if (userDoc) {
- // 遍历 user 表的购物车列表是否已有此商品
- userDoc.cartList.forEach(item => {
- if (item.productId == productId) {
- userProductId = productId
- item.productNum++
- }
- })
- if (userProductId) {
- // 已添加的商品只增加数量
- userDoc.save((err2, doc2) => {
- if (err2) {
- res.json({
- status: -1,
- msg: err2.message
- })
- } else {
- res.json({
- status: 0,
- msg: '操作成功',
- result: ''
- })
- }
- })
- } else {
- // 未添加的查询 goods 表信息
- goods.findOne({productId: productId}, (err3, goodsDoc) => {
- if (err3) {
- res.json({
- status: -1,
- msg: err3.message
- })
- } else {
- if (goodsDoc) {
- // 查出来的信息赋值给 user 表的 cartList
- goodsDoc.productNum = 1
- goodsDoc.checked = 1
- userDoc.cartList.push(goodsDoc)
- userDoc.save((err4, doc4) => {
- if (err4) {
- res.json({
- status: -1,
- msg: err2.message
- })
- } else {
- res.json({
- status: 0,
- msg: '操作成功',
- result: ''
- })
- }
- })
- }
- }
- })
- }
- }
- }
- })
- })
复制代码
7. 删除购物车商品接口(mongoose 删除用法)
- router.post('/cartDel', (req, res, next) => {
- const userId = req.cookies.userId
- const productId = req.body.productId
- user.update({
- userId: userId
- },
- {
- // 使用 $pull
- $pull: {
- cartList: {
- productId: productId
- }
- }
- }, (err, doc) => {
- if (err) {
- res.json({
- status: -1,
- msg: err.message
- })
- } else {
- if (doc) {
- res.json({
- status: 0,
- msg: '删除成功',
- result: ''
- })
- }
- }
- })
- })
复制代码
8. 修改购物车商品数据(mongoose 修改数据用法)
- router.post('/cartEdit', (req, res, next) => {
- const userId = req.cookies.userId,
- productId = req.body.productId,
- productNum = req.body.productNum,
- checked = req.body.checked
- user.update({
- userId: userId,
- 'cartList.productId': productId
- }, {
- 'cartList.$.productNum': productNum,
- 'cartList.$.checked': checked
- }, (err, doc) => {
- if (err) {
- res.json({
- status: -1,
- msg: err.message
- })
- } else {
- if (doc) {
- res.json({
- status: 0,
- msg: '操作成功',
- result: ''
- })
- }
- }
- })
- })
- // 还可以使用 findOne()+save()的方式来修改数据
复制代码
mongodb 数据库
安装 mongodb 数据库 安装教程 https://www.imooc.com/article/18438
安装完成后启动 mongodb(安装在腾讯云服务器了)
mongod -f /root/mongodb/etc/mongodb.conf 使用配置文件启动
复制代码
此处有坑: 如果需要 mongodb 常驻进程需要设置 fork=true, 否则在断开服务器连接后, 数据库会关闭 3. 另起终端窗口, 可以进行 mongodb 操作
mongo 进入 mongodb 操作模式
show dbs 查看数据库
use demo 选择数据库(没有的话创建)
db.dropDatabase() 删除数据库
show collections 查看集合
db.demo.drop() 删除集合
插入文档
db.createCollection('demo') 创建集合
db.demo.insert({id:123,name:'conan'}) 创建并插入集合
更新文档
db.demo.update({id:'123',{$set:{name:'kids'}}})
db.demo.update({id:'123',{$set:{'class.name':'jd'}}}) 更新子集字段
删除文档
db.demo.remove({id:123})
查询文档
db.demo.find() 查看集合
db.demo.find().pretty() 查看集合(格式化形式显示)
db.demo.findOne() 查看第一条集合的数据
db.demo.find({id:123}) 按条件查询 (findOne() 同样用法)
db.demo.findOne({age:{$gt:20}) 大于 20($lt=>小于,$eq=>等于,$gte=>大于等于,$lte=>小于等于)
复制代码
来源: https://juejin.im/post/5b457b605188251a90186ef4