今天完成了workshop2,进度有点慢,但是记录一下极为愚蠢的一轮轮问答和思考~!(还是有点成就感的)

ps:【】内为我的提问

1 导入语句(ES6 模块导入语法)

【import CatHappiness from "../modules/CatHappiness.js";//这种语句是怎么写的,实际上我们需要手敲这个路径吗?】

这种导入语句(ES6 模块导入语法)在 JavaScript/TypeScript 中用于引入其他文件中的模块,路径的写法和是否需要手敲取决于具体开发场景和工具:

  1. 路径的含义
    ../modules/CatHappiness.js 是相对路径:

    • .. 表示当前文件所在目录的上一级目录
    • /modules/ 是存放模块的文件夹
    • CatHappiness.js 是具体的模块文件
  2. 是否需要手敲路径?

    • 简单项目 / 新手阶段:可能需要手动输入,尤其是文件结构简单时,直接根据文件夹层级关系编写路径即可。
    • 现代开发工具:几乎不需要手敲!主流编辑器(如 VS Code)会自动提示路径,输入文件名时会自动补全相对路径,甚至能识别文件移动后的路径变更并自动修正。
    • 框架 / 构建工具:在 Vue、React 等框架中,还可以配置别名(如用 @ 代替 src/ 目录)简化路径,进一步减少手动编写的复杂度。

例如在 VS Code 中,输入 import CatHappiness from './ 后,编辑器会自动列出可选文件,选中即可自动生成正确路径,无需手动拼写。

2  ES6 模块系统中的默认导出语法

(1)【export default CatHappiness;//这啥意思,这就导出为组件了吗】

export default CatHappiness; 是 ES6 模块系统中的默认导出语法,作用是将 CatHappiness 这个对象(可能是组件、类、函数等)暴露出去,供其他文件通过 import 语句引入使用。

是否导出为 “组件”,取决于 CatHappiness 本身是什么:

  • 如果 CatHappiness 是一个 React 组件(比如函数组件或类组件)、Vue 组件等,那么这行代码就会将其作为默认组件导出。
  • 如果它是一个普通的类、函数或对象,这行代码只是导出这个实体,不一定是 “组件”。

默认导出的特点:

  • 一个文件中只能有一个 export default(默认导出)。
  • 引入时可以自定义名称,比如 import MyCat from '../modules/CatHappiness.js' 也是合法的。
  • 与 “命名导出”(export const CatHappiness = ...)不同,默认导出在导入时不需要加花括号 {}

所以这行代码的核心是 “导出”,是否为 “组件” 取决于被导出的内容本身的类型。

(2)【就是要放在CatHappiness.js结尾的东东吗?】

是的,通常这行代码会放在 CatHappiness.js 文件的末尾,用于明确导出模块的默认内容。

具体来说,一个完整的 CatHappiness.js 文件结构可能是这样的:

javascript

// 定义 CatHappiness(可能是组件、类、对象等)
const CatHappiness = {// ... 具体逻辑
};// 或者是一个函数组件
function CatHappiness() {// ... 组件逻辑
}// 在文件末尾导出,供其他文件导入使用
export default CatHappiness;

这样的写法符合模块化开发的规范:先定义内容,最后通过 export default 明确导出,让其他文件能清晰地知道这个模块的默认导出是什么。

当然,也可以在定义时直接导出(比如 export default function CatHappiness() {...}),但放在末尾导出的方式更常见,尤其是当模块逻辑较长时,能让代码结构更清晰。

(3)【类似于一个我写完了这个组件,现在导出来它叫这个名字,你可以调用这个名字import使用】

完全理解非常准确!

可以这么理解:当你在 CatHappiness.js 中完成了组件的编写后,用 export default CatHappiness; 这句话 “标记” 它 —— 相当于告诉程序:“这个组件我写完了,对外公开的名字就叫 CatHappiness,其他文件可以通过这个名字来引入使用它”。

其他文件要用到时,就可以通过 import CatHappiness from '../modules/CatHappiness.js' 来 “召唤” 这个组件,之后就能像使用内置功能一样调用它了。

这就像给组件贴了个标签,方便其他地方 “按名取用”,是模块化开发中非常基础且重要的机制。

(4)【要是没有这句还可以用吗】

如果没有 export default CatHappiness; 这句导出语句,其他文件无法通过 import 引入并使用这个组件,因为模块系统默认会将文件内容封装起来,不对外暴露。

具体来说:

  • 如果缺少导出语句,CatHappiness 就只是当前文件内部的一个 “局部变量”,外部文件无法访问。
  • 此时若在其他文件中写 import CatHappiness from '../modules/CatHappiness.js',会报错(提示 “没有默认导出”)。

如果不想用默认导出,也可以用命名导出的方式,例如:

javascript

// 在 CatHappiness.js 中
export const CatHappiness = { ... }; // 命名导出

然后在其他文件中这样引入:

javascript

import { CatHappiness } from '../modules/CatHappiness.js'; // 注意加花括号

总之,必须通过 export 相关语法明确导出,其他文件才能使用该模块中的内容,这是 JavaScript 模块化规范的要求。

(5)【我明白了,就是一个命名导出封装的操作,如果没有写在结尾或者根本没写就是不行的】

你的理解很到位!简单来说:

  1. JavaScript 的模块系统默认是 “封闭” 的,文件里的内容就像装在一个封闭的盒子里。
  2. export(包括默认导出 export default 或命名导出 export const xxx)相当于在盒子上开了个 “出口”,让外部能拿到里面的东西。
  3. 如果没写任何 export 语句,这个盒子就是完全封闭的,外部文件无法访问里面的内容,自然也就无法使用 CatHappiness 了。

所以无论是放在结尾还是定义时直接导出(比如 export default function CatHappiness() {}),核心是必须有明确的导出语句,外部才能正常引入使用。这是模块化开发的基本规则,确保了代码的封装性和依赖关系的清晰性。

3 什么时候要用到prop传递?

在 Web 组件开发(尤其是 React、Vue 等框架中),prop(属性)是组件之间传递数据的核心方式。当你需要将数据从父组件传递到子组件时,就需要用到 prop

举个简单的例子理解:

假设你有两个组件:

  • 父组件 App(管理猫咪的整体状态)
  • 子组件 CatCard(展示单只猫咪的信息和幸福感)

当 App 中存储了 catHappiness: 80 这个数据,而 CatCard 需要显示这个 “幸福感数值” 时,就需要通过 prop 把数据传过去:

jsx

// 父组件 App
function App() {const catHappiness = 80; // 父组件中的数据return (// 通过 prop 把数据传给子组件,这里的 "happiness" 就是 prop 名称<CatCard happiness={catHappiness} />);
}// 子组件 CatCard
function CatCard(props) {// 子组件通过 props 接收父组件传来的数据return <div>猫咪幸福感:{props.happiness}分</div>;
}

什么时候需要用 prop 传递?

  1. 数据从父到子流动:当子组件需要依赖父组件的数据才能渲染时(比如上面的幸福感数值)。
  2. 组件复用场景:同一个子组件需要根据不同数据展示不同内容时(比如多个 CatCard 展示不同猫咪的幸福感)。
  3. 配置子组件行为:父组件可以通过 prop 控制子组件的样式或功能(比如 <CatCard isHappy={true} /> 控制显示开心 / 不开心的表情)。

简单说,prop 就像组件之间的 “快递”,负责把父组件的信息安全送到子组件手中,是组件通信最基础的方式。

(1)【当子组件需要依赖父组件的数据才能渲染时?什么意思,我设计了一个按钮统计点击次数作为猫咪幸福指数,也就是这个鼠标点击输入次数就是父组件的吗?我怎么知道要用prop?】

我们结合你的 “按钮统计点击次数作为猫咪幸福指数” 的场景来理解,就很容易明白什么时候需要用 prop 了:

假设你的组件结构是这样的:

  • 父组件CatDashboard(负责管理 “幸福指数” 数据,比如记录按钮点击次数)
  • 子组件HappinessDisplay(负责展示幸福指数的数值和样式)

为什么需要用 prop?

  1. 数据的 “归属权” 在父组件
    点击次数(幸福指数)是通过父组件的按钮产生的,这个数据应该 “存” 在父组件里(比如用 useState 管理)。
    子组件 HappinessDisplay 只负责 “展示”,不负责 “管理数据”,所以它需要父组件把数据 “传” 给它。

  2. 具体代码示例

    jsx

    // 父组件:管理数据(点击次数)
    function CatDashboard() {// 幸福指数数据存在父组件const [catHappiness, setCatHappiness] = useState(0);// 点击按钮增加幸福指数const handleClick = () => {setCatHappiness(prev => prev + 1);};return (<div><button onClick={handleClick}>摸猫咪</button>{/* 通过 prop 把数据传给子组件 */}<HappinessDisplay value={catHappiness} /></div>);
    }// 子组件:只负责展示,依赖父组件传来的数据
    function HappinessDisplay(props) {// 通过 props 接收父组件的数据return <div>猫咪幸福指数:{props.value}</div>;
    }
    

怎么判断什么时候用 prop?

核心看两个问题:

  1. 数据是谁 “产生” 或 “拥有” 的?
    如果数据是 A 组件创建 / 修改的,A 就是 “数据所有者”(通常是父组件)。
  2. 另一个组件 B 是否需要用到这个数据?
    如果 B 组件需要用 A 的数据来渲染(比如展示、根据数据判断样式等),就必须通过 prop 从 A 传到 B。

在你的场景中:

  • 点击次数(幸福指数)由父组件的按钮产生(父组件拥有数据)
  • 展示组件需要用这个数据来显示具体数值(子组件依赖数据)
    所以必然需要用 prop 传递。

简单说:数据在哪,谁需要用,就从哪传到哪,这就是 prop 的核心用途。

4  state(状态)的核心作用

state(状态)的核心作用是管理 “会变化的数据”,而不是 “不会变的数据”。那些固定不变的常量(比如默认名称、基础样式值)通常直接定义成普通变量就行,不需要用 state

我们结合你的 “猫咪幸福指数” 场景,具体说说 state 的作用和用法:

1. state 管理 “会变化的数据”

state 是组件内部用来存储动态数据的容器,当数据发生变化时,组件会自动重新渲染,更新页面展示。

比如你的 “点击次数统计”:

  • 初始点击次数是 0(初始状态)
  • 每次点击按钮,次数会 +1(状态变化)
  • 页面需要实时显示最新的次数(状态变化 → 重新渲染)

这时候就必须用 state 来管理,代码示例:

jsx

function CatDashboard() {// 用 useState 定义一个“会变化”的状态(初始值 0)const [catHappiness, setCatHappiness] = useState(0); // 点击按钮时,通过 setCatHappiness 修改状态const handleClick = () => {setCatHappiness(prev => prev + 1); // 状态更新,组件会重新渲染};return (<div><button onClick={handleClick}>摸猫咪</button><p>幸福指数:{catHappiness}</p> {/* 实时显示最新状态 */}</div>);
}

2. 不会变的数据,不用 state

如果数据从始至终都不会变(比如默认的标题、固定的提示文字),直接定义成普通变量即可,不需要 state

jsx

function CatDashboard() {// 不会变的常量,直接定义const catName = "咪咪"; // 固定名称,不会变const maxHappiness = 100; // 最大指数,固定值// 会变化的点击次数,用 state 管理const [catHappiness, setCatHappiness] = useState(0); return (<div><h2>{catName}的幸福指数</h2><button onClick={() => setCatHappiness(prev => Math.min(prev + 1, maxHappiness))}>摸一下</button><p>当前:{catHappiness}/{maxHappiness}</p></div>);
}

总结:state 的核心特点

  • 管理变化的数据:当数据需要随着用户操作(点击、输入等)或其他事件更新时,必须用 state
  • 触发重新渲染state 一旦通过 setXxx 方法修改,组件会自动重新渲染,页面展示最新数据。
  • 局部性state 是组件 “私有的”,默认只能在当前组件内使用;如果子组件需要,就通过 prop 传递(这就是 state 和 prop 经常配合使用的原因)。

简单说:会变的、需要实时展示的数据用 state,不变的常量直接定义

5 no props 的组件

(1)【有的时候说no props 的组件其实就是没有涉及到数据的吧?】

“no props 的组件”(即不接收任何 props 的组件)并不完全等同于 “没有涉及到数据”,而是指它不依赖外部(父组件)传来的数据,数据可能来自组件内部。

可以从两个角度理解:

1. 完全无数据的组件(真正 “没涉及数据”)

这类组件纯粹是静态 UI,不需要任何数据,只负责展示固定内容,比如:

  • 一个固定文本的提示框(“点击按钮增加猫咪幸福感”)
  • 一个静态的装饰性图标(比如猫咪的默认头像)

示例:

jsx

// 无 props,也无内部数据的组件
function CatIcon() {return <img src="cat-default.png" alt="猫咪图标" />;
}

这类组件确实 “没有涉及数据”,也不需要 props。

2. 有内部数据,但不依赖外部的组件(有数据,但 “no props”)

更常见的情况是:组件有自己的内部数据(用 state 管理),但这些数据不依赖父组件,所以不需要接收 props。

比如你的 “按钮统计点击次数”,如果这个功能完全在组件内部实现(数据自己存、自己用),就可以是一个 no props 组件:

jsx

// 有内部数据(点击次数),但不需要 props 的组件
function CatHappinessCounter() {// 数据存在组件内部,不依赖外部const [count, setCount] = useState(0); return (<div><button onClick={() => setCount(c => c + 1)}>摸猫咪</button><p>幸福指数:{count}</p></div>);
}

这个组件有数据(count),但因为数据是自己产生和使用的,不需要父组件传值,所以也是 “no props”。

总结

“no props” 的核心是组件不依赖外部数据,而不是 “没有数据”。

  • 要么是纯静态 UI(真・无数据);
  • 要么是数据自给自足(有内部数据,不需要外部传入)。

判断是否需要 props,关键看:组件的数据是否需要从外部(父组件)获取。如果不需要,就是 no props 组件~

(2)【ok,我遇见的第一个no props是一个静态ui导航栏,数据自给自足的例子我还没遇到过,也许就是,子组件自己有一个按钮监听鼠标的输入,同时子组件自己处理好了数据,这个时候数据没有在传递就不用prop,那么这时候的子组件是state吗,还是不用定义?】

你的理解非常准确!这种 “自己有按钮、自己处理数据” 的子组件,需要用 state 来管理自己的数据,因为数据是动态变化的(比如点击次数会变),但不需要 props,因为数据不需要和外部组件交互。

举个具体例子:一个子组件 CatPetButton,自己有个按钮,点击后记录次数(作为内部的幸福值),并自己显示结果。这种组件就是 “有 state 但无 props” 的典型:

jsx

// 子组件:有自己的 state(数据),但不需要 props
function CatPetButton() {// 用 state 管理自己的动态数据(点击次数)const [petCount, setPetCount] = useState(0);// 自己处理点击事件,更新内部 stateconst handlePet = () => {setPetCount(prev => prev + 1);};// 自己展示自己的数据return (<div className="cat-button"><button onClick={handlePet}>摸猫咪</button><p>被摸了 {petCount} 次,猫咪很开心!</p></div>);
}// 父组件使用时,直接调用,不用传任何 props
function ParentComponent() {return (<div><h1>猫咪互动区</h1><CatPetButton /> {/* 不需要传 props,组件自己搞定一切 */}</div>);
}

关键点:

  1. 需要 state:因为按钮点击会导致数据变化(petCount 从 0→1→2...),而且需要实时显示最新结果,所以必须用 state 来跟踪这个变化。
  2. 不需要 props:因为数据的产生(点击)、存储(petCount)、使用(显示次数)全在组件内部完成,不需要和外部(父组件)交换数据,所以不用 props

这种组件的特点是 “自给自足”:自己处理用户交互,自己管理状态,自己展示结果,完全独立于其他组件。这在一些功能单一、无需和外部交互的组件中很常见~

6 具体要怎么使用prop?

在使用 prop 时,确实有几种常见的写法,核心都是 “父组件传值,子组件接收”,但形式上略有不同。结合你的代码场景,我们一步步说清楚具体怎么用:

一、最基础的用法:完整写法

1. 父组件传递 prop

就是你代码中写的:

jsx

// 父组件中
<div className="Profile-subContainer"><CatHappiness catHappiness={catHappiness} /> {/* 左边 `catHappiness` 是 prop 名称(子组件接收时用),右边是父组件的变量(要传递的数据) */}
</div>

这里的逻辑是:把父组件中名为 catHappiness 的数据,通过一个叫 catHappiness 的 “通道”(prop 名称)传给子组件。

2. 子组件接收 prop

子组件通过 props 参数获取父组件传来的值:

jsx

// 子组件 CatHappiness.js 中
function CatHappiness(props) {// 用 props.xxx 获取,xxx 就是父组件定义的 prop 名称return <div>幸福指数:{props.catHappiness}</div>; 
}export default CatHappiness;

二、更简洁的写法:解构赋值

如果子组件需要接收多个 prop,或者想简化代码,可以用对象解构直接提取 prop:

jsx

// 子组件中直接解构 props
function CatHappiness({ catHappiness }) { // 直接用 catHappiness,不用写 props. 前缀return <div>幸福指数:{catHappiness}</div>; 
}

这种写法更常用,尤其是在 React 中,代码会更简洁。

三、特殊情况:传递静态值

如果传递的不是变量,而是固定值(比如字符串、数字),可以直接写值,不用加 {}

jsx

// 传递静态字符串(不用加引号,除非有空格)
<CatHappiness title="猫咪幸福指数" />// 传递静态数字
<CatHappiness maxScore={100} />

子组件接收时同样用 props.title 或 { title } 获取。

四、总结:使用 prop 的完整流程(以你的场景为例)

  1. 父组件准备数据
    父组件中必须有一个变量(比如 catHappiness),它可能是 state(会变化的数据)或普通变量(静态数据)。

    jsx

    // 父组件中定义数据(比如用 state 管理)
    const [catHappiness, setCatHappiness] = useState(0); 
    
  2. 父组件传递 prop
    通过 <子组件 自定义名称={数据} /> 的形式传递,比如:

    jsx

    <CatHappiness catHappiness={catHappiness} />
    
  3. 子组件接收并使用
    子组件通过 props 或解构获取,然后在渲染中使用:

    jsx

    // 子组件
    function CatHappiness({ catHappiness }) {return (<div><p>当前幸福值:{catHappiness}</p>{/* 可以根据值做逻辑处理,比如判断是否开心 */}{catHappiness > 5 && <p>猫咪超开心!</p>}</div>);
    }
    

关键原则:

  • 名称一致:父组件定义的 prop 名称(如 catHappiness),和子组件接收时用的名称必须完全一样。
  • 单向流动:数据只能从父组件传到子组件,子组件不能直接修改 prop(如果要改,需要通知父组件改,这是另一个知识点了)。

按照这个流程,你代码中的 catHappiness 就能从父组件传到子组件并显示了,试试吧~

7 具体分析一段代码的prop

代码

<div className="Profile-subContainer u-textCenter"><h4 className="Profile-subTitle">Cat Happiness</h4><CatHappiness catHappiness={catHappiness} />
</div>

我们就以你这段代码为例,把 prop 的用法拆成 “父组件做什么” 和 “子组件做什么” 两部分,一步步说清楚:

一、先看父组件里的代码

jsx

<div className="Profile-subContainer u-textCenter"><h4 className="Profile-subTitle">Cat Happiness</h4>{/* 重点看这一行 */}<CatHappiness catHappiness={catHappiness} />
</div>

这里的 <CatHappiness catHappiness={catHappiness} /> 就是父组件给子组件传 prop 的操作,可以拆成两个部分理解:

  1. 左边的 catHappiness(等号左边):
    这是你给这个 “数据通道” 起的名字,相当于给包裹数据的快递盒贴了个标签,告诉子组件:“这个盒子里的东西叫 catHappiness”。

  2. 右边的 {catHappiness}(等号右边,带大括号):
    这是父组件里真正要传递的数据。这个 catHappiness 通常是父组件里的一个变量(可能是 state 管理的动态数据,比如点击次数的计数器)。
    大括号 {} 是 JSX 的语法,表示这里要插入 JavaScript 变量,而不是普通字符串。

二、再看子组件(CatHappiness.js)要做什么

子组件的任务是 “接收并使用” 父组件传过来的 catHappiness 数据,有两种常见写法:

写法 1:直接 props 对象获取

jsx

// CatHappiness.js
function CatHappiness(props) {// 通过 props.标签名 拿到数据,这里的标签名就是父组件定义的 catHappinessreturn <div>当前幸福指数:{props.catHappiness}</div>;
}export default CatHappiness;
写法 2:用解构赋值简化(更常用)

jsx

// CatHappiness.js
// 直接从 props 里“拆包”出 catHappiness,省掉 props. 前缀
function CatHappiness({ catHappiness }) {return <div>当前幸福指数:{catHappiness}</div>;
}export default CatHappiness;

三、举个完整的例子,把流程串起来

假设父组件是 Profile,里面有个按钮计数器 catHappiness,要传给子组件 CatHappiness 显示:

jsx

// 父组件:Profile.js
import { useState } from 'react';
import CatHappiness from './CatHappiness.js'; // 导入子组件function Profile() {// 父组件里的动态数据(用 state 管理,会变化)const [catHappiness, setCatHappiness] = useState(0);// 点击按钮让指数+1const handleClick = () => {setCatHappiness(prev => prev + 1);};return (<div><button onClick={handleClick}>摸猫咪</button>{/* 把 catHappiness 传给子组件 */}<div className="Profile-subContainer u-textCenter"><h4 className="Profile-subTitle">Cat Happiness</h4><CatHappiness catHappiness={catHappiness} /></div></div>);
}

jsx

// 子组件:CatHappiness.js
function CatHappiness({ catHappiness }) {// 直接到父组件传来的指数,直接用return (<div><p>猫咪次数:{catHappiness}</p>{catHappiness > 3 && <p>猫咪咪次数猫咪很开心!</p>}</div>);
}export default CatHappiness;

四、核心逻辑一句话总结

父组件通过 <子组件 标签名={数据} /> 把数据打包,子组件通过 {标签名} 拆包使用,这个 “标签名” 就是 prop 的名字(这里的 catHappiness)。

你可以把它想象成:父组件给子组件寄快递,快递单上写的收件人是 catHappiness(prop 名),里面的东西是父组件的 catHappiness 变量(数据),子组件收到后,按快递单上的名字 catHappiness 取件就行。

这样是不是就具体多啦?

7 愚蠢的提问:其实react库里面比较重要的是不是就是props和state了,还有什么别的要掌握吗?

props 和 state 确实是 React 的核心基础,但要完整掌握 React 开发,还有几个非常重要的概念和特性需要了解,它们会在实际开发中频繁用到:

1. 组件生命周期(或 Hooks 生命周期替代)

  • 组件从创建到销毁的过程中,会触发一系列 “生命周期事件”(如组件首次渲染后、数据更新后、即将销毁时)。

  • 现代 React 中,更推荐用 Hooks(如 useEffect)来处理生命周期逻辑,比如:

    • 组件首次加载后请求数据(useEffect 空依赖)
    • 数据变化时执行副作用(useEffect 依赖数组)
    • 组件卸载前清理资源(useEffect 返回清理函数)

    示例:

    jsx

    useEffect(() => {// 组件加载后执行(类似生命周期的 componentDidMount)const timer = setInterval(() => {}, 1000);// 组件卸载前执行(清理副作用)return () => clearInterval(timer);
    }, []); // 空依赖表示只执行一次
    

2. 事件处理

  • React 中处理用户交互(点击、输入等)的方式和原生 JS 类似,但有语法差异:

    • 事件名用驼峰式(如 onClick 而非 onclick
    • 事件处理函数通过 {} 绑定(如 <button onClick={handleClick}>
    • 阻止默认行为需显式调用 e.preventDefault()(不能 return false)

    示例:

    jsx

    function handleInputChange(e) {console.log('输入内容:', e.target.value);
    }return <input type="text" onChange={handleInputChange} />;
    

3. 条件渲染与列表渲染

  • 条件渲染:根据数据判断显示不同内容(如登录 / 未登录状态)

    jsx

    {isLoggedIn ? <UserInfo /> : <LoginButton />}
    
  • 列表渲染:用 map 遍历数组生成组件,必须加 key 属性

    jsx

    const cats = [{ id: 1, name: '咪咪' }, { id: 2, name: '花花' }];return (<ul>{cats.map(cat => (<li key={cat.id}>{cat.name}</li> // key 用于 React 优化渲染))}</ul>
    );
    

4. 表单处理

  • React 中表单通常用 受控组件 模式:表单值由 state 管理,通过 onChange 同步更新

    jsx

    function CatForm() {const [name, setName] = useState('');return (<inputtype="text"value={name} // 受控于 stateonChange={(e) => setName(e.target.value)} // 同步更新 state/>);
    }
    

5. 组件通信进阶

  • 除了父子组件通过 props 通信,还有:
    • 子传父:父组件传一个函数给子组件,子组件调用该函数传递数据

      jsx

      // 父组件
      <Child onSendData={(data) => console.log('子组件传来的数据:', data)} />// 子组件
      function Child({ onSendData }) {return <button onClick={() => onSendData('hello')}>传数据</button>;
      }
      
    • 跨组件通信:用 Context API 或状态管理库(如 Redux、Zustand),解决多层级组件数据共享问题。

6. Hooks 扩展

  • 除了 useState 和 useEffect,还有很多实用 Hooks:
    • useContext:获取 Context 中的数据(跨组件通信)
    • useRef:获取 DOM 元素或存储不触发重渲染的数据
    • useReducer:复杂状态逻辑的管理(类似简化版 Redux)
    • 自定义 Hooks:封装可复用的逻辑(如 useLocalStorageuseFetch

7. 路由(React Router)

  • 单页应用(SPA)的页面跳转依赖路由库 react-router-dom,核心概念:
    • <BrowserRouter>:路由容器
    • <Route>:定义路径与组件的对应关系
    • <Link>:跳转链接(类似 <a> 标签,但不刷新页面)
    • useNavigate:编程式导航(如登录后跳转到首页)

这些概念都是从 “基础使用” 到 “实际开发” 的必经之路,不用急于一次性掌握。可以按照 “先会用核心功能(props/state/ 事件)→ 处理常见场景(表单 / 列表)→ 学习进阶特性(Hooks / 路由)” 的顺序逐步深入,遇到具体需求时再针对性学习,效率会更高~

8 忘记import导入usestate

(1)【忘记import导入usestate了,usestate是一个函数还是什么的,我粗浅的认知里面{}花括号包裹的是jsx的东西,到底是什么?】

你的问题涉及到两个核心点:useState 的本质,以及 JSX 中 {} 的作用。这俩其实是不同层面的概念,咱们拆开说清楚:

一、useState 是什么?—— 它是一个 React 提供的函数

useState 是 React 的 内置 Hook(钩子函数),作用是让函数组件拥有 “状态管理” 能力。它的本质就是一个函数,需要从 react 库中导入才能使用:

jsx

// 必须先导入才能用
import { useState } from 'react'; function MyComponent() {// 调用 useState 函数,初始化状态(比如这里的 count 初始为 0)const [count, setCount] = useState(0); return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

  • 它的返回值是一个数组,里面有两个元素:当前状态(比如 count)和更新状态的函数(比如 setCount)。
  • 之所以用 {} 包裹着导入(import { useState } from 'react'),是因为 useState 是 React 库导出的 命名导出(named export),必须用花括号指定要导入的具体名称。

二、JSX 中 {} 的作用 —— 插入 JavaScript 表达式

在 JSX 语法中(就是你写的 <div>...</div> 这种类似 HTML 的代码),{} 是一个 “开关”,用来告诉 React:这里面写的是 JavaScript 代码,需要执行后再渲染

比如:

jsx

function CatComponent({ catName, catAge }) {// 定义一个 JS 变量const isAdult = catAge >= 1; return (<div>{/* 1. 插入变量 */}<p>猫名:{catName}</p> {/* 2. 插入表达式(运算、三元判断等) */}<p>年龄:{catAge}岁,{isAdult ? '成年' : '幼猫'}</p> {/* 3. 插入函数调用结果 */}<p>下次生日:{new Date().getFullYear() + (1 - catAge % 1)}</p> </div>);
}

  • 注意{} 里只能放 表达式(有返回值的代码,比如变量、1+1fn()、三元运算等),不能放语句(比如 iffor 循环这种没有返回值的代码块)。
  • 这和导入时的 {} 完全不是一回事:导入时的 {} 是 ES6 模块语法的一部分,用来指定命名导出;JSX 里的 {} 是 React 语法的一部分,用来嵌入 JS 逻辑。

总结一下

  • useState 是 React 提供的 函数,必须用 import { useState } from 'react' 导入(这里的 {} 是模块导入语法)。
  • JSX 中的 {} 是 嵌入 JavaScript 表达式的语法,用来在 UI 中动态展示数据或执行简单逻辑。

刚开始可能会混淆这两种 {},但写多了就会发现:一个是 “导入时用的”,一个是 “写 UI 时用的”,场景完全不同,慢慢就会习惯啦~

(2)【hook钩子?哦我感觉有点像py那种,比如先要导入一个numpy模块,然后才可以用numpy模块里面的方法,是这样吗,然后这里的usestate是react库里面的一个方法函数,导入react库里面的函数就是这样的加一个{}的语法?。】

你的理解得非常对!这个类比很准确,确实抓住了核心逻辑:

  1. 和 Python 导入模块的类比
    就像 Python 中需要先 import numpy 才能用 numpy.array() 一样,React 中需要先导入 useState 才能使用它。

    • Python:from numpy import array(从 numpy 中导入 array 函数)
    • React:import { useState } from 'react'(从 react 中导入 useState 函数)

    这里的 {} 作用和 Python 的 from ... import ... 语法类似,都是从模块中精准导入某个具体的功能(函数、变量等),而不是导入整个模块。

  2. 为什么要用 {} 导入 useState
    因为 useState 是 React 库中的命名导出(named export)

    • React 库中同时存在两种导出方式:
      • 默认导出(default export):比如 React 本身,导入时不用 {},如 import React from 'react'
      • 命名导出:比如 useStateuseEffect 这些 Hooks,导入时必须用 {} 并指定准确名称,因为一个库可能有多个命名导出,需要明确告诉程序 “你要哪个”。
  3. Hook 本质就是 “React 库提供的函数”
    你可以把 useStateuseEffect 这些 Hook 理解为 React 内置的 “工具函数”,每个函数解决特定问题:

    • useState:专门用来管理组件状态的函数。
    • useEffect:专门用来处理组件副作用(如请求数据、定时器)的函数。

    它们和 Python 中 numpy 里的 arraypandas 里的 DataFrame 本质一样 —— 都是 “库提供的、拿来就能用的工具”,只是语法上因语言不同而有差异。

所以你的理解完全正确:导入 useState 就像导入 Python 模块里的特定方法,{} 是 JavaScript 中 “精准导入命名导出” 的语法,而 Hook 本身就是 React 库提供的实用函数。用多了之后,这种导入和使用方式会变得和 Python 一样自然~

9 有关花括号...

(1)【我前面也遇到了一个花括号{},就是这段代码里面包裹的cathappiness。

<div className="Profile-subContainer u-textCenter"> <h4 className="Profile-subTitle">Cat Happiness</h4> <CatHappiness catHappiness={catHappiness} />

</div>

//然后,我觉得这个地方是因为我导入的cathappiness是一个js文件吧,啊,到底是怎么详细的理解,js里面导js?】

这段地方的花括号 {} 和导入导出是两个不同的概念,咱们分两步拆解清楚:

一、先明确:CatHappiness 组件的导入逻辑(JS 文件之间的引用)

你提到的 “JS 里面导 JS” 是对的 ——React 项目中,组件通常放在单独的 JS/JSX 文件里,使用时需要先导入才能用,这和 Python 中 from xx import xx 引用其他模块的逻辑一致。

假设你的 CatHappiness 组件在 CatHappiness.js 中,并且用 export default 导出:

jsx

// CatHappiness.js
function CatHappiness({ catHappiness }) {return <div>{catHappiness}</div>;
}// 默认导出(default export)
export default CatHappiness;

那么在父组件(比如 Profile.js)中,需要先导入这个组件才能使用:

jsx

// Profile.js
// 从 CatHappiness.js 文件中导入默认导出的组件
import CatHappiness from './CatHappiness'; // 注意路径要写对// 然后才能在 JSX 中使用 <CatHappiness /> 标签
function Profile() {const catHappiness = 5;return (<div><CatHappiness catHappiness={catHappiness} /></div>);
}

这里的关键是:

  • 组件文件(CatHappiness.js)通过 export default 对外 “暴露” 组件。
  • 父组件文件(Profile.js)通过 import 把这个组件 “拿过来用”。
  • 这就是 “JS 导 JS” 的核心:模块化复用代码。

二、再看 catHappiness={catHappiness} 中的花括号:JSX 中嵌入变量

当你已经成功导入 CatHappiness 组件后,在使用时写的 <CatHappiness catHappiness={catHappiness} />,这里的 {catHappiness} 是另一个逻辑:

  • 等号左边的 catHappiness:是传递给子组件的 prop 名称(自定义的标签名)。
  • 等号右边的 {catHappiness}:这里的花括号是 JSX 语法,表示 “这里要插入一个 JavaScript 变量”。

这个 catHappiness 变量是父组件自己定义的(可能是普通变量或 state),比如:

jsx

function Profile() {// 父组件自己的变量const catHappiness = 80; // 普通变量// 或者是 state 变量:const [catHappiness, setCatHappiness] = useState(0);return (// 把父组件的 catHappiness 变量,通过 prop 传给子组件<CatHappiness catHappiness={catHappiness} />);
}

简单说:这个花括号的作用是 “告诉 React,把我父组件里的 catHappiness 变量的值取出来,传给子组件”。

总结两个核心点

  1. 组件的导入导出

    • CatHappiness.js 用 export default CatHappiness 导出组件。
    • 父组件用 import CatHappiness from './路径' 导入组件,这样才能在 JSX 中写 <CatHappiness /> 标签。
      这是 “JS 文件之间共享代码” 的方式。
  2. JSX 中的花括号 {}

    • 在 <CatHappiness catHappiness={catHappiness} /> 中,右边的 {catHappiness} 是为了嵌入父组件的变量,让子组件能拿到这个值。
      这是 “在 JSX 中插入 JavaScript 变量” 的语法。

两者的关系是:先通过导入导出让组件可用,再通过带花括号的 prop 传递数据 —— 前者是 “组件能用”,后者是 “组件能拿到数据”,缺一不可~

(2)【咋涉及到 JSX 语法了,不是js吗?】

你观察得很仔细!这里确实涉及到一个重要区别:JSX 是 JavaScript 的 “扩展语法”,它长得像 HTML,但本质上是 JavaScript 的一部分,专门用于在 React 中描述 UI。

具体来说:

  1. 纯 JavaScript(.js)文件可以包含 JSX
    虽然文件后缀是 .js,但 React 项目会通过工具(如 Babel)把 JSX 语法 “翻译” 成普通 JavaScript 代码。比如你写的 <CatHappiness />,最终会被转换成 React 函数调用:React.createElement(CatHappiness, ...)

    所以,你的 .js 文件里其实可以同时包含:

    • 普通 JavaScript 代码(变量、函数、import/export 等)
    • JSX 语法(类似 HTML 的标签,用于描述 UI)
  2. JSX 中的 {} 是它的专属语法
    在 JSX 里(也就是就是那些类似 HTML 的标签中),{} 是专门用来嵌入普通 JavaScript 代码的 “接口”。比如:

    jsx

    // 这是 JSX 语法(写在 return 后面的标签部分)
    return (<div>{/* 这里的 {catHappiness} 就是用 JSX 的 {} 嵌入变量 */}<CatHappiness catHappiness={catHappiness} /></div>
    );
    

    这个 {} 是 JSX 语法的一部分,和普通 JavaScript 里的对象字面量(如 { name: 'xxx' })完全不同。

  3. 一句话总结

    • 你的文件是 .js 文件,里面主要写的是 JavaScript 代码。
    • 但为了方便描述 UI,React 允许在 JavaScript 中使用 JSX 语法(类似 HTML 的标签)。
    • 在 JSX 标签里,用 {} 来 “打通” JSX 和普通 JavaScript(比如插入变量、表达式)。

简单说,JSX 就像是 JavaScript 的 “UI 方言”—— 它基于 JS,专门用来写界面,而 {} 就是这个方言里 “引用原生 JS 内容” 的语法。这也是 React 设计的巧妙之处:让你在同一个文件里既能写逻辑(JS),又能写界面(JSX)。

(3)【这样啊,那就是要看我具体编码是不是为了写ui吧,如果在js文件里面写ui就要讲“方言”jsx,也就涉及到了花括号的引入js模块的语法】

你的理解非常到位!可以这么简单归纳:

  • 当你在 .js 文件里写逻辑(比如定义变量、函数、处理数据)时,用的是纯 JavaScript 语法(比如 const a = 1function fn() {})。
  • 当你在 .js 文件里写 UI(比如组件的渲染内容,通常在 return 后面)时,用的是JSX 语法(类似 HTML 的标签,比如 <div>...</div>)。
  • 而 JSX 里的 {} 就是这个 “UI 方言” 的 “翻译器”—— 当你需要在 UI 中插入 JavaScript 逻辑(比如变量、表达式)时,就用 {} 把 JS 代码包起来,告诉 React:“这部分是纯 JS,帮我执行后再显示到 UI 里”。

举个直观的例子,同一个 .js 文件里的两种语法:

jsx

// 这里是纯 JavaScript 逻辑(定义变量、函数)
function CatProfile() {const catName = "咪咪"; // 纯 JS 变量const happiness = 90;   // 纯 JS 变量// 这里开始是 JSX(描述 UI),用了 JSX 语法return (<div className="cat-card">{/* 用 JSX 的 {} 插入纯 JS 变量 */}<h3>名字:{catName}</h3><p>幸福值:{happiness}</p>{/* 用 JSX 的 {} 插入 JS 表达式 */}<p>状态:{happiness > 80 ? "超开心" : "一般般"}</p></div>);
}

所以核心就是:写逻辑用纯 JS,写 UI 用 JSX 方言,{} 是两者的连接桥。用多了之后,你会自然区分什么时候用哪种语法,就像切换 “说话方式” 一样自然~

10 报错:Uncaught ReferenceError: props is not defined

这个错误通常是因为在子组件中使用了 props 但没有正确接收它导致的。具体有两种常见情况和解决方法:

情况 1:子组件没有声明 props 参数

如果你的子组件代码里直接用了 props.xxx,但函数参数里没写 props,就会报这个错。

错误示例

jsx

// 子组件 CatHappiness.js
function CatHappiness() { // 这里没写 props 参数return <div>{props.catHappiness}</div>; // 直接用 props 就会报错
}

解决方法:在函数参数里加上声明 props

jsx

function CatHappiness(props) { // 加上 props 参数return <div>{props.catHappiness}</div>; // 现在可以正常使用了
}

情况 2:用了解构赋值但写错了格式

如果你想用更简洁的解构语法({ catHappiness }),但不小心写成了 props 或漏了大括号,也会报错。

错误示例

jsx

// 错误写法1:用了解构却写了 props
function CatHappiness(props) {return <div>{catHappiness}</div>; // 没写 props. 也没解构,直接用变量会报错
}// 错误写法2:解构时漏了大括号
function CatHappiness(catHappiness) { // 应该是 { catHappiness }return <div>{catHappiness}</div>;
}

解决方法:正确使用解构赋值,在参数里用 { } 包裹需要的属性:

jsx

function CatHappiness({ catHappiness }) { // 正确解构return <div>{catHappiness}</div>; // 可以直接用变量
}

总结

核心问题是 “子组件没有正确接收父组件传来的 props”,解决步骤:

  1. 检查子组件的函数参数,确保有 props 或 { 需要的属性 }
  2. 使用时,要么用 props.属性名,要么直接用解构后的 属性名

按这两种方式修改后,props is not defined 的错误就会消失啦~

11 onClick是内置的写好的吗,是react库自己带的方法吗?

是的,onClick 是 React 内置的事件处理属性,属于 React 库本身提供的特性,专门用于处理点击事件。

它的特点和原理:

  1. React 封装的合成事件onClick 并不是原生 JavaScript 的 onclick 事件,而是 React 对原生事件进行的封装(称为 “合成事件”),目的是统一不同浏览器的事件行为,让事件处理在各种浏览器中表现一致。

  2. 语法规范:React 中所有事件属性都采用驼峰命名法(camelCase),所以是 onClick 而不是原生 HTML 的 onclick

  3. 使用方式:必须通过花括号 {} 绑定一个函数(事件处理函数),比如:

    jsx

    // 正确:绑定一个函数
    <button onClick={handleClick}>点击我</button>// 错误:直接写执行语句(会导致页面加载时就执行)
    <button onClick={handleClick()}>点击我</button>
    

简单说,onClick 是 React 为开发者提供的 “现成工具”,专门用来处理点击交互,不需要自己定义,直接按照 React 的规范使用即可。类似的还有 onChange(输入变化)、onSubmit(表单提交)等,都是 React 内置的事件处理属性。

12 React、Vue 以及 Angular 等

(1)【react应该就是js用于写website的一个库,那我有时候会看到的vue还有别的是什么意思,别的框架?框架是这么说的吗?】

你的理解很准确!React、Vue 以及 Angular 等,都属于前端 JavaScript 框架 / 库,它们的核心目标都是帮助开发者更高效地构建网页(website)或 web 应用,但在设计理念和使用方式上有所不同。

先明确两个概念:

  • 库(Library):更专注于解决特定问题(比如 React 核心专注于 “UI 渲染” 和 “组件化”),你可以按需引入,灵活控制使用范围。
  • 框架(Framework):提供了一整套 “完整解决方案”,规定了代码的组织方式、项目结构等,你需要按照框架的规则来写代码(比如 Vue 有更明确的模板语法和项目规范)。

不过日常交流中,大家常常会把 “库” 和 “框架” 混用,比如把 React 也称为 “框架”,不用太纠结字面区别,重点是它们的定位。

常见的前端框架 / 库及其特点:

  1. React(你正在学的)

    • 由 Facebook 开发,核心思想是 “组件化” 和 “声明式 UI”(用 JSX 描述 UI 应该是什么样,而不是怎么实现)。
    • 灵活性极高,没有严格规定项目结构,适合大型复杂应用(比如 Facebook、Instagram)。
    • 生态非常丰富,需要搭配路由(React Router)、状态管理(Redux 等)等库一起使用。
  2. Vue

    • 由尤雨溪开发,更注重 “易用性” 和 “渐进式”(可以一点点引入到项目中,不用一次性全用)。
    • 提供了更接近 HTML 的 “模板语法”(比如 <div>{{ message }}</div>),对新手更友好。
    • 内置了很多功能(比如状态管理、路由的官方解决方案),开箱即用的体验更好。
  3. Angular

    • 由 Google 开发,是一个 “全功能框架”,包含了从 UI 到数据处理的全套工具。
    • 基于 TypeScript(JS 的超集,带类型),适合大型团队协作和企业级应用。
    • 学习曲线较陡,规则比较多,但规范性强。
  4. 其他:比如 Svelte(编译时框架,性能极好)、Solid(类 React 但更轻量)等,各有侧重。

为什么会有这么多框架?

就像做蛋糕可以用不同的模具和方法 —— 有的模具适合做复杂造型(React),有的操作简单适合新手(Vue),有的自带全套工具(Angular)。它们都是为了解决原生 JS 开发网页时的痛点(比如代码混乱、复用性差、状态难管理等),只是思路不同。

对你的建议:

现阶段先专注学好 React,把它的核心概念(组件、props、state、Hooks 等)吃透。等你有了一定基础,再看其他框架时,会发现很多思想是相通的(比如组件化、状态管理),学起来会很快。

前端框架的选择更多看项目需求和团队习惯,掌握其中一个深入使用,足以应对大部分开发场景~

(2)【只不过都是js语法下的库而已,每个库都有自己的函数,有自己的方法,就是做蛋糕选模具哪个顺手用哪个,看各自的优点吧,应该相差不会很大,学会一个上手别的应该不会很难(我猜的】

你这个比喻和判断都特别准!确实是这样:

  1. 核心相通:所有这些框架 / 库都基于 JavaScript,共享 JS 的核心语法(变量、函数、对象、数组等)和 Web 基础(DOM、事件、HTTP 等)。就像不管用什么模具做蛋糕,面粉、鸡蛋这些基础原料是一样的。

  2. 差异是 “招式” 而非 “内功”:不同框架的 “独特语法”(比如 React 的 JSX、Vue 的模板指令、Angular 的装饰器)更像是不同的 “招式”,但解决的核心问题(组件复用、状态管理、UI 渲染)高度重合。比如:

    • React 的 props 和 Vue 的 “Props” 作用完全一样(父传子数据)
    • React 的 useState 和 Vue 的 ref/reactive 都是为了管理状态
    • 事件处理(点击、输入)的逻辑本质相同,只是写法略有差异(onClick vs @click
  3. 学会一个再学其他,会有 “降维感”:当你吃透 React 后,再看 Vue 会发现 “哦,这个功能 React 里是那么实现的,Vue 只是换了种写法”。很多开发者都是掌握一个框架后,再快速上手其他框架,因为底层逻辑是相通的。

  4. 选择看场景和习惯:就像做蛋糕,复杂造型可能需要特定模具(比如 React 适合大型应用),日常快手做可能选更简单的模具(比如 Vue 上手更快),但最终都能做出蛋糕。

所以完全不用怕 “学了这个还要重新学那个”—— 打好 JavaScript 基础和前端核心概念(组件、状态、事件等),任何框架都只是 “换个工具用” 而已。你现在深耕 React 的每一步,其实都在为未来触类旁通其他框架铺路~

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

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

相关文章

写作路上的迷茫与突破

曾经&#xff0c;我也是那个在写作面前踌躇不前的人。每次提笔&#xff0c;满心都是“我写不好”“我没什么可写的”“我达不到别人的高度”……这些念头像藤蔓一样&#xff0c;紧紧缠绕着我&#xff0c;让我寸步难行。我看着群里的小伙伴们一个个妙笔生花&#xff0c;自己却只…

23 Active Directory攻击与防护策略解析

引言 Active Directory&#xff08;AD&#xff09;是企业IT环境中用户认证、访问控制和身份管理的核心。因其掌握整个网络的"钥匙"&#xff0c;AD常成为攻击者的首要目标。 从凭证转储到隐蔽侦察&#xff0c;攻击者通过多种手段控制AD。无论您是网络安全分析师、红…

【内容规范】关于标题中【】标记的使用说明

【内容规范】关于标题中【】标记的使用说明 在信息爆炸的时代&#xff0c;如何让内容更易识别、更具条理性&#xff0c;成为内容创作者和平台运营者共同关注的问题。标题中【】标记的使用&#xff0c;正是在这种需求下形成的一种实用规范。 这种规范的核心作用在于建立统一的内…

centos 9 安装docker教程

拉取相关依赖 dnf -y install dnf-plugins-core设置阿里云镜像库 dnf config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plu…

关闭Jetbrains Mono字体连写、连字功能

所谓的关闭Jetbrains Mono字体连写&#xff0c;其实就是更换为Jetbrains Mono NL字体二者的区别就是符号间距的大小不同&#xff0c;也就是有无连字功能。 下图以Visutal Studio为例&#xff1a;

漫花软件集合分享

漫花软件集合分享的各种apk 1、磁盘漫画【推荐】 2、你搜 3、皮皮喵 4、泼辣漫画 5、趣漫画 6、异次元&图源 7、漫 8、再漫画X 9、章鱼漫画 10、芝士漫画&图源 通过网盘分享的文件&#xff1a;漫画软件 链接: https://pan.baidu.com/s/1dlGl50MNzzVOdTP38_…

DB-GPT 0.7.3 版本更新:支持Qwen3 Embedding和Reranker模型、支持知识库自定义检索策略等

V0.7.3版本主要新增、增强了以下核心特性 &#x1f340; 支持Qwen3 Embedding和Reranker模型 &#x1f340; 支持知识库自定义检索策略&#xff1a;语义检索、全文检索、树形检索、混合检索等 &#x1f340; 新增GaussDB数据源支持 &#x1f340; 支持GLM-4.1V多模态模型 …

Django常见模型字段

AutoField:数据库中的自动增长类型&#xff0c;相当于ID自动增长的IntegerField类型字段&#xff0c;对应mysql的Int类型 BooleanField:真/假的布尔类型字段&#xff0c;对应mysql的Tinyint类型 CharField:字符类型字段&#xff0c;对应mysql的varChar类型 DateField:日期字段&…

前端列表封面图如何自不同图片比例不变形

设置图片宽度100%时&#xff0c;若不设置高度&#xff0c;可能导致高度不足导致空白区域。如何实现图片高度自适应填充&#xff0c;避免空白区域&#xff1f;解决方式&#xff1a;加上height&#xff1a;100%&#xff1b;object-fit:cover&#xff1b;就可以始终剪切铺满&#…

记录一次Spring Cloud Gateway配置的跨域处理:解决 ‘Access-Control-Allow-Origin‘ 头包含多个值的问题

在微服务架构中&#xff0c;前端与后端分离已经成为一种常见模式。这种模式下&#xff0c;前后端通常会部署在不同的域名或端口上&#xff0c;这就导致了跨域资源共享&#xff08;CORS&#xff09;问题。最近&#xff0c;在我们的项目中&#xff0c;我们遇到了这样一个问题&…

扫雷游戏完整代码

扫雷游戏完整代码test.cgame.cgame.h

vue打包后如何在本地运行?

1.打包前的配置打开vue.config.js配置如图所示内容//打包配置文件 module.exports {assetsDir: static,parallel: false,publicPath: ./, };这段代码是Vue.js项目的打包配置文件&#xff0c;主要功能包括&#xff1a; - assetsDir: static - 设置静态资源文件夹名为static - p…

Python特性工厂函数详解:优雅管理属性验证

在Python中&#xff0c;特性(property)是一种强大的工具&#xff0c;它允许我们在访问属性时执行自定义逻辑。本文将深入分析一个名为quantity的特性工厂函数&#xff0c;它用于确保属性值必须为正数。 特性工厂函数的概念 特性工厂函数是一种创建并返回property对象的函数&…

Ubuntu系统VScode实现opencv(c++)鼠标操作与响应

在之前的创作中心-CSDN滚动条调整图片亮度-CSDN博客创作中心-CSDN中,我们已经了解了滚动条实现亮度以及对比度调节,为了实现对图像中感兴趣区域&#xff08;ROI, Region of Interest&#xff09;的交互式选取&#xff0c;本文利用 OpenCV 提供的鼠标事件回调机制&#xff0c;设…

True or False? 基于 BERT 学生数学问题误解检测

True or False? 基于 BERT 学生数学问题误解检测 代码详见&#xff1a;https://github.com/xiaozhou-alt/Student_Math_Misconception 文章目录True or False? 基于 BERT 学生数学问题误解检测一、项目介绍二、文件夹结构三、数据集介绍四、BERT 模型介绍五、项目实现1. 数据…

小程序基于vue+nodejs的私人定做订制订单发布与对应商品出售平台

文章目录项目介绍主要技术与实现手段具体实现截图关于我本系统开发思路研究思路、方法和步骤java类核心代码部分展示系统测试本系统技术可行性分析源码获取详细视频演示或者查看其他版本&#xff1a;文章底部获取博主联系方式&#xff01;项目介绍主要技术与实现手段 uni-app框…

为什么要有动态内存分配?

文章目录1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free3.calloc和realloc3.1 calloc3.2 realloc4.常见的动态内存的错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5 对…

docker hub 拉取镜像失败报Get “https://registry-1.docker.io/v2/“: net/http: request canceled while waiting

自己记录一把&#xff0c;给兄弟们避坑 1.上问题报错代码 [rootlocalhost ~]# docker pull hello-world Using default tag: latestError response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connectio…

Hive数仓部署/分层/ETL脚本基础指南

部署Hive数仓及分层基础指南 部署和构建一个Hive数仓涉及多个步骤&#xff0c;包括设置Hadoop集群、配置Hive、设计数据仓库架构以及实现ETL&#xff08;Extract, Transform, Load&#xff09;过程。下面是一个详细的指南&#xff0c;帮助你完成这些步骤。 1. 设置Hadoop集群 首…

深入 Go 底层原理(六):垃圾回收(GC)

1. 引言Go 语言自带垃圾回收&#xff08;Garbage Collection, GC&#xff09;&#xff0c;让开发者从手动管理内存的繁重任务中解脱出来。Go 的 GC 以其低延迟和并发性而闻名&#xff0c;其目标是在不长时间暂停&#xff08;Stop The World, STW&#xff09;整个程序的情况下完…