nextjs项目中,使用postgres的完整案例

目的

通过此案例,可以简单快速的过一下数据库的操作,熟悉app-router这种模式下,client component和server component的两种组件中基本的接口使用。

技术栈

  • nextjs@14.2.* app-router
  • @vercel/postgres@0.10.*
  • typescript@5

重要事情说三遍1

  • app-router!!! 下面所有的代码和目录结构,脱离不开这个模式
  • app-router!!! 下面所有的代码和目录结构,脱离不开这个模式
  • app-router!!! 下面所有的代码和目录结构,脱离不开这个模式

创建表

初始化操作,可以看 最新nextjs中使用postgresSQL 这里

sql语句:CREATE TABLE article (content TEXT);

创建一个存放文章内容的表,字段为content 并且类型为TEXT. 详细的数据类型可以看这里

字符类型描述
character varying(n), varchar(n)变长,有长度限制
character(n), char(n)定长,不足补空白
text变长,无长度限制

创建文章数据(服务端)

sql语句:INSERT INTO article VALUES (${body.content});

接口文件:src/api/add-acticle/route.ts

import { sql } from '@vercel/postgres';
import { NextResponse } from 'next/server';export async function GET() {const { rows } = await sql`SELECT * FROM article`;return Response.json({ rows })
}export async function POST(request: Request) {const body = await request.json();await sql`INSERT INTO article VALUES (${body.likes});`;return NextResponse.json({ status: 200 });
}

创建文章数据(客户端)

目录:src/app/components/create-comp/index.tsx
涉及到react hook使用的组件,必须是use client

  • 以下出现的gyp-gao-ui组件库已发布到npm,如果只是想demo下,自行npm i -S gyp-gao-ui即可,使用中出现问题,可以看 nextjs中集成富文本编辑器wangEditor
  • 或者就是换成随便一个输入框
  • getHostStatic 方法的代码
    在这里插入图片描述
"use client";
import { RichText } from "gyp-gao-ui"; 
import { useState } from "react";
import { getHostStatic } from '../../../utils/static-index';export default function CreateText() {const [data, setData] = useState('');const handleInsert = async () => {const res = await fetch(`${getHostStatic()}/api/add-acticle`,{method: "post",body: JSON.stringify({content: data,}),});// 这里res可以自己在服务端那边组装成想要的格式哦// 然后前端这边就自行根据不同的结果做一些正常/异常处理};const handleChange = (value: string) => {setData(value);}return (<div><RichText onChange={handleChange} /><div className="btn" onClick={handleInsert}>保存数据</div></div>);
}

目录:src/app/create/page.tsx
主创建页面,服务端渲染的

import dynamic from 'next/dynamic'
import { Metadata } from 'next';
import './a.scss'; // 天然支持的scss/sassconst RichText = dynamic(() => import("../components/create-comp"), {ssr: false,
});export const metadata: Metadata = {title: '创建数据',
}export default async function CreateText() {return (<div className='a'><RichText /></div>);
}

查询展示文章数据 (客户端)

服务端数据生成和渲染

  • getHost 方法代码如下,切记该代码的运行环境不能是use client
    目录:src/utils/index.ts

服务端怎么知道当前项目的域名,通过headers上面的字段查询,官方文档

import { headers } from 'next/headers';const logPrefix = '[blog-render]:--> '
/** 获取当前域名 */
export const getHost = () => {const headersList = headers();// https://developer.mozilla.org/docs/Web/API/Headers/get// https://nextjs.org/docs/app/api-reference/functions/headersconst host = headersList.get('host');const xForwardedHost = headersList.get('x-forwarded-host');const referer = headersList.get('referer');const protocol = headersList.get('x-forwarded-proto');console.info(logPrefix + 'url:===', host, referer, protocol)// 获取协议const realProtocol = referer?.split('://')[0] || protocol;const realHost = host || xForwardedHost;console.info(logPrefix + 'realUrl:==', realProtocol, realHost)const url = `${realProtocol}://${realHost}`;return url;
}

目录:src/app/components/pre-comp/index.tsx

"use client";
import { RichTextRender } from "gyp-gao-ui";export default function Preview({ content }: {content: string}) {return (<div style={{marginBottom: '30px'}}><RichTextRender content={content} /></div>);
}

目录:src/app/preview/pages.tsx

import { Metadata } from 'next';
import dynamic from 'next/dynamic';
import { getHost } from '../../utils';export const metadata: Metadata = {title: '欢迎预览',}const RichTextReader = dynamic(() => import("../components/pre-comp"), {ssr: false,
});export default async function Preview() {const url = getHost();const data = await fetch(`${url}/api`);const { rows } = await data.json();return (<div>{rows.map((o: { content: string }, i: number) => <RichTextReader key={i} content={o.content} />)}</div>)
}

效果如下

列表数据展示如下,当然demo就不写那么美观的css了!
在这里插入图片描述

写在最后

找到正确的打开入口,学习就会事半功倍,觉醒吧前端同志。记得给博主点个赞,制作不易,感谢大家捧场!!!


  1. 还是希望大家,可以多多评论区讨论 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/448770.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-app写的微信小程序如何体积太大如何处理

方法一&#xff1a;对主包进行分包处理&#xff0c;将使用url: /pages/components/equipment/equipment跳转页面的全部拆分为分包&#xff0c;如url: /pagesS/components/equipment/equipment 在pages.json中添加 "subPackages": [{ "root"…

antd样式修改

1.Tab添加竖线 .ant-tabs .ant-tabs-tab {&::before {position: absolute;top: 50%;inset-inline-end: 0;width: 1px;height: 24px;background-color: #e1e1e1;transform: translateY(-50%);transition: background-color 0.2s;content: "";}} 像这样&#xff…

基于SSM的药品商城系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

科研绘图系列:R语言柱状图(histogram)

文章目录 介绍加载R包数据画图系统信息介绍 柱状图(Bar Chart),也称为条形图(Bar Graph),是一种常用的统计图表,用于展示不同类别的数据量。它由一系列垂直或水平的条形组成,每个条形的长度或高度代表相应类别的数值大小。 加载R包 library(tidyverse)# 显示中文 li…

增量知识 (Incremental Knowledge, IK)

在语义通信系统中&#xff0c;增量知识&#xff08;IK, Incremental Knowledge&#xff09;是一种增强数据传输效率和可靠性的技术&#xff0c;特别是用于混合自动重传请求&#xff08;HARQ, Hybrid Automatic Repeat reQuest&#xff09;机制时。它的核心思想是在传输失败后&a…

Android 15 推出新安全功能以保护敏感数据

Android 15 带来了增强的安全功能&#xff0c;可保护您的敏感健康、财务和个人数据免遭盗窃和欺诈。 它还为大屏幕设备带来了生产力改进&#xff0c;并对相机、消息和密钥等应用进行了更新。 Android 防盗保护 Google 开发并严格测试了一套全面的功能&#xff0c;以在盗窃之…

Stable Diffusion Web UI 大白话术语解释 (二)

归纳整理&#xff0c;Stable Diffusion Web UI 使用过程中&#xff0c;相关术语 ControlNet ControlNet 说简单点&#xff0c;就是你可以给 AI 一些“规则”&#xff0c;比如让它根据某些线条、结构或者骨架去画图。 这样能让 AI 画出更符合你要求的图片&#xff0c;特别适合画…

将爱传递 将“服务好”延伸

从泰康客户,转身成为泰康人,她直言是因为亲身感受了泰康“服务好”的魅力。 入司已8年的泰康养老浙江分公司HWP何英英,是泰康“服务好”的受益者。她从朋友的理赔中见证了泰康服务好的温度与力量,又被泰康养老的职域模式所吸引选择加入泰康。如今,她全身心投入在服务的第一线,…

PMP–知识卡片--项目生命周期与资源投入

预测型生命周期对变更并不友好&#xff0c;尤其是项目后期&#xff0c;变更代价太大&#xff0c;几乎让人无法接受。正如果所示&#xff0c;累计投入线代表项目累计的成本&#xff0c;也代表变更的代价。变更提出得越晚&#xff0c;代价越大。

实时语音转文字(基于NAudio+Whisper+VOSP+Websocket)

今天花了大半天时间研究一个实时语音转文字的程序&#xff0c;目的还包括能够唤醒服务&#xff0c;并把命令提供给第三方。 由于这方面的材料已经很多&#xff0c;我就只把过程中遇到的和解决方案简单说下。源代码开源在AudioWhisper: 实时语音转文字(基于NAudioWhisperVOSPWe…

1.几何算法-凸包

1.凸包的例子 1.1.简单求解 当着手设计一个计算凸包的算法时&#xff0c;此前所给出的凸包定义对我们没有多少帮助。按照定义&#xff0c;需要计算出“包含 P 的所有凸集的交”&#xff0c;可是这种集合有无限多个。而我们所观察到的“CH是一个凸多边形”这一事实&#xff0c…

libaom 源码分析:aomdec.c 文件

aomdec.c 功能:libaom 项目完成视频解码过程的 demo文件位置:libaom/apps/aomdec.c函数关系 命令行说明 终端输入 ./aomdec --help,输出如下,展示如何使用方法。Usage: ./aomdec <options> filenameOptions:--help Show usage options and exit…

pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

Qt_软件添加版本信息

文章内容: 给生成的软件添加软件的版权等信息 #include <windows.h> //中文的话增加下面这一行 #pragma code_page(65001)VS_VERSION_INFO VERSIONINFO

基于Arduino的简易收音机

DIY FM收音机&#xff1a;使用Arduino和Si4703模块打造 引言 在本项目中&#xff0c;我们将使用Arduino Nano和Si4703 FM调谐模块来构建一个功能完备的FM收音机接收器。这个易于跟随的指南非常适合想要深入无线电频率和无线通信世界的业余爱好者和电子爱好者。 Si4703模块是…

cuda编程模型

host和device&#xff1a; host&#xff1a;即CPU&#xff0c;CPU所关联的内存就叫host memorydevice&#xff1a;即GPU&#xff0c;GPU内的内存就叫device memory运行CUDA程序主要有三步&#xff1a;1&#xff09;host-to-device transfer&#xff1a;将数据从host memory拷到…

python基于大数据的电影市场预测分析

一、摘要 智慧是改变生活和生产的一种来源&#xff0c;那么智慧的体现更大程度上是对于软件技术的改变。当今社会&#xff0c;好的思路&#xff0c;好的创新方式往往是改变人们生活的一种来源。最常见最直接的形式就是各种软件的创始思路&#xff0c;京东因为非典的流行才能够…

【Java知识】java进阶-反射的原理以及实现

文章目录 反射的原理类对象继承图反射的使用注意事项 Java反射机制是Java语言的一个特性&#xff0c;它允许程序在运行时动态地加载、探查、使用编译期间完全未知的类。反射机制使得Java程序可以处理一些在编译时并不确定的类&#xff0c;增加了程序的灵活性。 反射的原理 类的…

如何提高LabVIEW编程效率

提高LabVIEW编程效率对开发者来说非常重要&#xff0c;尤其是在处理复杂项目或紧迫的开发周期时。以下是一些可以显著提升LabVIEW编程效率的技巧&#xff0c;从代码结构、工具使用到团队协作的多个角度进行详细分析&#xff1a; 1. 模块化设计 模块化设计 是提高代码可维护性和…

pdf怎么删除多余不想要的页面?删除pdf多余页面的多个方法

pdf怎么删除多余不想要的页面&#xff1f;在日常办公或学习中&#xff0c;我们经常会遇到需要处理PDF文件的情况。PDF文件因其格式稳定、不易被篡改的特点而广受青睐&#xff0c;但在编辑方面却相对不如Word等文档灵活。有时&#xff0c;在接收或创建的PDF文件中&#xff0c;可…