作为一个react技术栈的使用者,最近了解到了nextjs,感觉可能是前端的一个发展方向,但是看官方文档学习也不知道自己有没有理解清楚,所以打算写个文字记录下,也请看过的人如果发现我的错误希望能指正,以上算是开始。
项目搭建
这一步应该不用细说,用官方的脚手架执行就可以。我本地搭了个练手项目。
github地址:liutao5/ande (github.com)
与数据库交互
要说看了官方文档后最感兴趣的nextjs特点,就是服务端渲染了。于是有个一直以来的想法就想实践下,在服务端直接操作数据库,那是不是就可以不需要后端服务,一个前端项目就可以做到与数据库的交互了?
看了下官方的demo用的是prisma来与数据库交互,先照着试一下。
①安装prisma相关库。
npm i prisma @prisma/client
②新建prisma文件,记得安装vscode的prisma插件
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model user {
id Int @id @default(autoincrement())
name String @unique
pass_word String
create_time DateTime @default(now())
}
当然首先要配置好mysql数据库和对应的表,这里就不细说
③新建表的schema文件,这里是user表。另外添加相关curd的方法,这个在nextjs里叫[server actions](Data Fetching: Server Actions and Mutations | Next.js (nextjs.org))
"use server";
import prisma from "..";
export type User = {
id: number;
name: string;
pass_word: string;
create_time: Date;
};
export async function queryUser(): Promise<User[]> {
const res = await prisma.user.findMany();
return res;
}
export async function addUser(name: string, passWord: string) {
const res = await prisma.user.create({
data: {
name: name,
pass_word: passWord,
},
});
return res;
}
export async function deleteUser(id: number) {
const res = await prisma.user.delete({ where: { id } });
return res;
}
④然后new一个prisma实例供页面调用
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default prisma;
⑤最后就可以在直接在页面里调curd的方法了
"use client";
import { User, addUser, deleteUser, queryUser } from "@/prisma/schema/user";
import {
Button,
Container,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Stack,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
TextField,
} from "@mui/material";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
export default function Page() {
const [userList, setUserList] = useState<User[]>([]);
const [open, setOpen] = useState(false);
useEffect(() => {
query();
}, []);
const query = () => {
queryUser().then((res) => {
console.log(res);
setUserList(res);
});
};
const openDialog = () => {
setOpen(true);
};
const closeDialog = () => {
setOpen(false);
};
const handleAddUser = (username: string, password: string) => {
addUser(username, password)
.then((res) => {
closeDialog();
query();
})
.catch((err) => console.log(err));
};
const handleDeleteUser = (id: number) => {
deleteUser(id).then((res) => {
query();
});
};
return (
<Container>
<Button variant="contained" onClick={openDialog}>
add user
</Button>
<Table>
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Name</TableCell>
<TableCell>Password</TableCell>
<TableCell>CreateTime</TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{userList.map((user) => (
<TableRow key={user.id}>
<TableCell>{user.id}</TableCell>
<TableCell>{user.name}</TableCell>
<TableCell>{user.pass_word}</TableCell>
<TableCell>{user.create_time.toLocaleString()}</TableCell>
<TableCell>
<Button onClick={() => handleDeleteUser(user.id)}>
delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<UserForm
open={open}
handleClose={closeDialog}
handleAddUser={handleAddUser}
/>
</Container>
);
}
type UserFormProps = {
handleClose: VoidFunction;
handleAddUser: (username: string, password: string) => void;
open: boolean;
};
const UserForm = (props: UserFormProps) => {
const { open, handleClose, handleAddUser } = props;
const { register, handleSubmit, reset } = useForm();
const onSubmit = (data: any) => {
console.log(data);
const { username, password } = data;
handleAddUser(username, password);
reset();
};
return (
<Dialog open={open} onClose={handleClose} fullWidth>
<form onSubmit={handleSubmit(onSubmit)}>
<DialogTitle>Add User</DialogTitle>
<DialogContent>
<Stack spacing={2}>
<TextField
label="name"
size="small"
{...register("username", { required: true })}
/>
<TextField
label="password"
size="small"
{...register("password", { required: true })}
/>
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>close</Button>
<Button type="submit" variant="contained">
ok
</Button>
</DialogActions>
</form>
</Dialog>
);
};
在线demo
一个简单的页面,可以直接增删改查数据库的数据
以上就是nextjs中直接操作数据库的一些实践,如果有错误的地方欢迎指正。
继续研究其他玩法,希望这个系列还有后续