「项目」开发一个导航网站
- 作者
- Name
- 青玉白露
- Github
- @white0dew
- Modified on
- Reading time
- 5 分钟
阅读:.. 评论:..
背景
在工作学习中,发现一个问题,那就是有一个导航网站非常重要!
无意之中,看到一个很棒的导航网站,打算基于此开发一个,记录一下开发的过程。
Demo仓库:https://github.com/wangfengyuan/frontend-nav
记录
tailwindcss的scrollbar
https://adoxography.github.io/tailwind-scrollbar/examples
prisma的env没有读取到dababase_url
参考这个帖子:
两种解法:
1、安装dotenv
2、直接env.local改名为env
登陆怎么做?
bcrypt-ts到底怎么用?
!!!注意!不能够把加盐的函数直接去比较,因为每次生产的都是不一样的!
- 如果是Github模式
0、参考https://authjs.dev/getting-started/authentication/oauth
1、先在github申请appid和secret,填写url链接
2、而后在nextjs的env中写上
- 如果是账号密码模式
https://authjs.dev/getting-started/authentication/credentials
必须这样!!!官方文档是错的!!
from的action类型错误?
不用管···
https://www.reddit.com/r/nextjs/comments/1616bh9/form_action_not_working/
https://github.com/vercel/next.js/discussions/56581
client和server的调用方式不一样··
客户端的组件又报错了CSRF···
发现是环境变量错了,直接注释掉就行:
shadcn/ui的Button没有loading,怎么办?
直接参考这个文章:https://blog.typeart.cc/add-loading-spinner-in-shadcn-ui-button/
+ import { Loader2 } from 'lucide-react'; // ... 略過前面 cva 部份 export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> { asChild?: boolean; + loading?: boolean; } // 將 loading 與 children 從 props 取出來 const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( + ({ className, variant, size, asChild = false, loading, children, ...props }, ref) => { const Comp = asChild ? Slot : 'button'; return ( <Comp className={cn(buttonVariants({ variant, size, className }))} + disabled={loading} ref={ref} {...props} > + {loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : children} </Comp> ); }, ); Button.displayName = 'Button';
怎么使用safe-server-action?
官方文档:https://next-safe-action.dev/
Zod应该怎么使用?比如声明了一个结构体,应该怎么赋值呢?
官方文档:https://zod.dev/?id=basic-usage
这样:
import { z } from "zod"; const User = z.object({ username: z.string(), }); User.parse({ username: "Ludwig" }); // extract the inferred type type User = z.infer<typeof User>; // { username: string }
怎么实现选择Emoji?
如上图,我需要在这个输入框,可以选择表情或者分组地址。
找到一个库,在这里:https://ealush.com/emoji-picker-react/
很好用,可以选择屏蔽某些不需要的Emoji,比如Flag····
当选择表情之后,会有一个callBack,输出的内容是当前的表情信息:
{ "activeSkinTone": "neutral", "emoji": "😆", "imageUrl": "https://cdn.jsdelivr.net/npm/emoji-datasource-apple/img/apple/64/1f606.png", "isCustom": false, "names": [ "laughing", "satisfied", "smiling face with open mouth and tightly-closed eyes" ], "unified": "1f606", "unifiedWithoutSkinTone": "1f606" }
发现一个问题useAction的操作是异步的!
// 调用Action进行更新 const AddCategoryAction = useAction(AddCategory) <Button type="submit" variant="default" loading={AddCategoryAction.isPending} onClick={async () => { await AddCategoryAction.execute(newCategory) mylog("AddCategoryAction res", AddCategoryAction.result) if (AddCategoryAction.hasErrored) { mylog( "AddCategory Err", AddCategoryAction.result.validationErrors ) toast( JSON.stringify(AddCategoryAction.result.validationErrors) ?? "分类添加失败,请重试" ) } else { toast("分类添加成功") // window.location.reload() } }} > 保存 </Button>
由于是hook来的,在onclick函数里是异步的,造成数据不一致,怎么办啊!
两种方法:
1、换成使用const res = await AddCategoryAction.executeAsync(newCategory)
2、使用useEffect来监听
useEffect(() => { if (!AddCategoryAction.isPending) { if (AddCategoryAction.hasErrored) { toast( JSON.stringify(AddCategoryAction.result.validationErrors) ?? "分类添加失败,请重试" ) } else { toast("分类添加成功") // 你可以在这里执行其他操作,比如关闭对话框或重置表单 } } }, [ AddCategoryAction.isPending, AddCategoryAction.hasErrored, AddCategoryAction.result, ])
Icon可以选择的网站~
https://lucide.dev/guide/packages/lucide-react
如何从结构体中去除某个字段?-Omit
在 TypeScript 中没有严格意义上的“结构体”概念,但可以通过对象类型或接口来模拟。要从一个对象中去除某个字段,可以通过类型断言和对象解构的方式来实现。
假设你有一个类型如下:
interface MyType { field1: string; field2: number; field3: boolean; }
现在要去除 field2
字段,可以这样做:
const obj: MyType = { field1: 'some string', field2: 123, field3: true }; const { field2,...rest } = obj; const newObj = rest as Omit<MyType, 'field2'>; console.log(newObj);
这里使用了对象解构和类型断言来创建一个新的对象,不包含指定的字段。
或者可以使用 Omit
类型工具来创建一个新的类型,然后将原对象转换为新类型:
type NewType = Omit<MyType, 'field2'>; const newObj2: NewType = obj as NewType; console.log(newObj2);
遇到一个问题form的值没有更新啊!SetValue
有一个issue已经提到了:https://github.com/react-hook-form/react-hook-form/issues/456
其实关键在于SetValue不会导致form的组件重新更新。
如果想实现setValue之后,组件内容更新,需要useEffect进行组件re-render。
diaglog里的form数据没有被清空。
发现新建一个分类之后,再次点开新建,里面的内容还是上一次保存的数据,因此需要做一次清空。
TODO 图片尺寸不对···
源代码如下:
到底什么原因呢?
部署在vercel之后,一直报错Prisma is not defined
谷歌了半天,一直没找到问题出在哪··
发现是没有import····为什么编辑器没有提示啊?
shadcn/ui的Drawer组件在移动端有问题!
会导致移动端输入、下滑出现问题。
直接换成Sheet组件即可!