nextjs项目实践——前端与数据库直接交互①

919 阅读2分钟

作为一个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
一个简单的页面,可以直接增删改查数据库的数据

image.png

以上就是nextjs中直接操作数据库的一些实践,如果有错误的地方欢迎指正。
继续研究其他玩法,希望这个系列还有后续