跳到主要内容

79 篇博文 含有标签「前端」

前端开发技术文章

查看所有标签

JavaScript 的可选链操作符

· 阅读需 1 分钟
素明诚
Full stack development

可选链操作符 (?.) 允许开发者在访问深层嵌套对象属性时无需显式验证每一层的存在性。这大大简化了从复杂对象中提取值的过程,尤其是在属性可能未定义的情况下。该特性在 ECMAScript 2020 中正式引入,之前开发者需要进行多层检查以防运行时错误。

可选链操作符 (?.) 的应用场景

对象属性访问

当访问链中的某个中间属性不存在时,不会引发错误,而是使表达式短路并返回 undefined

let nestedProp = obj.first?.second;

此处,如果 obj.firstnullundefined,则 nestedProp 返回 undefined

数组索引访问

let item = arr?.[42];

表达式安全地访问数组的第 43 项,不必担心 arr 可能为 nullundefined

函数或方法调用

如果尝试调用的函数不存在,表达式会短路并返回 undefined,而不抛出错误。

obj.func?.();

如果 obj.func 存在且为函数,则执行调用;如果为 undefinednull,则不执行并返回 undefined

Cookie 和 Session 的区别

· 阅读需 2 分钟
素明诚
Full stack development

Session 指的是服务器为了跟踪和区分用户的状态而在服务器端存储的数据。当用户与 Web 应用交互时,服务器会创建一个会话(Session),用来保存关于这个用户的信息,这可以包括用户的登录状态、购物车内容或任何其他必要的数据,以保持用户在多个页面请求之间的持续性。

工作原理

会话创建:用户首次访问网站时,服务器会生成一个独一无二的会话标识符(Session ID),并以此来创建一个会话。这个会话标识符通常会通过 Cookie 发送到用户的浏览器,保存在用户端。

会话存储:服务器使用会话 ID 识别来自同一浏览器的后续请求,并可以根据需要检索和修改会话数据。

会话结束:会话可以通过服务器设置的超时,用户的主动登出或者通过其他机制结束。

Cookie:通常用来存储 Session ID,是服务器发送到用户浏览器并保存在本地的小数据片段。浏览器每次向服务器发送请求时都会自动附带这些 Cookie,使服务器能够识别用户和会话状态。

Session 数据:实际的数据保存在服务器端,通过从浏览器发送的 Cookie 中提取的 Session ID 进行访问和管理。

安全性

由于 Session 数据存储在服务器端,它比存储在用户浏览器中的 Cookie 更安全。没有直接的方式可以从用户端查看或修改存储在服务器上的 Session 数据。所以 Cookie 一般用来保存用户信息,Session 的主要作用就是通过服务端记录用户的状态

Axios 状态码处理范围

· 阅读需 2 分钟
素明诚
Full stack development
状态码范围Axios 行为
200 - 299触发 .then() 方法
小于 200触发 .catch() 方法
300 - 399根据具体情况(如重定向)处理
400 - 499触发 .catch() 方法
500 及以上触发 .catch() 方法

获取重定向信息

axios.get('/url', {
maxRedirects: 0 // 不自动重定向
}).then(response => {
console.log('响应状态码:', response.status); // 例如 302
console.log('重定向到:', response.headers.location); // 重定向目标 URL
}).catch(error => {
console.log('处理错误', error);
});

修改 validateStatus 函数

通过修改 validateStatus 函数,你可以定义哪些 HTTP 状态码应该解析为成功响应

axios.get('/api', {
validateStatus: function (status) {
return true; // 所有响应都视为成功,都会传递给.then()
}
})
.then(response => {
console.log('任何状态码都在这里处理:', response.status);
})
.catch(error => {
console.log('处理错误', error);
});

建议

前端开发中,通常会对 Axios 进行封装以便更高效地处理业务逻辑。一种常见做法是与前端团队约定一套自定义状态码,通过这些状态码来控制不同的逻辑流程。在这种设计中,服务端不管请求的实际结果如何,总是返回 HTTP 状态码 200。随后,通过响应体中的自定义 code 来判断具体的业务状态,并据此进行相应的处理。这种方法简化了响应的判断逻辑,使得前端开发者可以更直接地使用 Axios 来实现业务需求,同时也降低了处理网络或服务器错误的复杂性。

Nextjs 报错 Warning Extra attributes from the server style

· 阅读需 2 分钟
素明诚
Full stack development

问题原因

发生此错误的原因是 nextjs 从服务器端收到了客户端无法识别的额外属性,简单的说就是客户端渲染和服务端渲染不匹配。

我这个项目刚初始化,使用的是 next+radix-ui,配置全局主题的时候出现的错误

cf131e6a0d82e7d521bb6bf7454f15e7## 解决方法 1,忽略这个警告

修改 layout.tsx 的 html 属性,增加 suppressHydrationWarning

<html suppressHydrationWarning={true}>

解决方法 2,关闭浏览器插件

如果你有很多浏览器插件,尤其是涉及到样式和颜色,或者是文字类的,都会导致这个问题,你可以选择在开发环境下禁用这个插件

Chrome 推出了一个新的测试版功能,允许用户为特定 URL 关闭扩展,这有助于解决相关错误。您可以通过访问 chrome://flags/#extensions-menu-access-control 启用“Extensions Menu Access Control”标志,并重启 Chrome。启用后,您可以通过扩展程序图标来切换或启用/禁用特定 URL 的扩展。

18e725a41967c18898147d0c3ed1f519## 解决方法 3,不使用错误的嵌套

错误的嵌套如下,或者是例如li元素中嵌套ul元素,情况有很多

<a>
<a><a/>
<a/>

如果你有这个错误,大概率是这些问题导致的

pnpm 将子项目作为依赖引入项目

· 阅读需 2 分钟
素明诚
Full stack development

创建和配置 pnpm 工作空间

创建 pnpm-workspace.yaml 文件: 在项目的根目录下创建一个 pnpm-workspace.yaml 文件,用于指定包含的子项目路径。

packages:
- 'packages/*'

这告诉 pnpmpackages 文件夹下的每个子目录都是单独的项目,并应该被视为工作空间的一部分。

初始化子项目: 确保每个子项目目录下都有自己的 package.json 文件。这些 package.json 文件应定义各自的依赖和脚本。

安装和管理依赖

安装依赖: 在根目录执行 pnpm install 命令。这会根据 pnpm-workspace.yaml 的配置为所有子项目安装依赖,并在根目录的 node_modules 中创建必要的符号链接。

添加跨项目依赖: 如果你想在一个子项目中使用另一个子项目作为依赖,可以在 package.json 中使用 workspace: 协议。例如,如果 projectA 依赖于 projectB,则 projectApackage.json 应写为

{
"dependencies": {
"projectB": "workspace:*" // 注意这个 projectB 就是你子项目的文件夹名字
}
}

这告诉 pnpm 从当前工作空间中找到 projectB 并将其链接到 projectA

构建和运行项目

构建项目: 根据每个项目的配置,运行相应的构建命令。你可以在根目录下使用 pnpm run --filter <project-name> build 来针对特定项目运行构建脚本。

开发中的项目互用: 使用工作空间协议 workspace:* 允许你在开发中实时链接子项目,任何在依赖项目中的改动都会立即反映到使用该依赖的项目中。

Chrome http 获取麦克风

· 阅读需 1 分钟
素明诚
Full stack development

谷歌浏览器地址栏输入

chrome://flags/#unsafely-treat-insecure-origin-as-secure

设置 IP 地址并且启用

f6ef4dc1affa10203794f8d98eafca91

多个地址

http://10.20.201.215:30001,http://172.22.220.89:30001

重启浏览器

点击右下角的 Relaunch

重写 JS 数组方法

· 阅读需 4 分钟
素明诚
Full stack development

这篇文章汇总了当前已实现的数组方法。未实现的方法将在后续更新中补充到本文中。如果你希望检验自己的基础知识,也可以根据本文提供的表格逐一尝试实现这些数组方法。已实现的会插入超链接~

数组方法实现难度

方法名描述难度评级
push()向数组的末尾添加一个或更多元素,并返回新的长度。
pop()移除数组最后一个元素,并返回该元素。
shift()从数组中删除第一个元素,并返回该元素。
unshift()向数组的开头添加一个或多个元素,并返回新的长度。
indexOf()返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
lastIndexOf()返回数组中最后出现的指定元素的索引,如果未找到则返回 -1。
join()将所有数组元素连接成一个字符串并返回。
reverse()颠倒数组中元素的顺序。
includes()判断数组是否包含一个指定的值。
slice()返回数组的一个片段或子数组。
concat()合并两个或多个数组,并返回一个新数组。
splice()在数组中添加或删除元素,并返回被删除的元素。
toString()返回一个字符串表示数组中的元素。
toLocaleString()返回一个字符串表示数组中的元素。本地化的字符串表示形式。
fill()用一个固定值填充数组中从起始索引到终止索引的全部元素。
map()创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后的返回值。
filter()创建一个新数组, 其包含通过所提供函数测试的所有元素。
every()检测数组所有元素是否都符合指定条件。
some()检测数组中的某些元素是否满足指定条件。
find()返回数组中满足提供的测试函数的第一个元素的值。
findIndex()返回数组中满足提供的测试函数的第一个元素的索引。
findLast()返回数组中最后一个满足所提供测试函数的元素。
findLastIndex()返回数组中最后一个满足所提供测试函数的元素的索引。
reduce()对数组中的每个元素执行一个用户提供的 reducer 函数(升序执行),从左到右。
reduceRight()对数组中的每个元素执行一个用户提供的 reducer 函数(降序执行),从右到左。
flatMap()先对数组的每个元素执行一个映射函数,然后将结果压平成一个新数组。
flat()将所有嵌套数组的元素连接成一个新数组。
copyWithin()在数组内部,将一系列元素按序复制到另一个起始位置,并返回数组。
sort()对数组的元素进行排序。
entries()返回一个新的 Array Iterator 对象,包含数组中每个索引的键/值对。
keys()返回一个新的 Array Iterator,包含数组中每个索引的键。
values()返回一个新的 Array Iterator 对象,包含数组每个索引的值。
forEach()对数组的每个元素执行一次给定的函数。

如果你喜欢这篇文章请点个赞再走吧~

Nextjs 快速上手

· 阅读需 5 分钟
素明诚
Full stack development

阅读本文希望你有一定的前端基础,Next.js 了解以下几点即可快速上手,有问题的话就边做边解决~

文件系统路由

Next.js 通过 pages 目录中的文件和文件夹结构自动设置路由。你创建出来的每一个 React 组件文件都被视为一个路由。

如果你有一个博客,你可能需要为每篇文章创建一个页面。在 pages 目录下,你可以创建一个名为 posts 的文件夹,然后在其中创建一个名为 [id].js 的文件。这里的 [id] 表示动态的路由部分。

// pages/posts/[id].js
import { useRouter } from 'next/router';

function Post() {
const router = useRouter();
const { id } = router.query;

return <p>Post: {id}</p>;
}

export default Post;

预渲染和数据获取

Next.js 支持两种形式的预渲染:静态生成(Static Generation)和服务器端渲染(Server-side Rendering)

静态生成(Static Generation)

静态生成是在构建时生成 HTML 的过程(也就是执行 next build 命令时)。这意味着页面在构建时就被渲染好,并且在每个请求中重复使用。这种方式非常适合内容不频繁更改的页面。

示例:使用 getStaticProps 为博客首页获取文章列表

// pages/index.js
export async function getStaticProps() {
// 模拟从外部API获取数据
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();

// 将获取的文章数据通过props传递给页面组件
return {
props: { posts },
revalidate: 10, // 在生产模式下,每10秒重新生成页面一次
};
}

function HomePage({ posts }) {
return (
<div>
<h1>Latest Blog Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}

export default HomePage;

这个例子中,getStaticProps 在构建时调用,获取所有的博文,然后保存在页面的 HTML 中。通过设置 revalidate,你可以使页面在一定时间后重新生成,以便更新内容。

服务器端渲染(Server-side Rendering)

服务器端渲染是每次请求时都生成 HTML 的过程。这种方法适合内容频繁更新的页面,或者内容在每次请求时都可能不同的情况。

示例:使用 getServerSideProps 显示用户个人信息页面,这个信息依赖于每次请求的用户身份。

// pages/profile.js
export async function getServerSideProps(context) {
const { req } = context;
const userId = req.cookies.userId; // 假设用户ID存储在cookies中

const res = await fetch(`https://api.example.com/users/${userId}`);
const userData = await res.json();

return {
props: { user: userData }
};
}

function ProfilePage({ user }) {
return (
<div>
<h1>User Profile</h1>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
);
}

export default ProfilePage;

这个例子中,getServerSideProps 在每次页面请求时执行,从 API 获取当前用户的数据,并将其作为 props 传递给页面。这确保了用户看到的总是最新的信息。

API 路由

假设你有一个处理特定用户的 API 路由,文件路径为 pages/api/users/[id].js

// pages/api/users/[id].js
export default function handler(req, res) {
const { query: { id }, method } = req;

switch (method) {
case 'GET':
// 获取特定用户的信息
res.status(200).json({ id, name: "John Doe" });
break;
case 'PUT':
// 更新特定用户的信息
res.status(200).json({ id, name: "John Doe Updated" });
break;
case 'DELETE':
// 删除特定用户
res.status(200).json({ message: `User ${id} deleted.` });
break;
default:
// 不支持其他方法
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}


CSS 支持

Next.js 支持 CSS Modules,允许你使用局部作用域的 CSS。

// styles/Home.module.css
.home {
color: blue;
}

// pages/index.js
import styles from '../styles/Home.module.css';

function HomePage() {
return <div className={styles.home}>Welcome to the HomePage</div>;
}

export default HomePage;

图像优化

Next.js 提供了内置的 Image 组件,用于自动优化图像加载。推荐使用

示例:使用 Image 组件

import Image from 'next/image';

function MyImageComponent() {
return (
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
);
}

环境变量

管理应用的环境变量,如 API 密钥或数据库 URL,Next.js 提供了一个简单的方式来加载和使用环境变量。

// 在 .env.local 文件中设置
API_SECRET_KEY=your_secret_key

// 在代码中使用
process.env.API_SECRET_KEY

配置不同环境的环境变量

  • .env.local - 存放本地开发环境特有的变量,通常不应该提交到版本控制系统。
  • .env - 存放所有环境通用的变量。
  • .env.development, .env.test, .env.production - 分别用于开发、测试和生产环境的特定变量。

您可以通过设置 NODE_ENV 环境变量来指定当前环境。这通常在启动应用时完成

  • 在本地开发环境,NODE_ENV 通常默认为 development
  • 在生产环境部署时,应将 NODE_ENV 设置为 production
  • 对于测试环境,可以设置为 test

在命令行中启动应用时,可以这样设置环境变量

NODE_ENV=production npm run build

动态导入

Next.js 支持 JavaScript 和组件的动态导入,这有助于减少初始加载时间并按需加载功能。类似于 vue-router 的异步加载。这个特性都是用来实现代码拆分和按需加载,从而优化应用的初始加载时间和总体性能。

import dynamic from 'next/dynamic';

const DynamicComponent = dynamic(() => import('../components/hello'));

function Home() {
return (
<div>
<DynamicComponent />
</div>
);
}

export default Home;

样式

CSS 和模块:全局 CSS 文件只能在 _app.js_app.tsx 中导入,但 CSS 模块(.module.css)可以在组件的任何地方导入,以提供作用域样式。

特殊文件

pages/_app.js:允许你用布局和全局样式初始化页面。这个文件用于在页面间导航时保持状态。

pages/_document.js:用于自定义 HTML 文档结构,常用于增强应用的 <html><body> 标签。

pages/_error.js:用于覆盖 Next.js 提供的默认错误页面。

如果您喜欢这篇文章,不妨给它点个赞并收藏,感谢您的支持!

Web 响应式设计缩写和尺寸

· 阅读需 1 分钟
素明诚
Full stack development
名称缩写描述
像素px固定单位,一个像素点的大小。
百分比%相对单位,基于父元素的相应属性值的百分比。
视口宽度单位vw相对单位,基于视口宽度的百分比,1vw 等于视口宽度的 1%。
视口高度单位vh相对单位,基于视口高度的百分比,1vh 等于视口高度的 1%。
字体相对单位em相对单位,基于元素的字体大小。
根字体相对单位rem相对单位,基于根元素(:root 或 html)的字体大小。
非常小的设备xs用于小尺寸设备如手机竖屏。
小型设备sm用于稍大屏幕尺寸如手机横屏。
中等设备md用于中等屏幕设备如平板。
大型设备lg用于较大屏幕尺寸如桌面显示器。
非常大的设备xl用于非常大的屏幕尺寸,通常是大型桌面显示器。
超大的设备xxl在某些框架中使用,用于更大的桌面显示器。

Nextjs SSR SSG ISR 理解

· 阅读需 4 分钟
素明诚
Full stack development

Next.js 提供了几种预渲染技术,包括服务器端渲染(SSR)、静态站点生成(SSG)和增量静态再生(ISR)。这些技术是现代 web 开发中提高性能、SEO 和用户体验的关键。

服务器端渲染(SSR) - Server Side Rendering

定义

SSR 是一种预渲染技术,其中页面的 HTML 是每次请求时在服务器上生成的。这意味着每当用户请求页面时,服务器都会实时生成 HTML,包括所有预先获取的数据。

说明

服务器端渲染特别适合于内容经常变动的应用。由于内容在服务器上即时生成,因此用户总是看到最新的页面数据。这种方式对搜索引擎优化(SEO)也非常有利,因为搜索引擎抓取器抓取的是已经预渲染好的页面。

示例

在 Next.js 中使用 getServerSideProps 函数来获取数据,并在请求时实时渲染页面。

// pages/index.js
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/data');
const data = await res.json();

return { props: { data } };
}

function HomePage({ data }) {
return <div>Welcome to the page! Data: {data.content}</div>;
}

export default HomePage;

应用场景

  • 实时新闻网站
  • 股票市场数据页面
  • 社交媒体的动态更新页面

静态站点生成(SSG) - Static Site Generation

定义

SSG 是指在构建时生成所有必需页面的 HTML 的过程。构建完成后,每个页面都是一个静态文件,可以直接从 CDN 服务。

说明

静态站点生成适用于内容变化不频繁的页面,这种方式可以极大地提高网站的加载速度,因为静态文件可以从最接近用户的服务器快速提供。

示例

使用 getStaticProps 来预先获取数据,并在构建时生成静态页面。

// pages/about.js
export async function getStaticProps() {
const res = await fetch('https://api.example.com/info');
const info = await res.json();

return { props: { info } };
}

function AboutPage({ info }) {
return <div>About us: {info.description}</div>;
}

export default AboutPage;

应用场景

  • 博客
  • 文档网站
  • 企业营销网站

增量静态再生(ISR) - Incremental Static Regeneration

定义

ISR 是 Next.js 特有的一种混合渲染模式,它允许开发者为每个页面设置一个“再生”时间,用于定期更新静态内容。

说明

这种方法结合了 SSG 的性能优势和 SSR 的灵活性,页面在用户访问时不会立即生成,但可以在背景中定期更新,以确保内容的新鲜度。

示例

getStaticProps 中使用 revalidate 选项,来设定页面的再生时间。

// pages/products.js
export async function getStaticProps() {
const res = await fetch('https://api.example.com/products');
const products = await res.json();

return {
props: { products },
revalidate: 3600, // 页面每小时重新生成一次
};
}

function ProductsPage({ products }) {
return <div>{products.map(product => <div key={product.id}>{product.name}</div>)}</div>;
}

export default ProductsPage;

应用场景

  • 电子商务网站上的产品列表
  • 需要定期更新但不需要秒级更新的新闻文章

对比

特性 / 技术SSRSSGISR
生成时机每次请求时构建时构建时,定期再生
内容更新实时构建后不更新定期更新
性能中等,依赖服务器性能极高,直接从 CDN 服务高,静态文件,定期更新
适用场景动态内容网站静态内容网站静态和动态混合内容网站
SEO 优势
开发复杂度

这三种技术各有优势和特定的适用场景,选择合适的渲染方法可以极大提升应用的性能和用户体验。

如果您喜欢这篇文章,不妨给它点个赞并收藏,感谢您的支持!