Nextjs学习教程

一.手动创建项目

建议看这个中文网站文档,这个里面的案例配置都是手动的,也可以往下看我这个博客一步步操作
1.在目录下执行下面命令,初始化package.json文件

npm init -y

2.安装react相关包以及next包

yarn add next react react-dom
// 或者
npm install --save next react react-dom

3.在package.json文件的script节点,新增以下内容

  "scripts": {...,"dev": "next",  // 开发时运行"build": "next build", // 打包时运行"start": "next start"  // 打完包启动服务的命令}

注意:Next.js 只支持React 16及以上

4.根目录下新建pages目录(这里面就是所有页面代码了,会根据这个目录的内容自动生成路由)

5.在pages里面新建index.js,放入以下内容进行测试

export default function(){return <div>我是pages/index下面的内容</div>
}

6.启动项目测试

npm run dev
// 或者
yarn run dev

7.访问控制台的local地址,显示出如下页面

在这里插入图片描述
8.打包

npm run build
// 或者
yarn run build

打完包会在项目下新建生成一个.next文件,在根目录下执行如下命令会和开发时看到的效果一致

npm run start
// 或者
yarn run start

二.快速创建项目

官网文档

执行下面创建项目的命令

npx create-next-app next-create

下面会出现一堆询问的配置信息,这里直接走默认就好了

定义路由

这里的页面都是统一放到app文件夹下面每个文件的page.js文件

例如直接访问localhost:3000则访问的是app/page.js文件

例如直接访问localhost:3000/user则访问的是app/user/page.js文件

export default function(){// className={"text-red-500"} 使用原子化css标签return <div className={"text-red-500"}>我是user/page文件</div>
}

如果访问的页面有很多网格效果,则去app/globals.css里面把样式都删除,只留前三行即可

页面与布局

将app/Layout.js进行改造

import { Inter } from "next/font/google";
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children }) {return (<html lang="en"><body className={inter.className}>app下面的layout{children}</body></html>);
}

新建app/user/Layout.js存入以下内容

export default function userLayout({ children }) {return (<section>user下面的layout{children}</section>);
}

访问localhost:3000

在这里插入图片描述
访问localhost:3000/user

在这里插入图片描述
通过对比可以发现,app下面的就是公共的根样式,下面每个Layout.js都会继承到,然后每个文件夹下都可以定义当前路由页面的样式

链接和导航

修改下app/page.js内容如下

'use client';
import Link from "next/link";
import { useRouter } from "next/navigation";export default function Home() {const router = useRouter()return (<><h1 className="text-4xl text-orange-600">Hello Name</h1><br></br><Link href={"/user"}>跳转到user路由</Link><br></br><button onClick={()=>{router.push('/user')}}>点击跳转/user</button></>);
}

滚动到新路由的指定位置处,相当于锚点链接

<Link href="/dashboard#settings">Settings</Link>// Output
<a href="/dashboard#settings">Settings</a>

路由组

项目下新建三个路径文件

  • app/(marketing)/about/page.js
  • app/(marketing)/bolg/page.js
  • app/(marketing)/(shop)/acconut/page.js

在每个page.js里面随便写点内容,访问以下路径

  • localhost:3000/about
  • localhost:3000/bolg
  • localhost:3000/account

可以发现都能被访问到,总结规律就是文件夹名字带括号的相当于可以忽略了

路由组不参与url的设定的

个人感觉唯一作用是用于设置共同的Layout.js

创建如下两个Layout.js文件

  • app/(marketing)/Layout.js
  • app/(marketing)/(shop)/Layout.js

在这两个里面添加如下代码

export default function userLayout({ children }) {return (<section>marketing下面的layout{children}</section>);
}
export default function userLayout({ children }) {return (<section>marketing下面shop的layout{children}</section>);
}

运行后会发现,marking的Layout,js被它里面所有文件所共用,shop里面的Layout.js被shop里面的文件所共用,因为这个案例shop在marking里面的,因此shop里面的文件也共用marking里面的样式,这就是路由组,按照上面传统的方式建路由,需要每个文件单独设置自己的Layout.js,使用路由组可以达到复用性

动态路由

在app/user新建[username]文件夹,里面的page.js文件内容如下

export default function({params}){console.log('params',params);return <><div>我是user/[username]动态路由{params.username}</div></>
}

将app/page.js内容修改如下

'use client';
import Link from "next/link";
import { useRouter } from "next/navigation";export default function Home() {const router = useRouter()return (<><h1 className="text-4xl text-orange-600">Hello Name</h1><br></br><Link href={"/user/王二"}>跳转到user路由</Link><br></br><button onClick={()=>{router.push('/user/王五')}}>点击跳转/user</button></>);
}

当点击跳转到路由时,后面的参数就是动态参数,文件名username就是参数名,可以被params.username接收到并显示到页面上

上面有个弊端就是只支持一级动态参数,如果希望多级的话可以将[username]文件名换成[…username]这样就是可以匹配到后面所有参数,如下地址

  • localhost:3000/user/1/2/3/4/5

效果图

在这里插入图片描述
但是这里建议将[…username]文件名替换为[[…username]],两者区别在于[[…username]]当动态参数为空时也会被匹配到,剩余部分两者功能一致

Loadding加载和流的处理

1.在app下面新建Loading.js组件

export default function(){return <div className={"text-2xl text-pink-400"}>Loading...</div>
}

2.修改app/Layout.js

import { Inter } from "next/font/google";
import { Suspense } from "react";
import Loading from './loading';  // 引入app/loading.js
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children }) {return (<html lang="en"><body className={inter.className}><Suspense fallback={<Loading></Loading>}> // 2.使用SusPense将页面包裹app下面的layout{children}</Suspense></body></html>);
}

子组件代码

这里使用了async/await模拟了一下异步,这是个细节,因为上面的loadding效果如果要出来的话,页面数据必须要是有异步效果,因为我没注意到这点,费了点时间才搞明白

export default async function Posts() {await new Promise((resolve) => setTimeout(resolve, 2000));return <div>1111</div>;
}

注意:将Lodding放到app/Layout.js里面包裹的话,则针对所有页面生效,如果某个页面有不一样的loading效果的话,则需要在当前文件夹里面的Layout.js去单独引入对应的Loading.js,可以在当前文件夹里面创建个Loading.js,这样的话Loading.js的样式仅仅作用于当前文件夹下的所有页面

import { Suspense } from "react";
export default function userLayout({ children }) {return (<section>// 这个loading效果仅作用于当前文件夹下面的所有页面<Suspense fallback={<div className={"text-2xl text-pink-400"}>Loading...</div>}>user下面的layout{children}</Suspense></section>);
}

注意:必须是渲染的页面内有异步操作(如async/await)才会有Loading.js效果

错误处理

新建app/error.js,放入以下内容

'use client'export default function({error,reset}){return (<div><h2>我是全局的错误样式处理</h2><button onClick={()=>reset()}>重试一下</button></div>)
}

也可以对每个页面单独定义路由样式,只需要在目标页面的文件夹内新建error.js,放入以下内容即可

例如我在app/user/error.js内加入以下内容

'use client'export default function({error,reset}){return (<div><h2>app/user 页面内有错误啦!!!</h2><button onClick={()=>reset()}>重试一下</button></div>)
}

例如我们在目标的user页面加入一些错误信息

export default function Posts() {console.log('a',a);  // 这里没有a变量,因此这里会报错return <div>1111</div>;
}

当我们在浏览器访问localhost:3000/user就会报出以下错误

在这里插入图片描述
当我们访问其他页面有错误信息时,但是没有给那个页面单独定义错误样式,则会触发全局的错误样式

例如访问: localhost:3000/about

在这里插入图片描述

组件化渲染

并行路线,也就是web端的组件

在app下面新建@home和@setting文件夹,里面都新建一个page.js文件,在里面写一点页面

在app/Layout.js里面改为如下页面代码

import { Inter } from "next/font/google";
import { Suspense } from "react";
import Loading from './loading';
import "./globals.css";const inter = Inter({ subsets: ["latin"] });export const metadata = {title: "Create Next App",  // 网站标题description: "Generated by create next app", // 描述信息
};export default function RootLayout({ children,home,setting }) {return (<html lang="en"><body className={inter.className}><Suspense fallback={<Loading></Loading>}>app下面的layout{home}{children}{setting}</Suspense></body></html>);
}

在这里插入图片描述

可以发现组件效果已经出来了

但是上面的仅限于在Layout.js里面使用的组件,下面是可以应用到我们页面里面的组件的案例

在app平级处创建components/frame/index.js,放入以下内容

import Image from "next/image";export default function({photo}){console.log('photo',photo);return <><Image src={photo.src} alt="" width={600} height={600} className={'w-full object-cover aspect-square col-span-2 w-28'}></Image></>
}

在app里面新建photo/page.js文件,插入以下内容

import Photo from "@/components/frame"  // 引入组件
export default function(){const photo = {src:'https://take-saas.oss-cn-hangzhou.aliyuncs.com/wechat_applets/coach/bgcimg/bgc-13.png'}// 给组件传值return <Photo photo={photo}></Photo>
}

注意:这里可能会报错图片问题(网络图片需要加一下白名单才能正常加载,如下在next.config.mjs里面进行配置)

/** @type {import('next').NextConfig} */
const nextConfig = {images:{domains:['take-saas.oss-cn-hangzhou.aliyuncs.com'] // 这里是存放域名白名单处}
};export default nextConfig;

然后就可以看到图片正常加载了

在这里插入图片描述

定义404页面

在app下面新建not-found.js,放入以下内容

export default function(){return <div className={"text-2xl text-pink-400"}>访问页面不存在...</div>
}

当页面访问一个不存在的页面路由时,页面显示效果如下

在这里插入图片描述
PS:由于博客内容都是自学做的整理,在某一次排查问题时,也就是刚好博客写到这里时,刷到了一个博主的nextjs教程合集,也挺详细的,力推点击进入合集地址

三.重新创建带src文件目录的项目

跟刚刚步骤一样,只是选择配置的时候选择使用src目录

路由

路由跳转和传参,在src/pages/home/index.js加入以下代码

import Link from "next/link";
import Router from "next/router";function Home({ items, time }) {return (<div className="Home"><Link href={'/home/xiaoji'}>跳转到xiaoji页面</Link><br></br><Link href={'home/xiaoji?name=萧寂'}>跳转到xiaoji页面(带参数)</Link><hr></hr><button onClick={()=>{Router.push('/home/xiaoji')}}>跳转到xiaoji页面</button><br></br><button onClick={()=>{Router.push('/home/xiaoji?name=萧寂')}}>跳转到xiaoji页面(第一种带参数)</button><button onClick={()=>{Router.push({pathname:'/home/xiaoji',query:{name:'萧寂'}})}}>跳转到xiaoji页面(第二种带参数)</button></div>);
}
export default Home;

接收参数,在src/pages/home/xiaoji.js加入以下代码

import { withRouter } from "next/router";function xiaoji({ router }) {return (<><div>{router.query.name}</div></>);
}// 需要withRouter包裹组件可以取到参数信息
export default withRouter(xiaoji)

路由里面的六个钩子事件

将上面的src/pages/home/index.js代码更改如下,然后查看浏览器控制台的打印语句

import Link from "next/link";
import Router from "next/router";function Home({ items, time }) {Router.events.on('routeChangeStart',(args)=>{console.log("1.routeChangeStart->路由开始变化,参数为:",args);})Router.events.on('beforeHistoryChange',(args)=>{console.log("2.beforeHistoryChange->浏览器的历史记录状态发生变化(常用于询问用户是否保存页面内容),参数为:",args);})Router.events.on('routeChangeComplete',(args)=>{console.log("3.routeChangeComplete->路由变化结束,参数为:",args);})Router.events.on('routeChangeError',()=>{console.log("4.routeChangeError->路由发生错误,404不算错误");})Router.events.on('hashChangeStart',(args)=>{console.log("5.hashChangeStart->hash值开始发生变化,参数为:",args);})Router.events.on('hashChangeComplete',(args)=>{console.log("6.hashChangeComplete->hash值变化完成,参数为:",args);})return (<div className="Home"><Link href={'/home/xiaoji'}>跳转到xiaoji页面</Link><br></br><Link href={'home/xiaoji?name=萧寂'}>跳转到xiaoji页面(带参数)</Link><hr></hr><button onClick={()=>{Router.push('/home/xiaoji')}}>跳转到xiaoji页面</button><br></br><button onClick={()=>{Router.push('/home/xiaoji?name=萧寂')}}>跳转到xiaoji页面(第一种带参数)</button><br></br><button onClick={()=>{Router.push({pathname:'/home/xiaoji',query:{name:'萧寂'}})}}>跳转到xiaoji页面(第二种带参数)</button><br></br><Link href={"#xiaoji"}>模拟hash值发生变化</Link></div>);
}
export default Home;

网络请求发送

getStaticProps 和 getServerSideProps

getStaticProps 和 getServerSideProps 是 Next.js 中用于数据获取的两个重要函数,它们在页面渲染时分别起到不同的作用。

1、getStaticProps:

用途:主要用于静态生成页面,即在构建时获取数据并将其预先注入到页面中。
执行环境:只在构建时运行,不会在每次请求时重新运行。
数据获取:可以在构建时从外部数据源获取数据,并将数据作为 props 传递给页面组件。
适用情况:适用于不频繁变化的静态内容,如博客文章、产品页面等。
2、getServerSideProps:

用途:用于服务器端渲染页面,即在每次请求时动态获取数据并注入到页面中。
执行环境:在每次请求时在服务器端运行,可以根据每次请求动态获取数据。
数据获取:可以在每次请求时从外部数据源获取数据,并将数据作为 props 传递给页面组件。
适用情况:适用于需要在每次请求时动态获取数据的情况,如用户特定数据、实时数据等。

总的来说,getStaticProps 用于静态生成页面,适用于不频繁变化的内容,而 getServerSideProps 用于服务器端渲染页面,适用于需要每次请求时动态获取数据的情况。根据页面的需求和数据更新频率,您可以选择合适的函数来获取数据并注入到页面中。

getStaticProps

在src/pages/home/index.js加入以下内容

function Home({ items, time }) {return (<div className="Home"><p>timer: {time}</p>{items.map((item) => {return (<h4 style={{ margin: "15px 0" }} key={item.qa_id}>{item.name}</h4>);})}</div>);
}export async function getStaticProps() {// 在这里调用外部接口,可以写各种服务端代码:连数据库,访问文件系统.....const resp = await fetch("https://fts.jd.com/area/get?fid=-1");const items = await resp.json();console.log('items',items);// 此函数必须返回 { props: { 需要携带的数据 } } 对象,Home 组件在构建时将接收到 `items` 参数。return {props: {items,time: Date.now(), // 为了方便对比yarn dev和yarn build的区别,加入时间戳},};
}export default Home;

浏览器访问:http://localhost:3000/home
效果图

在这里插入图片描述

getServerSideProps

把上面的代码替换成下面的,然后还是访问相同的路由地址

function Home({ items, time }) {return (<div className="Home"><p>timer: {time}</p>{items.map((item) => {return (<h4 style={{ margin: "15px 0" }} key={item.qa_id}>{item.name}</h4>);})}</div>);
}export async function getServerSideProps(context) {// 在这里调用外部接口,可以写各种服务端代码:连数据库,访问文件系统.....const resp = await fetch("https://fts.jd.com/area/get?fid=-1");const items = await resp.json();// 此函数必须返回 { props: { 需要携带的数据 } } 对象,Home 组件在构建时将接收到 `items` 参数。return {props: {items,time: Date.now(), // 为了方便对比yarn dev和yarn build的区别,加入时间戳},};
}export default Home;

这里会发现其实效果是一样的,但是我在props里面返回了个时间戳,我们先运行yarn run build先打包,然后运行yarn run start执行打包后的文件再访问上面的路由地址,观察页面上的时间戳变换,可以发现getStaticProps 方法打包出来的时间戳一直是固定了的,也就是这上面的数据只在初始化就渲染一次,后续不会执行,适合作为静态页面数据获取使用,而getServerSideProps方法打包出来的运行后,时间戳是一直变化的,也就是每次都会从服务器获取数据并渲染

pages页面路由动态获取

在src/pages/home/detial.js加入以下内容

function Detail({ id }) {// 获取文章详情信息数据渲染到组件中。return <div className="Detail">{id}</div>;}export default Detail;export async function getStaticPaths() {const paths = [{ params: { id: '1' } },{ params: { id: '2' } },];return { paths, fallback: false };}export async function getStaticProps({ params }) {const id = params.id;// 根据 id 从外部数据源获取数据return { props: { id } };}

浏览器访问:http://localhost:3000/home/detial/1
或者
http://localhost:3000/home/detial/2
都能进行访问,除此之外都是404,这样就是给动态参数加了限制,限制了哪些参数允许访问此页面,例如做文章详情之类的,需要传入文章id,如果id不匹配则返回404这种,可以根据后端数据内容动态渲染paths里面的id值,代码如下:

function Detail({ detailData }) {// 获取文章详情信息数据渲染到组件中。return <div className="Detail">{JSON.stringify(detailData)}</div>;
}export default Detail;export async function getStaticPaths() {// 调用api,获取文章列表const resp = await fetch("url");const items = await resp.json();// 遍历文章列表,获取文章id,根据文章id生成所有需要预渲染的静态页面路径const paths = items.map((item) => ({params: { id: `${item.qa_id}` }, // id的值必须是字符串类型,因为动态路径参数也是字符串类型,要保持一致}));// { fallback: false } 不在上述预渲染列表范围内的路径id,显示404页面。// 改为true就不会受到限制,默认为falsereturn { paths, fallback: false };
}export async function getStaticProps({ params }) {
// 根据id进行动态请求数据const resp = await fetch(`url/${params.id}`);const detailData = await resp.json();return {props: {detailData,},};
}

getStaticPaths 函数说明

  • 仅在构建时运行。它非常适合预渲染需要在构建时使用动态数据的类似路径(如/blog/:id)。当与 getStaticProps 结合使用时,它会从 数据库/接口 等数据结构中生成动态页面,然后 Next 可以对其进行静态服务
  • getStaticPaths 只能和 getStaticProps 配合使用,不能和 getServerSideProps 一起使用

如果fallback参数为true,则在构建时没有生成的路径不会导致404页面,可以先暂时为用户提供一个临时页面,同时 next 会去后台会运行 getStaticProps 函数,对构建时没有生成的路径页面进行动态预渲染。可以将上面的页面进行如下改造

import { useRouter } from "next/router";function Detail({ id }) {// 获取文章详情信息数据渲染到组件中。const router = useRouter();if (router.isFallback) {return <div>正在请求,请稍后...</div>; // 临时页面,给用户友好提示}return <div className="Detail">{id}</div>;}export default Detail;export async function getStaticPaths() {const paths = [{ params: { id: '1' } },{ params: { id: '2' } },];return { paths, fallback: true };}export async function getStaticProps({ params }) {const id = params.id;// 根据 id 从外部数据源获取数据return { props: { id } };}  

组件

在src下面新建components文件夹,新建demo.js文件

export default function ({children}){return <div>{children}</div>
}

在pages/home/xiaoji.js里面使用

import Demo from "@/components/demo";export default function (){return <Demo><button>我是萧寂</button></Demo>
}

效果图

在这里插入图片描述

项目结构如下
在这里插入图片描述

页面css编写

行内样式

function Home({ items, time }) {return (<><div>我是萧寂</div><div className="Home">我是萧寂</div><style jsx>{`div{color:blue;}.Home{color:red;}`}</style></>);
}export default Home;

效果图

在这里插入图片描述

外部样式

在src新建static文件夹再新建index.css文件,存入以下内容

div{color: blue;
}
.Home{color: red;
}
import '../../static/index.css'
function Home({ items, time }) {return (<><div>我是萧寂</div><div className="Home">我是萧寂</div></>);
}export default Home;

效果和上面相同

自定义页面的Header头,用于优化SEO

单个页面自定义(建议将Head单独封装成组件,在每个页面引入使用)

import { parseSetCookie } from "next/dist/compiled/@edge-runtime/cookies";
import Head from "next/head";
function Home({ items, time }) {return (<><Head><title>萧寂牛逼</title><meta charSet="utf-8"></meta></Head><div>我是萧寂</div></>);
}export default Home;

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

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

相关文章

opera打不开网页最简单的解决办法

如果以上为解决问题&#xff0c;继续下面操作 检查网络连接&#xff1a; 确认您的电脑已连接到互联网。 检查网络连接是否稳定&#xff0c;网络速度慢或链路拥堵可能会导致网页加载失败。 修改Local State文件&#xff1a; 关闭Opera浏览器。 定位到Opera浏览器的配置…

【NI国产替代】PCIe 高速采集卡, 8 位双通道数字化仪器,采集卡最高采样率高达 5 GS/s 模拟带宽高达 500 MHz

• 8 位双通道数字化仪器 • 最高采样率高达 5 GS/s • 模拟带宽高达 500 MHz • 采用 PCIe 3.0 x 8 接口 • 基于 Xilinx Kintex UltraScale, XCKU040 • 提供硬件、FPGA、软件定制服务 高速采集卡是一款 8 位双通道数字化仪器&#xff0c;采集卡最高采样率高达 5 GS/s 模…

客户案例|Zilliz Cloud 助力点石科技转型 AI 智能服务商

福建点石科技网络科技有限公司成立于2010年&#xff0c;是国家高新技术企业&#xff0c;阿里云、蚂蚁金服等大厂海内外生态合作伙伴ISV。在餐饮、零售、酒店、旅游、商圈的行业定制化服务化上有深厚积累&#xff0c;在境内外做了大量标杆性软件项目&#xff0c;如东南亚RWS圣淘…

如何将HTTP升级成HTTPS?既简单又免费的方法!

在当今数字化时代&#xff0c;网络安全已成为用户和企业关注的焦点。HTTPS作为一种更加安全的网络通信协议&#xff0c;正逐渐取代传统的HTTP成为新的标准。对于许多网站管理员和内容创作者来说&#xff0c;如何免费升级到HTTPS是一个值得探讨的问题。本文将详细介绍一些免费的…

【动态规划-BM79 打家劫舍(二)】

题目 BM79 打家劫舍(二) 描述 你是一个经验丰富的小偷&#xff0c;准备偷沿湖的一排房间&#xff0c;每个房间都存有一定的现金&#xff0c;为了防止被发现&#xff0c;你不能偷相邻的两家&#xff0c;即&#xff0c;如果偷了第一家&#xff0c;就不能再偷第二家&#xff0c;如…

数据结构之ArrayList与顺序表(下)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 ArrayList的具体使用 118. 杨辉三角 扑克洗牌算法 接上篇&#xff1a;数据结构之ArrayLis…

【数据结构】平衡二叉树(AVL树)

目录 前言 一、AVL树概念 二、AVL树节点定义 三、AVL树插入 1. 按照二叉搜索树的方式插入新节点 2. 维护节点的平衡因子与调整树的结构 a. 新节点插入较高左子树的左侧---左左&#xff1a;右单旋 b. 新节点插入较高右子树的右侧---右右&#xff1a;左单旋 c. 新节点插入…

SpeedyBee飞塔F405 V3 50A

遥控器常用的几种协议&#xff1a; 一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出 - 蔡子CaiZi - 博客园 (cnblogs.com) SpeedyBee飞塔的官方教程&#xff1a; FlowUs 息流 - 新一代生产力工具 为8位电调刷写固…

纷享销客安全体系:安全合规认证

安全合规认证是指组织通过独立的第三方机构对其信息系统和数据进行评估和审查&#xff0c;以确认其符合相关的安全标准、法律法规和行业要求的过程。 安全合规认证可以帮助组织提高信息系统和数据的安全性&#xff0c;并向客户、合作伙伴和监管机构证明其符合相关的安全标准和…

Ambari集成Apache Kyuubi实践

目前还有很多公司基于HDP来构建自己的大数据平台&#xff0c;随着Apache Kyuubi的持续热度&#xff0c;如何基于原有的HDP产品来集成Apache Kyuubi&#xff0c;很多人都迫切的需求。集成Apache Kyuubi到HDP中&#xff0c;主要涉及Ambari的二次开发。本文详细叙述了集成Apache K…

Duilib多标签选项卡拖拽效果:添加动画特效!

动画是小型界面库的“难题”、“通病” 几年前就有人分享了如何用direct UI制作多标签选项卡界面的方法。还有人出了一个简易的浏览器demo。但是他们的标签栏都没有Chrome浏览器那样的动画特效。 如何给界面添加布局是的动画特效呢&#xff1f; 动画使界面看起来高大上&#…

HQL面试题练习 —— 求连续段的最后一个数及每个连续段的个数

目录 1 题目2 建表语句3 题解 题目来源&#xff1a;拼多多。 1 题目 有一张表t_id记录了id&#xff0c;id不重复&#xff0c;但是会存在间断&#xff0c;求出连续段的最后一个数及每个连续段的个数。 ----- | id | ----- | 1 | | 2 | | 3 | | 5 | | 6 | | 8 | | …

2024 年最新 Python 基于百度智能云实现文字识别 OCR 详细教程

文字识别 OCR 概述 文字识别OCR&#xff08;Optical Character Recognition&#xff09;提供多场景、多语种、高精度的文字检测与识别服务&#xff0c;多项ICDAR指标居世界第一。广泛适用于金融服务、财税报销、法律政务、保险医疗、快递物流、交通出行、教育培训等场景&#…

设计模式-外观(门面)模式(结构型)

外观模式 外观模式又称门面模式&#xff08;结构型模式&#xff09;&#xff0c;它是一个可以屏蔽系统复杂性的设计模式。俗话说没有什么问题是加一层“介质”解决不了的&#xff0c;如果有那就在加一层。在开发过程中肯定封装过Utils类&#xff0c;我认为这就是一种门面模式&…

RocketMQ的安装

首先到RocketMQ官网下载页面下载 | RocketMQ (apache.org)&#xff0c;本机解压缩&#xff0c;作者在这里用的是最新的5.2.0版本。按照如下步骤安装。 1、环境变量配置rocket mq地址 ROCKETMQ_HOME D:\rocketmq-all-5.2.0-bin-release 在变量path中添加”%ROCKETMQ_HOME%\bi…

Python | Leetcode Python题解之第132题分割回文串II

题目&#xff1a; 题解&#xff1a; class Solution:def minCut(self, s: str) -> int:n len(s)g [[True] * n for _ in range(n)]for i in range(n - 1, -1, -1):for j in range(i 1, n):g[i][j] (s[i] s[j]) and g[i 1][j - 1]f [float("inf")] * nfor …

Block Transformer:通过全局到局部的语言建模加速LLM推理

在基于transformer的自回归语言模型&#xff08;LMs&#xff09;中&#xff0c;生成令牌的成本很高&#xff0c;这是因为自注意力机制需要关注所有之前的令牌&#xff0c;通常通过在自回归解码过程中缓存所有令牌的键值&#xff08;KV&#xff09;状态来解决这个问题。但是&…

英码科技推出鸿蒙边缘计算盒子:提升国产化水平,增强AI应用效能,保障数据安全

当前&#xff0c;随着国产化替代趋势的加强&#xff0c;鸿蒙系统Harmony OS也日趋成熟和完善&#xff0c;各行各业都在积极拥抱鸿蒙&#xff1b;那么&#xff0c;边缘计算要加快实现全面国产化&#xff0c;基于鸿蒙系统开发AI应用势在必行。 关于鸿蒙系统及其优势 鸿蒙系统是华…

SpringCloud-面试篇(二十三)

&#xff08;1&#xff09;SpringCloud常见组件有那些 有无数微服务需要相互调用&#xff1a;可以用远程调用组件OpenFeign组件&#xff0c;也可以用Dobble 这么多微服务相互调用怎么管理&#xff1a;就用到注册中心组件Nacos&#xff0c;Eureka 所有的服务去找注册中心做注…

计算机组成结构—IO方式

目录 一、程序查询方式 1. 程序查询基本流程 2. 接口电路 3. 接口工作过程 二、程序中断方式 1. 程序中断基本流程 2. 接口电路 3. I/O 中断处理过程 三、DMA 方式 1. DMA 的概念和特点 2. DMA 与 CPU 的访存冲突 3. DMA 接口的功能 4. DMA 接口的组成 5. DMA 的…