当前位置: 首页 > news >正文

Next.js入门介绍(服务端渲染)

Next.js

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 前言
三 设置
四 多页面
五 链接
六 样式
七 共享组件
八 布局组件
九 实战
 9.1 目录结构
 9.2 UI 组件
 9.3 Markdown 内容
 9.4 Pages 入口和 API
  9.4.1 服务端渲染
 9.5 Public 静态资源
 9.6 resoruces
十 参考文献

二 前言

返回目录

使用 Next.js 好处:

  • 服务器端渲染(默认)
  • 自动代码切分, 加速页面加载
  • 简单的客户端路由(基于页面)
  • 基于 Webpack 的开发环境, 支持热模块替换(HMR: Hot Module Replacement)
  • 可以使用 Express 或其他 Node.js 服务器实现
  • 使用 Babel 和 Webpack 配置定制

渲染模式

  • 客户端渲染:页面在浏览器获取到 JavaScript 和 CSS 等文件之后开始渲染,完全在客户端工作,路由也是客户端路由
  • 服务端渲染:页面由服务端渲染过后直接返回 HTML 页面给前端,URL 的变更会刷新整个页面
  • 同构(Universal App):为改进客户端渲染中首屏加载过大文件或者过多文件变得特别慢,所以将首屏渲染放在服务端来提升首屏速度,首屏过后交由客户端控制

三 设置

返回目录

Next.js 可以在 Windows、Mac 和 Linux 运行,只需要在系统中安装 Node.js 即可开始构建 Next.js 应用程序。

那么开始创建项目:

  • 创建项目文件夹:mkdir next
  • 前往文件夹:cd next
  • 初始化项目:npm init -y
  • 安装 React 和 Next:npm i react react-dom next

此处标记下版本:

"dependencies": {"next": "^10.0.4","react": "^17.0.1","react-dom": "^17.0.1"
}
  • 新建 pages 文件夹:mkdir pages

此时项目文件夹如下所示:

+ .next
+ node_modules
+ pages- index.js
- package-lock.json
- package.json

首先,修改 package.json

package.json

{"name": "next","version": "1.0.0","description": "next","main": "index.js",
+ "scripts": {
+   "dev": "next"
+ },"keywords": [],"author": "","license": "ISC","dependencies": {"next": "^10.0.4","react": "^17.0.1","react-dom": "^17.0.1"}
}

然后,往 pages/index.js 添加内容:

pages/index.js

const Index = () => (<div><h1>Hello next</h1></div>
);export default Index;

最后,终端执行 npm run dev,就可以看到页面显示:Hello next

四 多页面

返回目录

当然,一个页面太孤独了,给它添加个小伙伴 pages/about.js

pages/about.js

const About = () => (<div><h1>关于 next</h1></div>
);export default About;

这样访问 about.js 就可以看到 关于 next 了。

五 链接

返回目录

修改下 pages/index.js,添加一个站内跳转:

pages/index.js

import Link from 'next/link';const Index = () => (<div><h1>Hello next</h1>
+   <Link href='/about'>
+     <a>About Page</a>
+   </Link></div>
);export default Index;

这样在 http://localhost:3000/ 我们就可以看到 About Page 并点击跳转过去了。

Next.js 处理了 location.history 相关的内容,所以不需要再处理路由了

<Link> 组件不仅可以放 <a> 标签,你还可以放 <button>,能放置的唯一要求是:它能够接受一个 onClick 属性

六 样式

返回目录

下面再处理下 pages/index.js,将链接换成 next 喜欢的深空蓝:

pages/index.js

import Link from 'next/link';const Index = () => (<div><h1>Hello next</h1><Link href='/about'><a style={{ textDecoration: 'none', color: 'deepskyblue' }}>About Page</a></Link></div>
);export default Index;

注意:你并不能在 <Link> 上添加样式,因为它是一个高阶组件,只能接收 href 属性

七 共享组件

返回目录

新建一个好看的页头组件:

components/Header.js

import Link from 'next/link';const linkStyle = {marginRight: 15,color: 'deepskyblue'
};const Header = () => (<div><Link href='/'><a style={linkStyle}>Home</a></Link><Link href='/about'><a style={linkStyle}>About</a></Link></div>
);export default Header;

这个组件将我们 pages/about.jspages/index.js 关联了起来,要怎么使用呢?

pages/index.js

import Header from '../components/Header';const Index = () => (<div><Header /><h1>Hello next</h1></div>
);export default Index;

pages/about.js

import Header from '../components/Header';const About = () => (<div><Header /><h1>关于 next</h1></div>
);export default About;

so easy~

这样就搞成公共的了。

注意:pages 目录是特殊的,Next.js 会读取 pages 作为入口,但是 components 不是特殊的,你可以将你的组件文件夹命名成 comps 也是可行的

八 布局组件

返回目录

既然前面已经做到共享了,那么为何不丰富一下,将其作为一个布局组件。

Header 作为布局组件的一部分,新建 components/Layout.js

components/Layout.js

import Header from './Header';const layoutStyle = {margin: 20,padding: 20,border: '1px solid #DDD',
};const Layout = (props) => (<div style={layoutStyle}><Header />{props.children}</div>
);export default Layout;

这样就可以在 index.jsabout.js 中使用了。

pages/index.js

- import Header from '../components/Header';
+ import Layout from '../components/Layout';const Index = () => (
- <div>
-   <Header />
-   <h1>Hello next</h1>
- </div>
+ <Layout>
+   <h1>Hello next</h1>
+ </Layout>
);export default Index;

pages/about.js

- import Header from '../components/Header';
+ import Layout from '../components/Layout';const About = () => (
- <div>
-   <Header />
-   <h1>关于 next</h1>
- </div>
+ <Layout>
+   <p>关于 next</p>
+ </Layout>
);export default About;

在这里 {props.children} 是创建布局组件的一种手段。

创建布局组件还有其他方式:

方式一

import withLayout from '../lib/layout';const Page = () => (<p>Hello next</p>
);export default withLayout(Page);

方式二

const Page = () => (<p>Hello next</p>
)export default () => (<Layout page={Page}/>)

方式三

const content = (<p>Hello next</p>);export default () => (<Layout content={content}/>);

九 实战

返回目录

9.1 目录结构

返回目录

+ components ———————————————————— UI 组件- Layout.jsx                 —— 布局- Nav.jsx                    —— 导航- Page.jsx                   —— 内容
+ markdown   ———————————————————— Markdown 存放位置- Next.md- react-markdown.md- README.md
+ pages      ———————————————————— Next 规定页面目录+ api      ———————————————————— 本地 API 存放地址- getCatelog.js            —— API:获取目录- getContent.js            —— API:获取内容+ pages    ———————————————————— 子页面加载- [...args].js             —— [...args].js 是 Next.js 规则,可以解构成 A.js、B.js 等- index.js ———————————————————— 入口
+ public     ———————————————————— 静态资源+ css      ———————————————————— CSS- global.css+ img      ———————————————————— 图片- monkey.jpg
+ resoruces  ———————————————————— 工具+ react-syntax-highlighter   —— 魔改 Code 样式- dracula.js               —— 使用这种样式- index.js                   —— 工具入口

9.2 UI 组件

返回目录

Layout.jsx

import Head from 'next/head'; // 设置页面头部信息
import Nav from './Nav';
import Content from './Content';const Layout = (props) => (<>{/* 设置头部信息 */}<Head><link href='./css/global.css' rel='stylesheet'/><title>文档库</title></Head>{/* 设置页面导航 */}<Nav {...props} />{/* 设置页面内容 */}<Content {...props} /></>
);export default Layout;

这里存放了 UI 组件,然后希望传递的数据是这样的:

props = {catelog: [{id,url,title}], // 目录信息content: '', // 文本信息
}

所以 Nav.jsxContent.jsx 如下:

Nav.jsx

import Link from 'next/link';const Nav = (props) => {return (<nav><ul>{props.catelog && props.catelog.map((item) => (<li key={item.id}><Link href={item.url}>{item.title}</Link></li>))}</ul></nav>);
};export default Nav;

Content.jsx

import React from 'react'; // 导入 React
import ReactMarkdownWithHtml from 'react-markdown/with-html'; // 支持 HTML 代码
import gfm from 'remark-gfm'; // 处理删除线、表格、任务清单和 URL
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; // 设置代码高亮
import { dracula } from '../resoruces'; // 魔改样式// 设置代码高亮
const renderers = {code: ({ language, value }) => {return (<SyntaxHighlighterstyle={dracula}language={language}children={value}/>);},
};const Page = (props) => (<div className="content"><ReactMarkdownWithHtmlallowDangerousHtmlrenderers={renderers}children={props.content}plugins={[gfm]}/></div>
);export default Page;

9.3 Markdown 内容

返回目录

markdown 这个目录存放了需要展示的 Markdown 文件,这里就不贴内容了,随意放点都 OK。

9.4 Pages 入口和 API

返回目录

pages 这个目录是 Next.js 指定的,用来存放入口和 API 等内容的。

+ pages      ———————————————————— Next 规定页面目录+ api      ———————————————————— 本地 API 存放地址- getCatelog.js            —— API:获取目录- getContent.js            —— API:获取内容+ pages    ———————————————————— 子页面加载- [...args].js             —— [...args].js 是 Next.js 规则,可以解构成 A.js、B.js 等- index.js ———————————————————— 入口

首先,看主入口 index.js

pages/index.js

import Layout from '../components/Layout';// Next 钩子
export async function getStaticProps() {// 调用 3000 接口,这个请求会被 pages/api/xxx 获取到const [catelogInfo, contentInfo] = await Promise.all([fetch(`http://localhost:3000/api/getCatelog`),fetch(`http://localhost:3000/api/getContent?args=/`),]);// 获取 200 响应if (catelogInfo.status === 200 && contentInfo.status === 200) {const [catelogData, contentData] = await Promise.all([catelogInfo.json(),contentInfo.json(),]);// 拿到接口数据并返回return {props: {catelog: catelogData.catelog,content: contentData.content,},}};
};const Index = (props) => (<Layout {...props} />
);export default Index;

在这里需要注意的是 getStaticProps,如果是服务端渲染应该是 getInitialProps,但是我这里希望直接将所有 Markdown 打包成 HTML,所以就不需要 SSR 配置了。

但是为了避免有的小伙伴需要,后面会加个小节来演示。

然后,当用户通过 <Link /> 请求 pages/A.js 等页面的时候,就会进入 pages/[...args].js 文件:

pages/[…args].js

import Layout from '../../components/Layout';const Index = (props) => (<Layout {...props} />
);// Next 钩子:预构建-获取目录
export async function getStaticPaths() {// 调用 3000 接口,这个请求会被 pages/api/xxx 获取到const [catelogInfo] = await Promise.all([fetch(`http://localhost:3000/api/getCatelog`),]);// 获取 200 响应if (catelogInfo.status === 200) {const [catelogData] = await Promise.all([catelogInfo.json(),]);// 拿到接口数据并返回return {paths: catelogData.catelog.map((item) => item.url),fallback: false, // 如果为 false,其他路由为 404,否则不会 404}};
};// Next 钩子
export async function getStaticProps({ params }) {// 获取链接路径const path = params.args[0];// 调用 3000 接口,这个请求会被 pages/api/xxx 获取到const [catelogInfo, contentInfo] = await Promise.all([fetch(`http://localhost:3000/api/getCatelog`),fetch(`http://localhost:3000/api/getContent?args=/${path}`),]);// 获取 200 响应if (catelogInfo.status === 200 && contentInfo.status === 200) {const [catelogData, contentData] = await Promise.all([catelogInfo.json(),contentInfo.json(),]);// 拿到接口数据并返回return {props: {catelog: catelogData.catelog,content: contentData.content,},}};
};export default Index;

最后,不管是 pages/index.jspages/[...args].js 都会调用 api/getCatelogapi/getContent,所以这两个直接写读取文件:

pages/api/getCatelog.js

const fs = require('fs');
const path = require('path');const BASE_PATH = path.join(process.cwd());// 接口
export default async (req, res) => {// GET 操作if (req.method === 'GET') {// 读取文件夹并返回目录const files = fs.readdirSync(`${BASE_PATH}/markdown`);return res.json({catelog: files.map((item, index) => {const title = item.split('.')[0];return {id: index,title,url: `/pages/${title}`};})});}
}

pages/api/getContent.js

const fs = require('fs');
const path = require('path');const BASE_PATH = path.join(process.cwd());// 接口
export default async (req, res) => {// GET 操作if (req.method === 'GET') {// 如果是 / 根路径,那么重定向为 /READMEif (req.query.args === '/') {req.query.args = '/README';}// 读取文件并返回数据const data = fs.readFileSync(`${BASE_PATH}/markdown${req.query.args}.md`, 'utf-8');return res.json({ content: data });}
}

到此我们页面基本能跑起来了。

9.4.1 服务端渲染

返回目录

+ pages      ———————————————————— Next 规定页面目录+ api      ———————————————————— 本地 API 存放地址- getCatelog.js            —— API:获取目录- getContent.js            —— API:获取内容- [...args].js ———————————————— [...args].js 是 Next.js 规则,可以解构成 A.js、B.js 等- index.js ———————————————————— 入口

这里注意下 [...args] 直接放在一级目录即可,当然也可以放到 pages 里面。

index.js

import Index from './[...args]';export default Index;

[…args].js

import Layout from '../components/Layout';const Index = (props) => (<Layout {...props} />
);// Next 钩子:调用接口
Index.getInitialProps = async (ctx) => {// 获取链接路径const path = ctx.asPath;// 调用 3000 接口,这个请求会被 pages/api.js 获取到const [catelogInfo, contentInfo] = await Promise.all([fetch(`http://localhost:3000/api/getCatelog`),fetch(`http://localhost:3000/api/getContent?args=${path}`),]);// 获取 200 响应if (catelogInfo.status === 200 && contentInfo.status === 200) {const [catelogData, contentData] = await Promise.all([catelogInfo.json(),contentInfo.json(),]);// 拿到接口数据并返回return {catelog: catelogData.catelog,content: contentData.content,}};
};export default Index;

9.5 Public 静态资源

返回目录

public/css/global.css

blockquote {padding: 0 15px;color: #777;border-left: 4px solid #ddd;
}

img/monkey.jpg

随便找个猴子图片

9.6 resoruces

返回目录

resoruces/index.js

"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "dracula", {enumerable: true,get: function get() {return _dracula.default;}
});var _dracula = _interopRequireDefault(require("./react-syntax-highlighter/dracula"));

resoruces/react-syntax-highlighter/dracula.js

"use strict";Object.defineProperty(exports, "__esModule", {value: true
});
exports.default = void 0;
var _default = {"code[class*=\"language-\"]": {"color": "#f8f8f2","background": "none","textShadow": "0 1px rgba(0, 0, 0, 0.3)","fontFamily": "Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace","textAlign": "left","whiteSpace": "pre","wordSpacing": "normal","wordBreak": "normal","wordWrap": "normal","lineHeight": "1.5","MozTabSize": "4","OTabSize": "4","tabSize": "4","WebkitHyphens": "none","MozHyphens": "none","msHyphens": "none","hyphens": "none"},"pre[class*=\"language-\"]": {"color": "#f8f8f2","background": "#282a36","textShadow": "0 1px rgba(0, 0, 0, 0.3)","fontFamily": "Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace","textAlign": "left","whiteSpace": "pre","wordSpacing": "normal","wordBreak": "normal","wordWrap": "normal","lineHeight": "1.5","MozTabSize": "4","OTabSize": "4","tabSize": "4","WebkitHyphens": "none","MozHyphens": "none","msHyphens": "none","hyphens": "none","padding": "1em","margin": ".5em 0","overflow": "auto","borderRadius": "0.3em"},":not(pre) > code[class*=\"language-\"]": {"background": "#282a36","padding": ".1em","borderRadius": ".3em","whiteSpace": "normal"},"comment": {"color": "#6272a4"},"prolog": {"color": "#6272a4"},"doctype": {"color": "#6272a4"},"cdata": {"color": "#6272a4"},"punctuation": {"color": "#f8f8f2"},".namespace": {"Opacity": ".7"},"property": {"color": "#ff79c6"},"tag": {"color": "#00bfff"},"constant": {"color": "#ff79c6"},"symbol": {"color": "#ff79c6"},"deleted": {"color": "#f50000"},"boolean": {"color": "#bd93f9"},"number": {"color": "#bd93f9"},"selector": {"color": "#50fa7b"},"attr-name": {"color": "#50fa7b"},"string": {"color": "#50fa7b"},"char": {"color": "#50fa7b"},"builtin": {"color": "#50fa7b"},"inserted": {"color": "#50fa7b"},"operator": {"color": "#f8f8f2"},"entity": {"color": "#f8f8f2","cursor": "help"},"url": {"color": "#f8f8f2"},".language-css .token.string": {"color": "#f8f8f2"},".style .token.string": {"color": "#f8f8f2"},"variable": {"color": "#f8f8f2"},"atrule": {"color": "#f1fa8c"},"attr-value": {"color": "#f1fa8c"},"function": {"color": "#f1fa8c"},"class-name": {"color": "#f1fa8c"},"keyword": {"color": "#8be9fd"},"regex": {"color": "#ffb86c"},"important": {"color": "#ffb86c","fontWeight": "bold"},"bold": {"fontWeight": "bold"},"italic": {"fontStyle": "italic"}
};
exports.default = _default;

导出模式

  • SSR(Server Side Rendring)
  • SSG(Static Site Generation)
  • SSR With hydration
  • CSR(Client Side Rendering)
  • CSR With Pre-Rendring
  • Trisomorphic Rendring

SSR(Server Side Rendring)

SSR 即服务端渲染。

服务器呈现响应于导航为服务器上的页面生成完整的 HTML。

这样可以避免在客户端进行数据获取和模板化的其他往返过程,因为它是在浏览器获得响应之前进行处理的。

在服务器上运行页面逻辑和呈现可以避免向客户端发送大量 JavaScript,这有助于实现快速的交互时间。

SSG(Static Site Generation)

SSG 即静态网站生成。

静态网站生成类似于服务器端渲染,不同之处在于构建时而不是在请求时渲染页面。

与服务器渲染不同,由于不必动态生成页面的 HTML,因此它还可以实现始终如一的快速到第一字节的时间。

通常,静态呈现意味着提前为每个 URL 生成单独的 HTML 文件。

借助预先生成的 HTML 响应,可以将静态渲染器部署到多个 CDN,以利用边缘缓存的优势。

SSR With hydration

SSR With hydration 即视图通过同时进行客户端渲染和服务端渲染,从而达成一种平衡。

导航请求(例如整页加载或重新加载)由服务器处理,该服务器将应用程序呈现为 HTML,然后将 JavaScript 和用于呈现的数据嵌入到生成的文档中。

理想状态下,就可以像服务器渲染一样实现快速的 First Contentful Paint,然后通过使用称为 hydration 的技术在客户端上再次渲染来修补。

从真实网站中收集的效果指标表明, 使用 SSR 水合模式效果并不好,强烈建议不要使用它。

原因归结为用户体验:最终很容易使用户陷入怪异的山谷。

CSR(Client Side Rendering)

CSR 即客户端渲染。

客户端渲染,意味着: 直接使用 JavaScript 在浏览器中渲染页面。

所有逻辑,数据获取,模板和路由均在客户端而不是服务器上处理。

CSR With Pre-Rendring

CSR With Pre-rendering 即在构建阶段,就将 HTML 页面渲染完毕,不会进行二次渲染。

也就是说,当初打包时页面是怎么样,那么预渲染就是什么样。

等到 JS 下载并完成执行,如果页面上有数据更新,那么页面会再次渲染,这时会造成一种数据延迟的错觉。

Pre-render 利用 Chrome 官方出品的 Puppeteer 工具,对页面进行爬取。

它提供了一系列的 API, 可以在无 UI 的情况下调用 Chrome 的功能, 适用于爬虫、自动化处理等各种场景。

它很强大,所以很简单就能将运行时的 HTML 打包到文件中。

Trisomorphic Rendring

Trisomorphic Rendring 即三态渲染。

在三态渲染模型中,可以使用服务器流式渲染进行初始导航,然后让 Service Worker 在 HTML 加载完成后,继续进行导航 HTML 的渲染。

这样可以使缓存的组件和模板保持最新状态,并启用 SPA 样式的导航,以在同一会话中呈现新视图。

如果可以在服务器,客户端页面和 Service Worker 之间共享相同的模板和路由代码时,这种方法十分有效。

十 参考文献

返回目录

  • Next.js - 中文网站
  • Next.js - 英文官网
  • Next.js 中文学习文档 - 2018
  • Next.js - GitHub
  • 十、Next.js:导出静态 HTML 应用程序
  • Next.js - Github - 静态 HTML 导出
  • https://juejin.cn/post/6844903944343273485
  • ismomrphic-fetch 和 fetch 区别
  • Next.js - GitHub 报错清单
  • React SSR 详解【近 1W 字】+ 2个项目实战
  • 【译】Next.js 9.3 getStaticProps,getStaticPaths和getServerSideProps的新API概述
  • 魅族官网基于 next.js 重构实践总结与分享
  • 「干货」你需要了解的六种渲染模式
  • Next.js 报错 i18n

填坑系列

  • Next.js踩坑入门系列(一)— Hello Next.js!
  • Next.js踩坑入门系列(二)— 添加Antd && CSS
  • Next.js踩坑入门系列(三)— 目录重构&&再谈路由
  • Next.js踩坑入门系列(四)— 中期填坑
  • Next.js踩坑入门系列(五)— 引入状态管理redux
  • Next.js踩坑入门系列(六) —— 再次重构目录

相关文章:

Next.js入门介绍(服务端渲染)

Next.js 一 目录 不折腾的前端&#xff0c;和咸鱼有什么区别 目录一 目录二 前言三 设置四 多页面五 链接六 样式七 共享组件八 布局组件九 实战 9.1 目录结构 9.2 UI 组件 9.3 Markdown 内容 9.4 Pages 入口和 API  9.4.1 服务端渲染 9.5 Public 静态资源 9.6 resor…...

模板Plus

文章目录 1.非类型模板参数的引入2.标准库和普通数组3.模板的特化 1.非类型模板参数的引入 //非类型模板参数 -- 常量 template<class T, size_t N 10> class array { private:T _a[N]; };int main() {array<int> a1;array<int, 100> a2;array<double, …...

spring事务和数据库事务是怎么实现

Spring事务的原理 Spring事务的本质其实就是数据库对事务的支持&#xff0c;没有数据库的事务支持&#xff0c;spring是无法提供事务功能的。对于纯JDBC操作数据库&#xff0c;想要用到事务&#xff0c;可以按照以下步骤进行&#xff1a; 获取连接 Connection con DriverManag…...

el-date-picker设置默认当前日期

HTMl部分&#xff1a; <el-form-item label"拍摄时间&#xff1a;"><el-date-pickerv-model"searchData.filmingTimeRange"type"daterange"align"right"unlink-panelsrange-separator"至"start-placeholder"…...

vue中使用this.$refs获取不到子组件的方法,属性方法都为undefined的解决方法

问题描述 vue2中refs获取不到子组件中的方法&#xff1f;&#xff0c;而获取到的是undefined 原因及解决方案&#xff1a; 第一种、在循环中注册了很多个ref 因为注册了多个ref&#xff0c;获取是不能单单知识refs.xxx&#xff0c;需要使用数组和索引来获取具体一个组件refs[…...

Linux命令200例:df用于显示文件系统的磁盘空间使用情况

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…...

Service not registered 异常导致手机重启分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、Service not registered 异常导致手机重启二、Service not registered 解决方案 一、Service not registered 异常导致手机重启 1.重启 的部分Log如…...

深度解读|一站式ABI平台 Smartbi Insight V11 能力再升级

纵观过去&#xff0c;我们发现汽车和BI的发展有异曲同工之妙。 100来年&#xff0c;汽车的动力从蒸汽到燃油再到新能源&#xff0c;汽车的操控方式从手动到自动再到智能无人驾驶。而在BI领域&#xff0c;自1958年BI的概念提出后&#xff0c;底层数据准备从报表开发、Cube多维模…...

vConsole手机调试模式uniapp和原生h5

手机打开调试模式的方法 尽量放在页面头部&#xff0c;底部有可能不行 原生 <script src"https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js"></script> <script>// init vConsolevar vConsole new VConsole();console.log(Hello world)…...

Flutter Dart语言(05)异步

0 说明 该系列教程主要是为有一定语言基础 C/C的程序员&#xff0c;快速学习一门新语言所采用的方法&#xff0c;属于在C/C基础上扩展新语言的模式。 1 async和await 在Dart语言中&#xff0c;虽然没有像其他语言&#xff08;如Java、C、Python&#xff09;中的传统多线程概…...

滇医通微信小程序分析笔记

注意 本文章仅供学习交流使用&#xff0c;如果你是铁粉你就会知道博主之前发布过一篇相关的文章&#xff0c;但是由于代码涉及到法律相关所以就隐藏了&#xff0c;两年的时间过去了&#xff0c;因为女朋友已经早早安排上了&#xff0c;所以就搁置了&#xff0c;本次不做代码分…...

IoTDB在springboot2中的(二) 查询

上一章我们处理的基本的构建接入&#xff0c;以及插入的处理&#xff0c;那么接下来我们进行查询的操作处理。 我们继续在IoTDBSessionConfig工具类中加入查询的方法处理 /*** description: 根据SQL查询最新一条数据* author:zgy* param sql sql查询语句&#xff0c;count查询…...

SpringBoot 底层机制分析【Tomcat 启动+Spring 容器初始化+Tomcat 如何关联Spring 容器】【下】

&#x1f600;前言 本篇博文是关于SpringBoot 底层机制分析实现&#xff0c;希望能够帮助你更好的了解SpringBoot &#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大…...

NLP(六十五)LangChain中的重连(retry)机制

关于LangChain入门&#xff0c;读者可参考文章NLP&#xff08;五十六&#xff09;LangChain入门 。   本文将会介绍LangChain中的重连机制&#xff0c;并尝试给出定制化重连方案。   本文以LangChain中的对话功能&#xff08;ChatOpenAI&#xff09;为例。 LangChain中的重…...

C字符串与C++ string 类:用法万字详解(上)

目录 引言 一、C语言字符串 1.1 创建 C 字符串 1.2 字符串长度 1.3 字符串拼接 1.4 比较字符串 1.5 复制字符串 二、C字符串string类 2.1 解释 2.2 string构造函数 2.2.1 string() 默认构造函数 2.2.2 string(const char* s) 从 C 风格字符串构造 2.2.3 string(co…...

async/await函数需要trycatch吗?

前言 写异步函数的时候&#xff0c;promise 和 async 两种方案都非常常见&#xff0c;甚至同一个项目里&#xff0c;不同的开发人员都使用不同的习惯, 不过关于两者的比较不是本文关注的重点&#xff0c;只总结为一句话&#xff1a;“async 是异步编程的终极解决方案”。 当使…...

Jenkins集成appium自动化测试(Windows篇)

一&#xff0c;引入问题 自动化测试脚本绝大部分用于回归测试&#xff0c;这就需要制定执行策略&#xff0c;如每天、代码更新后、项目上线前定时执行&#xff0c;才能达到最好的效果&#xff0c;这时就需要进行Jenkins集成。 不像web UI自动化测试可以使用无痕浏览器做到无界…...

MongoDB:切换log日志文件

可以不重启MongoDB&#xff0c;切换日志文件 use admin db.runCommand({logRotate:1})参考 MongoDB 日志切割三种方式...

代码随想录第三十五天

代码随想录第三十五天 Leetcode 860. 柠檬水找零Leetcode 406. 根据身高重建队列Leetcode 452. 用最少数量的箭引爆气球 Leetcode 860. 柠檬水找零 题目链接: 柠檬水找零 自己的思路:我的垃圾思路&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;复…...

块、行内块水平垂直居中

1.定位实现水平垂直居中 <div class"outer"><div class"test inner1">定位实现水平垂直居中</div></div><style>.outer {width: 300px;height: 300px;border: 1px solid gray;margin: 100px auto 0;position: relative;}.te…...

Mybatis引出的一系列问题-动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQL 语句有多痛苦&#xff0c;例如拼接时要确保不能忘记添加必要的空格&#xff0c;还要注意去掉列表最后一个列名的逗号。利用动态 SQL&#xff0c;可以彻底…...

Docker学习之构建Base Image

构建Base Image 目标是构建一个类似官方Hello world的镜像&#xff0c;需要配置好Docker运行环境。 创建目录&#xff0c;编写代码 创建并进入docker目录。 mkdir docker cd dockertouch hello.cvim hello.chello.c文件的内容如下&#xff1a; #include <stdio.h>in…...

SFM(Structure from Motion)和NeRF(Neural Radiance Fields)

SFM&#xff08;Structure from Motion&#xff09;和NeRF&#xff08;Neural Radiance Fields&#xff09;都是计算机视觉领域中的重要算法&#xff0c;用于不同的任务和应用。 SFM&#xff08;Structure from Motion&#xff09;&#xff1a; SFM是一种从图像序列中重建三维场…...

[Vue] Vue2和Vue3的生命周期函数

vue2有11个生命周期钩子, vue3有8个生命周期钩子 从vue创建、运行、到销毁总是伴随着各种事件, 创建、挂载、更新到销毁。 1.vue2系列生命周期 ⑴【beforecreate】实例创建前。 vue完全创建之前&#xff0c;会自动执行这个函数。 ⑵【Created】实例创建后。 这也是个生命…...

springboot集成分布式任务调度系统xxl-job(调度器和执行器)

一、部署xxl-job服务端 下载xxl-job源码 下载地址&#xff1a; https://gitee.com/xuxueli0323/xxl-job 二、导入项目、创建xxl_job数据库、修改配置文件为自己的数据库 三、启动项目、访问首页 访问地址&#xff1a; http://localhost:8080/xxl-job-admin/ 账号&#xff1…...

11_Vue3中的新的组件

1. Fragment 在Vue2中&#xff1a;组件必须要有一个跟标签在Vue3中&#xff1a;组件可以没有根标签&#xff0c;内部会将多个标签包含在一个Fragment虚拟元素中好处&#xff1a;减少标签层级&#xff0c;减少内存占用 2. Teleport 什么是Teleport?——Teleport 是一种能够将…...

详解推送Git分支时发生的 cannot lock ref 错误

在码云上建了一个项目仓库,分支模型使用 git-flow ,并在本地新建了一个功能分支 feature/feature-poll。后来在推送时发生错误,提示 cannot lock ref ...... 这样的错误信息。下面复盘一下具体过程和解决办法,以供参考。 在码云中建立仓库时,考虑到想按照 GitFlow 的模式…...

[国产MCU]-BL602开发实例-PWM

PWM 文章目录 PWM1、BL602的PWM介绍2、PWM驱动API介绍3、PWM使用示例脉冲宽度调制(Pulse width modulation,简称PWM)是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳定电源输出的改变。这种方…...

【JMeter】 使用Synchronizing Timer设置请求集合点,实现绝对并发

目录 布局设置说明 Number of Simulated Users to Group Timeout in milliseconds 使用时需要注意的点 集合点作用域 实际运行 资料获取方法 布局设置说明 参数说明&#xff1a; Number of Simulated Users to Group 每次释放的线程数量。如果设置为0&#xff0c;等同…...

无法对watchdog.sys等系统文件删除,弯道修复,这里解决办法很简单

右击360强力删除...

金融网站如何做设计/网站建设方案设计书

1.目录结构boot/ 目录下包括三个汇编程序&#xff0c;其中包括磁盘引导程序 bootsects.s、获取BIOS中参数的 setup.s汇编程序和32位运行启动代码head.s汇编程序。这三个汇编程序完成了把内 核从快射别上引导加载到内存的工作&#xff0c;并对系统配置参数进行探测&#xff…...

网站群怎么做/宁波seo网络推广报价

在Ubuntu中备份svn上传的代码&#xff0c;将备份的文件命名为svn_backup当前时间.dump文件(例svn_backup20100525.dump)1.编写脚本文件(backup.sh)sudo touch backup.sh创建脚本文件&#xff0c;并编辑文件sudo vim backup.sh上图为配置的文件内容&#xff0c;代码如下&#xf…...

怎么建一个购物网站/网络营销最基本的应用方式是什么

1.什么是原子类 一度认为原子是不可分割的最小单位&#xff0c;故原子类可以认为其操作都是不可分割 1.1 为什么要有原子类&#xff1f; 对多线程访问同一个变量&#xff0c;我们需要加锁&#xff0c;而锁是比较消耗性能的&#xff0c;JDk1.5之后&#xff0c; 新增的原子操作类…...

wordpress 维基主题/西安seo服务培训

美团团购订单系统优化记团购订单系统简介 美团团购订单系统主要作用是支撑美团的团购业务&#xff0c;为上亿美团用户购买、消费提供服务保障。2015年初时&#xff0c;日订单量约400万~500万&#xff0c;同年七夕订单量达到800万。 目标 作为线上S级服务&#xff0c;稳定性的提…...

广州安全教育平台入口登录处/aso优化榜单

阅读目录&#xff1a;1.背景2.项目管理&#xff0c;质量、度量、进度3.软件开发是一种设计活动而不是建筑活动4.快速开发&#xff08;简单的系统结构与复杂的业务模型&#xff09;5.技术人员的业务理解与产品经理的业务理解的最终业务模型5.1.产品的业务理解&#xff08;业务流…...

申请建设网站经费的请示/各网站收录

建造者&#xff08;Builder&#xff09;模式 角色如下&#xff1a; 抽象建造者类&#xff08;Builder&#xff09;&#xff1a;组合Product&#xff0c;实现复杂对象的那些部分的创建具体建造者类&#xff08;ConcreteBuilder&#xff09;&#xff1a;实现builder接口&#x…...