代码对应地址
node服务端代码
前端vue3 typescript代码地址
最近在使用vue3
和typesript
写一个后台系统的demo。对于一些登录及内容数据不想单纯的使用假数据模拟,所以从零搭建一个nodejs的后端内容
首先进行下一栏安装
代码语言:txt复制npm i koa koa-router koa-bodyparser nodemon
项目的目录结构
代码语言:txt复制project
│ README.md
│ .env
│ package.json
└───src
│ └───app // 服务端代码实现
│ │ │ index.ts // 引入koa及相关内容,导出
│ │ │ config.ts // 导出.env中的环境变量
│ │ │ database.ts // 连接数据库
│ │ │
│ └───controller // 对应的业务处理层
│ └───middleware // 中间件
│ └───router // 匹配 路由
│ └───service // SQL相关操作
│ └───type
│ │ main.ts // 服务端启动文件
│
└───node_modules
│ ...
前置条件
首先需要在本地安装mysql
mysql安装地址
安装后需要进行mysql初始化 这里会提示你登录密码,需要保存登录密码先登入数据库。登入后再修改密码
代码语言:txt复制mysqld --initialize
执行成功后会生成data文件夹,就是初始化的内容。
如果提示报错,mysql命令不可用,可以在安装的mysql文件夹下的bin中吊起终端执行。所有的mysql都要替换成./mysql
./mysqld --initialize
启动 MySQL
代码语言:txt复制systemctl start mysqld
查看 MySQL 运行状态
代码语言:txt复制systemctl status mysqld
需要给mysql设置密码,在项目中连接时需要配置的密码(我忘记我是不是这么配置的了)
代码语言:txt复制mysqladmin -u root password "new_password";
执行 输入设置好的密码就可以使用了
代码语言:txt复制./mysql -u root -p
Enter password:*******
项目中安装mysql
代码语言:txt复制npm i mysql2
在database中使用并连接,下面有对应代码
页面代码
安装了nodemon package.json
中可以使用nodemon启动项目
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "cross-env NODE_ENV=development nodemon ./src/main.ts"
},
main.js
代码语言:txt复制const app = require('./app')
const config = require('./app/config') // config中读取了.env中配置的环境变量
app.listen(config.port, () => {
console.log('8001 OK')
})
app/database.ts
连接mysql数据库 可以根据mysql创建本地数据库连接
代码语言:txt复制const mysql = require('mysql2')
const config = require('./config')
const connections = mysql.createPool({
host: config.sql_host,
user: config.user,
port: config.sql_port,
password: config.password,
database: config.database
})
connections.getConnection((err: any, conn: any) => {
conn.connect((err: any) => {
if (err) {
console.log('sql error')
} else {
console.log('sql OK')
}
})
})
module.exports = connections.promise()
app/index.ts
代码语言:txt复制const koa = require('koa')
//解析请求参数的
const bodyParser = require('koa-bodyparser')
const routers = require('../router/index') //整合所有的页面统一返回路由
const errorHandler = require('./error-handle') //处理错误函数
const app = new koa()
app.on('error', errorHandler)
app.use(bodyParser()) //解析请求参数的
// 调用router.routes()来组装匹配好的路由,返回一个合并好的中间件
Object.keys(routers).map(item => {
app.use(routers[item].routes())
app.use(
routers[item].allowedMethods({
// throw: true, // 抛出错误,代替设置响应头状态
// notImplemented: () => '不支持当前请求所需要的功能',
// methodNotAllowed: () => '不支持的请求方式'
})
)
})
// 调用router.allowedMethods()获得一个中间件
// 当发送了不符合的请求时,会返回 `405 Method Not Allowed` 或 `501 Not Implemented`
module.exports = app
router/user.ts
代码语言:txt复制const Router = require('koa-router')
//controller中定义了对应接口的处理方法
const { login, create, getUserInfo, userLogout } = require('../controller/user')
//接口参数验证自定义中间件
const { verifyUser, verifyLogin, verifyToken } = require('../middleware/user')
const userRouter = new Router({ prefix: '/api' })
userRouter.post('/create', verifyUser, create)
userRouter.post('/login', verifyLogin, login)
userRouter.post('/logout', userLogout)
userRouter.get('/userInfo', verifyToken, getUserInfo)
module.exports = userRouter
controller/user
代码语言:txt复制const service = require('../service/user')
var jwt = require('jsonwebtoken')
import { UserRes } from '../type/user'
import { CommonRes } from '../type/common'
class UserController {
// 登录
async login(ctx: any) {
// 获取用户请求参数
const user = ctx.request.body
let token = jwt.sign(user, 'shhhhh', {
expiresIn: 60 * 60 * 24
})
const result: CommonRes = {
code: 200,
message: '登录成功!',
token: token
}
// 返回数据
ctx.body = result
}
// 登出
async userLogout(ctx: any) {
const result: CommonRes = {
code: 200,
message: '登出成功'
}
// 返回数据
ctx.body = result
}
// 创建账户
async create(ctx: any) {
// 获取用户请求参数
const user = ctx.request.body
// 查数据库
const result: CommonRes = await service.create(user) //数据库操作创建账号
// 返回数据
ctx.body = result
}
}
module.exports = new UserController()
service/user
代码语言:txt复制// 只做数据库处理操作
const connection = require('../app/database')
import { UserReq } from '../type/user'
import { CommonRes } from '../type/common'
class UserService {
async create(user: UserReq) {
const { username, password } = user
const statement = `INSERT INTO users (name, password) VALUES (?, ?);`
const createUsersTable = `CREATE TABLE IF NOT EXISTS users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL UNIQUE,
password VARCHAR(50) NOT NULL,
createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`
try {
const createResq = await connection.query(createUsersTable)
} catch (error) {
console.log(error)
}
const result = await connection.execute(statement, [username, password])
const res: CommonRes = {
code: 200,
message: '创建成功'
}
// 将user 存储到数据库
return res
}
//查询用户是否存在
async getUserByName(name: string) {
const statement = `SELECT * FROM users WHERE name = ?;`
const result = await connection.execute(statement, [name])
return result
}
}
module.exports = new UserService()