news 2026/10/7 11:55:30

import 花括号什么时候加?关键看文件导出方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
import 花括号什么时候加?关键看文件导出方式

先给结论:import带不带花括号,跟 App.vue 本身没关系,也跟你导入的是不是工具函数没关系,只跟工具函数文件在导出时怎么写有关。文件用export default xxx导出,导入就不带花括号;文件用export function xxx、export const xxx这种命名导出,导入就必须带花括号。就这么简单。

但我知道,看到这句结论你心里可能还悬着一块石头:"那我经常看到同一个工具文件,有的人 import 带花括号,有的人不带,不也都跑通了吗?"这种情况确实存在,但大概率是因为那个文件同时提供了默认导出和命名导出。这一层绕不清楚,下次换一个文件,照样报错。下面我把原理、判断方法和踩坑经历完整捋一遍,这篇内容适合刚接触 Vite + Vue 3 的开发者,也适合那些项目能跑、却始终没搞懂为什么有时候加花括号有时候不加的人。

1. 第一次踩到 "Named export not found" 报错的完整现场

很多人在 App.vue 里遇到花括号问题,都是从一段莫名其妙的报错开始的。我先还原一下我见过无数次的场景。

1.1 报错现场还原

假设你的项目里有一个工具函数文件src/utils/index.js,里面是这么写的:

// src/utils/index.js export default { debounce(fn, wait) { let timer = null return function (...args) { clearTimeout(timer) timer = setTimeout(() => fn.apply(this, args), wait) } }, formatDate(date) { return date.toLocaleDateString('zh-CN') }, }

然后在App.vue里,你想用其中的debounce,很自然地写了:

<script setup> import { debounce, formatDate } from '@/utils' </script>

浏览器控制台立刻给你一句经典报错:

SyntaxError: The requested module '/src/utils/index.js' does not provide an export named 'debounce'.

如果你执行的是打包构建,Rollup 那边会换个说法:

RollupError: "debounce" is not exported by "src/utils/index.js".

1.2 这报错为什么格外反直觉

这个报错最让人懵的地方在于:debounce明明就在文件里啊!那个默认导出的对象里清清楚楚写着debounce(fn, wait),你凭什么说找不到?

问题就出在import { debounce }这个写法上。它看起来非常像"从一个对象里解构出 debounce 属性",既然对象里有这个属性,按说就应该能拿到。但 ES 模块的规则不是这样的:花括号导入不是对象解构,它是在按名字查找这个模块的"命名导出表"。

你回头看工具函数文件,里面只有一个export default { ... },也就是默认导出。整个文件没有出现过export const debounce = ...或export function debounce() {}这样的命名导出语句,所以模块的命名导出表里根本没有debounce这一项。哪怕默认导出对象里恰好带着debounce属性,那也只是一个叫default的出口里的一个字段,跟命名导出表是两回事。

这个区分的背后,就是 ES 模块本身的设计逻辑:一个模块可以向外开很多个"出口",每个出口都有名字;你import的时候,必须准确对应到某个出口的名字。下面把这两类出口彻底讲清楚。

2. 花括号的底层逻辑:JavaScript 模块的两种出口

在 ES Module 体系里,每个文件就是一个模块。文件里写的东西默认是私有的,别人想看,必须先export出去。而export一共就两种形态,对应到import就形成了"带不带花括号"的规则。

2.1 先学会从文件里认出两种出口

第一种是默认导出,语法是export default,一个文件最多只能有一个默认导出。它不要求有名字,可以导出一个函数、一个对象、一个类,什么都行:

export default function debounce(fn, wait) { // ... }

第二种是命名导出,语法是export加上一个带名字的声明。export function、export const、export class,或者export { a, b }都算。一个文件可以有无数个命名导出:

export function debounce(fn, wait) { // ... } export const formatDate = (date) => { // ... } // 也可以在文件最后统一导出 export { debounce, formatDate }

对应到import这边,规则就是:

文件导出写法导入写法说明
export default debounceimport debounce from './utils'不加花括号,接收的名字随便起:import anyName from './utils'也对
export function debounce() {}import { debounce } from './utils'加花括号,且名字必须和导出名字完全一致
export const formatDate = ...import { formatDate } from './utils'加花括号,名字严格匹配,大小写都不能错
export default { debounce, formatDate }import utils from './utils'默认导出的是整体对象,导入后用utils.debounce访问
同时有export default和export constimport utils, { formatDate } from './utils'语法上允许,见第 4 节场景 C

2.2 两种出口的行为差异

你可以把这两种出口想成两种取货方式。

默认导出像一个"前置服务台",你走过去说"把你们家的工具包给我",对方会直接递给你一整包东西。至于你给它起个什么名字——叫utils、叫myTools、甚至叫abc——服务台不关心,反正递过来的就是那个整体。所以import tools from './utils'和import anything from './utils'拿到的都是同一个默认导出。

命名导出则像"带名字的自助货架"。货架上的每件商品都贴着一个标签,你要拿货必须先报出准确的标签名:debounce就是debounce,写成Debounce或者debounce2都拿不到。系统找到标签后才会把那一件商品交给你。

所以在日常开发里,判断"该不该加花括号"最快的方法不是背语法,而是打开你要导入的那个文件,看一眼导出语句长什么样:看到export default就不加花括号,看到export function xxx或export const xxx就加花括号。看一次,记一辈子。

2.3 为什么import { debounce }不是对象解构

这一节是很多人一直绕不过去的心结。从长相来看,import { debounce, formatDate } from './utils'和语法上的解构赋值确实像:都是{ 变量名 }的形式。但它们的内核完全不同。

解构赋值是运行时行为,它的机制是"从目标对象的属性中取值",所以只要utils对象上有一个debounce属性,const { debounce } = utils就能成功,属性不存在的顶多得到一个undefined。

import { debounce }是编译期行为,它在模块加载时就要求模块的命名导出表里必须存在名为debounce的导出。注意,这里查的是"命名导出表",不是"默认导出对象的属性列表"。如果一个文件只有export default { debounce },那它的命名导出表是空的,debounce并没有出现在这张表里,于是报错。你可以理解为:import { x }是在问模块"你有没有一个名叫 x 的出口",而不是"你的 default 对象里有没有 x 这个属性"。

理解了这一层,以后再看到那种"明明对象里有这个函数,import { }却报错"的问题,就不会再被绕进去了。

3. 可以直接照抄的判断表与四步判断法

原理归原理,实际写代码时你不可能每次都翻文档。这里给一个闭着眼都能用的判断流程。

3.1 四步判断法

当你需要在 App.vue 里导入一个工具函数时:

  1. 打开工具函数文件,找到它的导出语句。
  2. 判断导出类型:如果是export default,走"不带花括号"分支;如果是export function/export const/export { ... },走"带花括号"分支;如果两种都有,两个分支都要用上。
  3. 命名导出时必须核对名字:函数名拼写、大小写、有没有下划线/驼峰,都要和导出语句完全一致。
  4. 导入后先确认调用方式:不带花括号导入的可能是一个对象或函数,带花括号导入的是那个具体的函数,两者的调用写法不同。

实际操作时,第 1 步最花时间,尤其是工具函数散落在不同目录的时候。但判断本身就这么简单,不需要记任何"高级规则"。

3.2 导出口写法与导入写法的完整对照表

下面这张表我建议直接收藏,写代码时拿不准了就看一眼。它覆盖了 Vue 项目里 90% 以上的工具函数导入场景。

工具函数文件写法App.vue 导入写法调用方式
export default debounceimport debounce from '@/utils'debounce(fn, 300)
export default { debounce, formatDate }import utils from '@/utils'utils.debounce(fn, 300)
export function debounce() {}import { debounce } from '@/utils'debounce(fn, 300)
export const formatDate = ...import { formatDate } from '@/utils'formatDate(new Date())
export { debounce, formatDate }import { debounce, formatDate } from '@/utils'分别调用两个函数
export default+export const混合import utils, { formatDate } from '@/utils'utils.debounce(...)+formatDate(...)

最后一行稍微特殊,下面第 4 节场景 C 会给出完整代码。

3.3 偷懒最高效的办法:让编辑器自动生成导入语句

如果你用的是 VSCode,装了 Vue 官方推荐的 Volar 插件,那还有一个更省事的办法:在 App.vue 里直接敲函数名,比如输入formatDate,然后按快捷键触发 Quick Fix,选择import formatDate from '@/utils'或者import { formatDate } from '@/utils',编辑器会自动判断该不该带花括号,并生成正确的导入语句。

这个办法对新手尤其友好。因为 IDE 读取的是工具函数文件的元数据,它知道那个模块到底用了哪种导出方式,生成的结果基本不会错。你可以先让 IDE 帮你写,再对照表格看一眼,几次下来自己就掌握规律了。我团队里带新人的时候,经常建议他们这么做,比自己对着报错猜要快得多。

4. App.vue 里工具函数导入的几种实际写法盘点

原理和判断方法都有了,接下来把 App.vue 里最常见的几种导入写法逐个拆一遍,每段都给可直接复制的代码。下面的示例统一以 Vue 3 的<script setup>为例,路径别名@/utils指向src/utils/index.js。

4.1 场景 A:工具文件全部命名导出(我最推荐的风格)

工具文件:

// src/utils/index.js export function debounce(fn, wait = 300) { let timer = null return function (...args) { clearTimeout(timer) timer = setTimeout(() => fn.apply(this, args), wait) } } export function formatDate(date) { return date.toLocaleDateString('zh-CN') }

App.vue:

<script setup> import { debounce, formatDate } from '@/utils' const handleSearch = debounce((keyword) => { console.log('搜索:', keyword) }, 500) const today = formatDate(new Date()) </script> <template> <input placeholder="输入关键词" @input="e => handleSearch(e.target.value)" /> <p>{{ today }}</p> </template>

命名导出 + 花括号导入的写法有两大好处:第一,import { debounce }能从代码上直接看出你用了哪些工具函数,不会把整个文件都拉进来;第二,多人协作时只要你遵守"命名导出"这一条,花括号问题就再也不会出现了。这也是我最终给团队定下的统一规范,原因会在第 6 节展开。

4.2 场景 B:工具文件默认导出一个对象

很多老项目或者工具库喜欢把一堆函数收进一个对象再默认导出去:

// src/utils/index.js const debounce = (fn, wait = 300) => { let timer = null return function (...args) { clearTimeout(timer) timer = setTimeout(() => fn.apply(this, args), wait) } } const formatDate = (date) => date.toLocaleDateString('zh-CN') export default { debounce, formatDate, }

对应的 App.vue 导入不能加花括号,而是要导入这个整体对象:

<script setup> import utils from '@/utils' const handleSearch = utils.debounce((keyword) => { console.log('搜索:', keyword) }, 500) const today = utils.formatDate(new Date()) </script> <template> <p>{{ today }}</p> </template>

这种方式在小型项目里很常见,因为确实方便:一个对象打包所有工具方法,导入后utils.xxx调用即可。但它的缺点是:如果你只需要其中一个函数,你仍然会把整个对象引进来,压缩和 tree-shaking 的效果都不如命名导出;而且你只能在导入后通过utils.访问,代码里到处是utils.前缀。

4.3 场景 C:默认导出与命名导出混合

有的工具文件会同时提供两种出口。比如默认导出的是整个工具对象,方便你import utils一把梭;同时又把某些常用函数额外命名导出一份,方便你按需引用:

// src/utils/index.js export function debounce(fn, wait = 300) { // ... } export function formatDate(date) { // ... } export default { debounce, formatDate, }

这时候 App.vue 就可以把两种导入写在同一行,用逗号隔开:

<script setup> import utils, { debounce } from '@/utils' // utils 是默认导出的整体对象 // { debounce } 是命名导出的独立函数 const a = utils.formatDate(new Date()) const b = debounce(() => {}, 300) </script>

这个写法看着花哨,实际只用在一个场景:你既想通过utils.formatDate使用整体对象里的方法,又想直接调用某个独立命名导出的函数。大多数情况下建议只用其中一种,没必要刻意混用,除非你在改一个历史遗留代码,那个文件已经被写成了混合导出。只要遇到了,记住语法是import utils, { debounce }就够了。

4.4 场景 D:导入后重命名,避免命名冲突

在 App.vue 里导入两个模块,两个模块恰好都导出了同名函数,这种情况很常见。比如你有一个本地工具函数formatDate,又装了date-fns,两边都有formatDate。花括号导入支持as关键字重命名:

<script setup> import { formatDate as localFormatDate } from '@/utils' import { formatDate as libFormatDate } from 'date-fns' const a = localFormatDate(new Date()) const b = libFormatDate(new Date(), 'yyyy-MM-dd') </script>

默认导出同样可以换名字:import whatever from '@/utils',名字随便起,本质上不影响使用。所以你可以把"不加花括号"的导入理解为"反正接的是默认出口,叫什么由你定"。

4.5 场景 E:一次导入整个模块的命名导出集合

还有一种写法是import * as utils from '@/utils',它会将目标模块的所有命名导出收集成一个 namespace 对象。很多人会把它和场景 B 搞混,但它俩不是一回事:

<script setup> import * as utils from '@/utils' // utils 是一个包含所有命名导出的对象 // 如果文件还有默认导出,它会挂到 utils.default 上 </script>

如果工具文件用的是命名导出:

export function debounce() {} export function formatDate() {}

那么import * as utils之后,调用方式是utils.debounce(...)、utils.formatDate(...)。如果工具文件用的是默认导出,import * as utils后你需要utils.default.debounce(...),这种调用方式相当别扭,实际项目里很少这么干。

所以我的建议是:import * as utils这种写法可以用来快速试探一个文件的导出结构,但不建议作为日常工具函数的导入方式。它把"这个文件有哪些导出"这个问题从编译期挪到了运行期,代码可读性和 IDE 提示都不如显式的import { xxx }。

4.6 App.vue 中两个容易被忽略的使用细节

细节一:如果你用的是 Vue 3 的<script setup>,import进来的函数直接就能在<template>里使用,不需要在<script>里再 return 一次。这一点非常多人踩坑——从 Vue 2 的 Options API 切过来时,大家习惯了在methods里包装函数,其实<script setup>会自动把顶层的绑定暴露给模板。

细节二:如果你还在用 Vue 2 或者 Vue 3 的 Options API 写法,import进来的函数不会出现在this上,也不能直接在模板里被引用。你必须先在methods或computed里做一层包装:

<script> import { formatDate } from '@/utils' export default { methods: { getToday() { return formatDate(new Date()) }, }, } </script> <template> <p>{{ getToday() }}</p> </template>

Options API 里直接写{{ formatDate(new Date()) }}是拿不到这个函数的,因为它的作用域只停留在<script>的模块顶层,不会自动挂到组件实例上。

5. 别被报错带偏:三类高频导入错误的完整排查链路

如果前面的规则都理解了,剩下的就是实战排错能力。这里梳理三类我在实际项目里见到频率最高的导入错误,每一条都按"现象 → 根因 → 修复"的顺序完整还原一遍。

5.1 错误一:导出方式与导入方式不匹配

现象:浏览器控制台报SyntaxError: The requested module does not provide an export named 'debounce',或者构建时报RollupError: "debounce" is not exported by ...。

根因:工具文件根本没有名为debounce的命名导出,它可能只有export default。你在导入时却用了import { debounce },于是模块在命名导出表里找不到这个出口。

排查链路:

  1. 点击报错信息里的模块路径,比如/src/utils/index.js,直接跳转到工具函数文件。
  2. 在文件里搜索export关键字,看清楚导出语句。
  3. 如果是export default {...},说明默认导出的只是一个整体对象,你需要改成import utils from '@/utils',然后通过utils.debounce调用。
  4. 如果你确实希望用import { debounce },那就得回头修改工具函数文件,把export default {...}改成单独的export function debounce() {}。

同样的排查流程也适用于反向场景:工具文件明明是export function debounce() {},你却写成了import debounce from '@/utils'。这时报错通常是Missing default export或者"default" is not exported by ...,本质上还是导出类型不匹配。

5.2 错误二:名字拼写或大小写不一致

现象:报错信息里明确说找不到某个名字,比如'formatDate',但你打开文件一看,文件里明明写着export const formatDate = ...。

根因:命名导入对"名字的一致性"要求极其严格,拼写、大小写、下划线风格有任何偏差都不行。formatDate和FormatDate是两个完全不同的导出名字。这种错误在中文开发者里非常常见,因为从拼音/中文描述切换到英文驼峰时很容易手滑。

排查链路:

  1. 对比报错信息中的导出名和工具文件里的导出名,一个字符都不要放过。
  2. 特别注意formatDate和formatdate、debounce和deBounce这种细微差别。
  3. 最快的修复办法是删掉手写的导入语句,在 App.vue 里直接用函数名,触发 VSCode 的自动导入,让 IDE 生成准确的命名。

这类错误不会造成任何运行时的歧义,ES 模块的静态分析机制会在加载阶段就直接拦住,所以只要你一个字一个字地核对,基本都能快速解决。

5.3 错误三:把模块对象当成函数直接调用

现象:控制台报TypeError: utils is not a function,或者TypeError: utils.debounce is not a function。

根因:这类错误本质上是"导入写法与调用方式不匹配"的另一种表现。比如你写了import utils from '@/utils',但工具文件其实是用命名导出写的,没有默认导出,这时utils可能是undefined或整个模块的 namespace 对象;又比如你写了import * as utils from '@/utils',却直接调用utils(),完全忘了它是一个容器对象而不是函数本身。

排查链路:

  1. 打印一下导入结果:console.log(utils),看看它到底是函数、对象还是 undefined。
  2. 如果是undefined或报Missing default export,说明你用了"不带花括号"的方式想拿默认导出,但文件只有命名导出。
  3. 如果是对象,看看Object.keys(utils)里有没有你要的函数名。
  4. 修复方式分两种:想要整体对象,就确认工具文件有export default;想要具体函数,就改成import { debounce }。

下面的表格把这三种错误的特征汇总起来,方便排查时快速对照:

报错信息大概率原因排查切入点修复方向
does not provide an export named 'xxx'文件没有xxx这个命名导出打开文件找 export调整导入方式或补充命名导出
Missing default export文件没有默认导出,却用了不带花括号的导入查找文件是否有export default改为import { xxx }或补默认导出
xxx is not a function把模块对象当成了函数调用console.log(xxx)看类型改为xxx.yyy()或改导入方式

5.4 一个容易误解的补充:旧项目里 CommonJS 风格的工具文件

如果你在维护一个老项目,工具函数文件可能是 CommonJS 风格的module.exports = { debounce, formatDate }。这种文件在 Vite 和 webpack 下,import行为会因为打包器的 interop 处理变得不太一样:有可能import utils from './utils'能拿到整个 exports 对象,也有可能import { debounce }也能工作。但这套行为是打包器"额外照顾"出来的,不是 ES 模块的原生语义。

我的建议很明确:新写的工具函数文件一律用原生 ESM 语法(export/export default),不要混用module.exports。混用会导致"为什么别人能跑我不能跑"的玄学问题,排查起来非常痛苦。老文件如果已经在跑就别动它,新文件从第一天就按原生 ESM 规范来写。

6. 踩过坑之后,我给团队定的工具函数导出规范

花括号的问题本身不大,但它折射出来的问题是:一个项目里如果没有统一的模块导出规范,每个文件都在凭习惯乱写,那么"加不加花括号"这种低级问题就会反复消耗所有人的精力。我在带团队时,把工具函数文件的导出方式统一成了"全命名导出,禁止默认导出一个对象"。理由如下。

6.1 为什么选择"命名导出"而不是"默认导出一个对象"

第一,命名导出对 tree-shaking 最友好。当你只import { debounce }时,Rollup / Vite 可以很明确地知道你没有用到formatDate,构建时就能把没用的代码摇掉。而默认导出一个对象时,整个对象是一个整体,工具函数越多,打包产物体积越不可控。

第二,命名导出让"引用了什么"一目了然。看一个 Vue 文件的导入语句,就能知道它依赖了哪几个工具函数;改成默认导出对象后,所有地方都是import utils from '@/utils',你根本看不出这个组件用了utils里的哪些方法。

第三,命名导出能从根本上消灭"花括号到底加不加"的问题。因为全项目工具函数统一用export function和export const,那么导入时永远都是import { xxx },不需要再做判断。新同事上手也只需要记住一条规则:"工具函数导入,永远带花括号。"

第四,默认导出一个对象还有一个隐性麻烦:对象里某个函数在调试时,报错堆栈显示的往往是(0 , _utils.debounce)(...)这种经过编译处理的调用形态,不如直接import { debounce }后调用的堆栈干净。

6.2 规范的例外情况

前面的规范只针对工具函数文件。项目里另外两类文件天然适合默认导出,不要一刀切:一是.vue单文件组件本身,Vue 的组件导入要求默认导出一个组件对象;二是路由配置文件、入口文件这种"一个文件只导出一个东西"的场景,用默认导出反而更自然。

所以规范的准确说法是:**在src/utils/和src/api/这类"函数集合型"文件里,统一使用命名导出,不用默认导出一个对象。**Vue 组件文件不在此列。

6.3 迁移成本和最终建议

如果你手头的老项目里工具函数已经大量使用export default导出一整个对象,我不建议为了规范而一次性重写所有文件。这种改动看起来机械,实际容易引入细小的调用错误,测试不全就会挂。比较稳妥的做法是:

  1. 老文件继续保留默认导出,调用处也继续用import utils from '@/utils'。
  2. 新增工具函数一律写在新文件里,并且使用命名导出,新文件不再提供默认导出。
  3. 等某个老文件/老模块需要大改时,顺手把它的导出方式转换成命名导出,同时通过 IDE 的全局搜索替换更新引用。

这样既不需要大动干戈,又让项目朝着一个更健康的方向演进。规范的目的不是让你立刻推翻所有旧代码,而是让未来的代码不再产生新的混乱。

最后再说一个实操小技巧:在 VSCode 里把鼠标悬停在导入的名字上,或者按 F12 跳转到定义,就能直接看到这个函数在源文件里是怎么导出的。下次再有人问你"App.vue 里 import 工具函数到底什么时候加花括号",你都不用解释,让他自己打开文件看一眼export后面跟的是什么,答案立刻就出来了。这个让人头疼的语法细节,解决过一次就是永久解决,之后写任何 JavaScript 项目都不会再被它绊住。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 11:52:34

AI做PPT新范式:A+B模式实战,从内容脚本到视觉生成全流程

做PPT这件事&#xff0c;几乎每个职场人都绕不开。我见过太多人打开空白幻灯片就开始一页一页地堆文字&#xff0c;也见过有人花三天时间调一个动画效果&#xff0c;结果汇报时投影仪分辨率不兼容&#xff0c;白忙一场。最近半年&#xff0c;AI工具的爆发让PPT制作这件事有了全…

作者头像 李华
网站建设 2026/10/7 11:52:23

微电网多目标优化的MOJS算法MATLAB实现与工程实践

微电网多目标优化这个方向&#xff0c;最近几年在电力系统调度里火得很。很多人一上来就问我用什么算法好&#xff0c;我的回答通常不是NSGA-II就是MOPSO&#xff0c;但如果你愿意多试一种思路&#xff0c;多目标水母搜索算法&#xff08;Multi-objective Jellyfish Search, MO…

作者头像 李华
网站建设 2026/10/7 11:51:40

DeepSeek Harness:面向Mod Engineering的AI工程化基础设施

1. 项目概述&#xff1a;DeepSeek Harness不是“又一个IDE插件”&#xff0c;而是开发者工作流的底层重构太卷了——这句感叹背后&#xff0c;是开发者对工具链进化速度的真实体感。当别人还在调试上一个版本的本地大模型接入方案时&#xff0c;DeepSeek团队在春节假期刚过就发…

作者头像 李华
网站建设 2026/10/7 11:51:34

从Selenium到Playwright:Web自动化测试迁移实战指南

1. 为什么要换掉 Selenium&#xff1a;一场测试工具的更替逻辑1.1 Selenium 最让人头疼的三件事先亮个底。我在 Web 自动化测试这条路上走了差不多六年&#xff0c;前四年基本都耗在 Selenium 上。不是说 Selenium 不好——它底子扎实、生态庞大、文档全&#xff0c;到今天依然…

作者头像 李华
网站建设 2026/10/7 11:51:06

DeepSeek Harness v0.2:Agent运行时与技能沙箱实战指南

1. 这不是又一个“AI桌面壳”&#xff0c;而是开发者手里的Agent调度中枢 DeepSeek Harness v0.2 桌面应用发布那天&#xff0c;我正用它在离线局域网里跑一个本地知识库问答插件——没有联网、没有云API调用、连公司防火墙都懒得放行&#xff0c;但整个Agent工作流照常启动&am…

作者头像 李华
网站建设 2026/10/7 11:50:37

从传统产品经理到AI产品经理:转型硬技能与实战路径全攻略

从产品经理到型AI产品经理&#xff1a;转型全攻略&#xff08;建议收藏&#xff09;先说个我观察到的现象&#xff1a;最近半年&#xff0c;我身边做传统产品经理的朋友&#xff0c;没有一个不在琢磨AI。有些人偷偷报班学提示词工程&#xff0c;有人天天刷大模型榜单&#xff0…

作者头像 李华