前端小白写的Vue+Koa2+Mysql移动商城

栏目: Node.js · 发布时间: 5年前

内容简介:大家好!本人前端新手,最近费劲脑汁撸了个vue移动端商城,请大佬们帮忙点评一下。目前实现的功能有:Github地址是:

大家好!本人前端新手,最近费劲脑汁撸了个vue移动端商城,请大佬们帮忙点评一下。

目前实现的功能有: 注册登录、购物车、搜索、收货地址 预览地址 (⊙▽⊙)

Github地址是: github.com/lyfan13/Vue…

若觉得还可以的话希望给个star呀,谢谢大佬们 ~(~ ̄▽ ̄)~

如果只运行前端vue的话在vue里npm run serve就可以直接用了,连的是我的云服务器。

但还想运行koa后台的话,需要自己搭建个mysql(>5.5),然后把backup.sql导入到数据库,再修改下koa /config/db.js的 mysql 地址,还有前端vue的axios请求,就可以了。

效果图:

前端小白写的Vue+Koa2+Mysql移动商城

1.前端Vue

主要技术栈

[vue、vue-router、axios、vuex、vuex-persistedstate(vuex状态持久化)、vant(ui)]

一些细节就不展开来说了,掘金上都有。

我发现用vuex-persistedstate来做vuex的状态持久化是真的好用,终于不用整天写storage.set/getItem了

主要文件目录树

基本上是一个页面对应一个组件

│ vue.config.js

├─ public

│ │ index.html

│ └─assets(图片)

├─ src

│ │ App.vue

│ │ main.js

│ │ router.js

│ │ store.js

├─ components(公共组件)

│ │ BottomBar.vue

│ │ NavBar.vue

├─ views

│ │ Address.vue

│ │ Buy.vue

│ │ Cart.vue

│ │ Detail.vue

│ │ Home.vue

│ │ Login.vue

│ │ Member.vue

│ │ Search.vue

│ │ Submit.vue

一些细节:

判断是否登录的全局前置导航守卫:

//main.js
router.beforeEach((to, from, next) => {
  if ((to.name == "member" || to.name == "submit" || to.name == "address") && !store.state.loginStatus.token) {
    Toast.fail('请先登录')
    next({ name: 'login' })
  } else if (to.name == "login" && store.state.loginStatus.token) {
    Toast.success('已经登录!')
    next({ name: 'home' })
  } else { next() }
})
复制代码

vuex-persistedstate 状态持久化插件

//store.js
export default new Vuex.Store({
  plugins: [createPersistedState({
    storage: window.localStorage,
    key: 'sundayvuex'
  })],
  state...})
复制代码

2.后端Koa2

主要中间件

[koa-cors、koa-router、mysql、sequelize(管理数据库)]

主要文件目录树

schema定义数据结构,module定义方法,controller定义返回内容

数据库的连接/config/db.js

const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const sequelize = new Sequelize('test', 'vueshop', '123456', {
  host: 'localhost',
  dialect: 'mysql',
  port:3306,
  //搜索功能的like
  operatorsAliases: { $like: Op.like },
  ...
});

复制代码

│ app.js

├─ bin

│ │ www

├─ config

│ │ db.js

├─ routes

│ │ index.js

│ │ users.js

├─ controllers

│ │ address.js

│ │ allitem.js

│ │ detaillist.js

│ │ homeitem.js

│ │ navlist.js

│ │ seckill.js

│ │ swiper.js

│ │ user.js

├─ modules

│ │ address.js

│ │ allitem.js

│ │ detaillist.js

│ │ homeitem.js

│ │ navlist.js

│ │ seckill.js

│ │ swiper.js

│ │ user.js

├─ schema

│ │ address.js

│ │ allitem.js

│ │ detaillist.js

│ │ homeitem.js

│ │ navlist.js

│ │ seckill.js

│ │ swiper.js

│ │ user.js

用户的注册登录:

//schema/user.js定义数据结构
module.exports = function (sequelize, DataTypes) {
  return sequelize.define('user', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
      autoIncrement: true
    },
    user: {
      type: DataTypes.STRING,
      allowNull: false,
      field: 'user',
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
      field: 'password'
    },
    token: {
      type: DataTypes.STRING,
      allowNull: false,
      field: 'token'
    },
  })
}
复制代码
//modules/user.js定义方法
...
class UserModel {
  //创建用户
  static async createUser (data) {
    let result = await User.findOne({
      where:{
        user:data.user
      }
    })
    if(!result){
      await User.create({
        user: data.user,
        password: data.password, 
        token: data.token, 
      })
      return true 
    }else{
      return false
    }
  }
  //获取用户信息
  static async getUser (req) {
    return await User.findOne({
      where:{
        user:req.user,
        password:req.password
      }
    })
  }
}
复制代码
//controller/user.js定义返回内容
...
class UserController {
  //注册
  static async signin (ctx) {
    // 接收客服端
    let req = {
      user: ctx.request.body.user,
      password: sha1(ctx.request.body.password),
      token: jwt.sign({ hello: ctx.request.body.user }, 'cheisy', { expiresIn: 24 * 60 * 60 * 1 })
    };
    if (req.user && req.password ) {
      let created = await UserModel.createUser(req)
      if (created) {
        ctx.response.status = 200;
        ctx.body = {code: 200,msg: '创建User成功',created}
      } else {
        ctx.response.status = 412;
        ctx.body = {code: 412,msg: '创建user失败',created}
      }
    } else {
      ctx.response.status = 416;
      ctx.body = {msg: '参数不齐全',}
    }
  }
  // 登录
  static async login (ctx) {
    let req = {
      user: ctx.request.body.user,
      password: sha1(ctx.request.body.password)};
    try {
      let data = await UserModel.getUser(req);
      if (data) {
        ctx.response.status = 200;
        data.password = '*****'
        ctx.body = {code: 200,msg: '登录成功',data}
      } else {
        ctx.response.status = 300;
        ctx.body = {code: 300, msg: '用户名或密码错误'}
      }
    } catch (err) {
      ctx.response.status = 412;
      ctx.body = {code: 412,msg: '查询失败',data}
    }
  }
}
module.exports = UserController
复制代码

路由

//routes/index.js注册登录的路由
const UserController = require('../controllers/user')
router.post('/signin',UserController.signin)
router.post('/login',UserController.login)
复制代码

Koa运行成功图:

前端小白写的Vue+Koa2+Mysql移动商城

2.结语

第一次写Markdown,好难啊 (+﹏+)~~

另本人最近在找工作,个人资料是

let profile = {sex:'boy',age:'24',city:'广州',area:'黄浦区'}
复制代码

大佬们/朋友们可以联系我wx一起'吹吹风' 备注:掘金

O(∩_∩)O哈哈~

前端小白写的Vue+Koa2+Mysql移动商城

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Growth Hacker Marketing

Growth Hacker Marketing

Ryan Holiday / Portfolio / 2013-9-3 / USD 10.31

Dropbox, Facebook, AirBnb, Twitter. A new generation of multibillion dollar brands built without spending a dime on “traditional marketing.” No press releases, no PR firms, and no billboards in Times ......一起来看看 《Growth Hacker Marketing》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具