【前端基础知识笔记】 【项目导向型】(持续更新中)

本文记录了作者在开发todo-list、个人中心和微博项目中遇到的前端基础知识,包括NPM版本控制、本地持久化存储、表单提交处理、解构赋值、CSS布局、React Router、按需加载、CSS Module、useEffect、useState、React组件生命周期、跨域解决方案、Redux单向数据流、头像圆形化等知识点,旨在帮助开发者巩固项目中遇到的实际问题和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我在做项目的过程中,学习了一些前端基础知识。为了方便以后的查询,将这些知识集中在这篇博客中,方便以后的查询。

注意!这些知识是不成体系的,因为我只是按照遇到的先后顺序记载于此。这是为了方便结合项目开发过程来复习巩固。

目录

【todo-list项目中的知识】

1. NPM 版本号控制

2. 如何实现本地持久化存储

3. 表单提交后,页面的默认行为是刷新,如何阻止页面在提交后刷新

4. 解构赋值

5. CSS布局:使元素上下居中有哪些常用的办法

【个人中心项目中的知识】

1. react-router-dom中的组件

2. (按需加载)导入组件的方式

3. 不被CSS支持的选择器

4. (CSS Module写法)如何引入两个样式

5. useEffect的返回函数(在组件销毁时执行的函数)

5.1 useEffect的第二个参数

5.2 在哪些情况下需要用useEffect这个hook?

6. 组件内的函数、变量等会再组件渲染时重新生成

7. useState的参数为函数时,该函数的参数是什么?

8. 优化加载

9. antd + React.StrictMode warning

10. 开发环境与生产环境

11. 组件的生命周期 - mount与unmount

12. 闭包

13 Promise

14. 学习一下classComponent

【微博项目 】

1. 切换host

2. The OAuth 2.0 Authorization Framework

3. 前端如何解决跨域问题:

3.1 什么是跨域?关于浏览器的同源策略

3.2 可能遇到的跨域问题?

3.3 为什么要限制跨域通信?

3.4 解决跨域通信的方案有哪些?

4. node层的作用

5. Redux的单向数据流的优势

6. 如何把用户的头像变成圆形的

7. Scss、Sass与Less

8. 微博多图拼接显示

方法 1:没听到

方法 2:用antd或者别的UI框架的grid system。

方法 3:width: 33%; box-sizing: border-box (没有UI框架下的最佳实践)

方法 3 新问题 1:图片不一定是正方形的,如何变成正方形的呢?【无UI框架的最佳实践】

方法 3 新问题 2:图片被拉伸了



【todo-list项目中的知识】


1. NPM 版本号控制

版本号:major.minor.patch

^:控制Major

~:控制Minor

空前缀:安装指定版本


2. 如何实现本地持久化存储

应当使用localStorage进行存储。

localStorage: localStorage 很适合进行少量数据(< 5 M)的存取
sessionStorage: sessionStorage 会在页面关闭之后被清空,无法进行持久化存储
indexedDB:看情况,如果是存储一个简单 JSON 对象,则没有必要使用数据库

此外:localStorage可以存储图片(不过不能太大,可以存小图标

有一种编码方式叫做 base64,这种编码方式可以将二进制编码为可显示的 ASCII 字符(大小写字母及若干个标点符号)。

因此虽然localStorage不能存储二进制,但是可以存储base64编码后的图标。


3. 表单提交后,页面的默认行为是刷新,如何阻止页面在提交后刷新

改用别的方案:比如监听input元素的keydown事件检测回车,而不再使用表单提交。

阻止默认行为:使用preventDefault方法可以组织后续行为的执行,在表单提交汇总可以组织跳转。

使表单不通过校验:监听表单的onSubmit事件并返回false。当onSubmit事件返回false之后,浏览器会认为表单未通过校验,进而就不进行跳转。


4. 解构赋值

数组解构:

支持:解构字符串、跳跃解构、利用剩余参数解构,也支持默认值。

// example 1
const text = "Hello world";
const [,e,l, ...rest] = text;
// H is skipped.
// e --> e
// l --> l
// rest --> ["l", "o", " ", "w", "o", "r", "l", "d"]

// example 2
const array = [1,2,3];
const [a, b, c, d = 100] = array;
// d === 100 

对象解构:

关键:用对应的键名来解构对象,如果想取别的名字要用别名(见example 2)。

支持:键名解构(example 1)、别名解构(example 2)、层级结构(example 3);也支持剩余属性解构和默认赋值。

实际上,example 3中的层级结构类似于example 2的别名,只是这个别名也被解构了。

// example 1 basic
const Person = {name: "Fiona", age: 22, title: "Miss"};
const {name, age, title} = Person; // declare three variables and assgin them values.

// example 2 alias
// formate: {attribute: variable name}
const Person = {name: "Fiona", age: 22, title: "Miss"};
const {name: who} = Person // who === "Fiona";

// example 3 hierarchical structure
const family = {
    property: 567222333,
    members: [
        {name: "Fiona", age: 22},
        {name: "Eris", age: 24},
    ]
};

const { members:[first, ...rest] } = family;
//first === {name: "Fiona", age: 22}
//rest === [ {name: "Eris", age: 24} ]

应用:

for of循环:以快速获取对象属性。比如遍历一个班级的名单(每一项为{name:xxx, age:xxx}),可以for (const {name, age} of array) { ... }

解构参数:以快速获取内容。比如在定义、调用中都以[name, age]作为参数。

 

参数默认值:联合结构参数一起使用,把默认值也写成一个结构体。

// array
function add([x, y] = [1, 2]) {
    return x + y;
}
add() === 3;

// object
function sub({x, y} = {x: 10, y: 5}) {
    return x - y;
}
sub() === 5;

交换变量:

[a, b] = [b, a]

import 语句:

ES6的import语句也是解构赋值。

 

注意事项:

对已经声明了的变量使用解构赋值时,要把这个语句包裹在小括号里()。不然,由于以大括号 { 开头,会被解释器认为本语句将是一个块级代码。

此外:基本类型解构:解释器将{}中的变量自动转化为对象(比如输入一个函数的名字作为变量名,就会变为这个函数对象);而null和undefined因为无法被转换为对象,因此无法解构。


5. CSS布局:使元素上下居中有哪些常用的办法

使用Flex布局:如果不考虑兼容性问题,使用flex布局加align-item: center。

relative相对定位:需要知父子元素的高度,且父元素下也只能有这一个元素。

设置line-height使得文字上下居中:如果父元素只有这一个子元素,而且知道父元素的height,那么可以通过设置子元素的line-height值为父元素的height值。参考这篇文章 应该是这个意思:


【个人中心项目中的知识】


1. react-router-dom中的组件

<BrowserRouter> 是用于包裹 React 路由链接的组件,放置于最外层。参考参阅官方文档

<Switch> 类似switch-case,能够选择其中一个 <Route> 进行渲染;

<Route> 每条路由的路径及组件声明;

<Link> 一个类似于 <a> 标签的组件,可以用于 React 单页应用内的导航。

举例:

const Router = () => (
    <Switch>
        {/* Switch相当于js中的switch function */}
        <Route exact path="/" component={Home}/>  
        <Route exact path="/login" component={Login}/>
        <Route exact path="/register" component={Register}/>
        {/* Route负责匹配一个路径和渲染此路径的组件。 */}
    </Switch>
);

2. (按需加载)导入组件的方式

举例:如果想从antd中导入Menu组件:

import { Menu } from 'antd' 
// 是最常用也是最简单的方法,结合解构方便快捷地导入组件;需要注意的是,这种方法需要搭配摇树优化插件才能实现按需加载;

import Menu from 'antd/lib/menu' 
// 这种方法是一种按需加载的引入方法,只引入所需要的模块,减小打包体积;

import { Menu } from 'antd/dist/antd' 
// 是将打包好的 Antd 资源文件导入,也是直接将整个包导入,而且无法进行加载优化;

const { Menu } = require('antd') 
// 是 nodejs 的 require 导入方法,在 ES6 普及的当下,并不推荐在项目中使用这种写法(各类配置文件除外)。

搭配tree-shaking插件,通过 import {Menu} from 'antd' 导入组件可以实现按需加载。

如果是直接找到了Menu所在的文件,即'antd/lib/menu',也可以手动按需加载导入Menu。

余下的两种方法(一种写明了资源文件,一种是用的require而不是import),则无法实现按需加载。


3. 不被CSS支持的选择器

镶嵌语法(nesting)、变量、mixin写法(为了代码复用)

// nesting写法
.myArticle {
    &p {
        ...
       }
}

// @width是一个变量
@width: 10px;

// mixin可以进行代码复用
.mixin()

4. (CSS Module写法)如何引入两个样式

假设 './index.module.less' 中有 .dark和 .light两个类样式:

CSS Module可以直接导入到组件中:

import styles from './index.module.css'

也可以用解构赋值的方法导入:

import {dark, light} from './index.module.css'

如果使用单一的样式:

<div class = {styles.dark}>Dark Theme</div>

如果要使用多个样式,要添加空格: 第一行两个变量间添加了空格,第二行是用空格来join。

<div class = {`$(dark) $(light)`}>Dark & Light</div> 
<div class = {[dark, light].join(' ')}>Dark & Light</div>

5. useEffect的返回函数(在组件销毁时执行的函数)

useEffect被用于在函数组件中模拟生命周期。

下面是来自九章的说明:

举个例子:

function MyComponent() {
    useEffect(() => {
        const timer = setInterval(
            () => console.log('hooooooook!'),
            1000
        );
        return () => clearInterval(timer);
    }, []);
    
    return (<div>Hello</div>);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值