项目中遇到的问题
大纲链接 §
[toc]
推荐阅读 Vite真香之路 问题记录
pnpm add -g pnpm
安装路径提示错误 无法升级 The location of the currently running pnpm differs from the location where pnpm will be installed
⇧
复现
- 运行
pnpm add -g pnpm
- 会报如下错误:
|
|
解决
- 使用
npm install -g pnpm
参考
- mac The location of the currently running pnpm differs from the location where pnpm will be installed
- 安装pnpm
- pnpm中文
build
遇到报错 The service was stopped: write EPIPE
⇧
failed to load config from xxx\vite.config.ts error during build:
Error: The service was stopped: write EPIPE
- 重启服务即可 抽风,同端口号
3000
被占用- 管理员模式 打开终端 运行
net stop winnat && net start winnat
- 管理员模式 打开终端 运行
如何在生命周期中恰当地处理异步与异步传递数据
created
mounted
- 组件间传递数据
登录注册 错误时也跳转 ⇧
- 已解决 bug
解决 使用tsx语法 使用slot
插槽报错 [Vue warn]: Slot "default" invoked outside of the render function: this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.
⇧
- 请求先后
- 先获取总的数据 前一个生命周期
onBeforeMount
参考
- arco-design-vue issues Select组件不显示placeholder属性 #236
- Add a class to every child of a slot
- In Vue.js can a component detect when the slot content changes
ts 动态声明字符串模板变量类型 ⇧
|
|
样式设置了overflow-x: hidden;
导致了window.scrollTo
失效 ⇧
@/components/BlogBody.tsx
- 记录当前滚动位置
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- 记录初始/上一次滚动位置
oldScrollTop.value = scrollTop;
,初始为const oldScrollTop = ref(0);
- 记录对比当前和上一次滚动位置差值
const scrollStep = scrollTop - oldScrollTop.value;
scrollStep
为正 向下 隐藏导航栏;为负 向上 显示导航栏
|
|
@/components/Layout.tsx
|
|
@/styles/layout.module.scss
|
|
参考
- stackoverflow window.pageYOffset is always 0 with overflow-x: hidden
- stackoverflow overflow-x:hidden still can scroll
- window.pageYOffset is always 0 with overflow-x: hidden
- CSS Tricks How to Make an Unobtrusive Scroll-to-Top Button
- CSS深入理解之overflow 笔记
- Vue实现某个元素监听滚动条失效问题(scrollTop一直等于0 )
- 溢出 | overflow
- overflow Runebook.dev
- css笔记 - 张鑫旭css课程笔记之 overflow 篇
报错[Vue warn]: Unhandled error during execution of render function ref=Ref< undefined >
⇧
render()
函数中的数据在组件创建时,直接调用beautifyDate()
时还未初始化,导致报错- 解决方法:在调用异步方法
getBlogDetail()
内部,执行方法beautifyDate()
,并赋值给已定义的响应式数据createdAt.value
- 在
render()
函数中使用this.createdAt
而不是直接调用beautifyDate()
css modules
中如何使用 深入组件样式? ⇧
- 想使用jsx写法编写组件的时候,无法使用scoped这个用法
- 因为jsx等同于一个js文件,里面可写不了template与style标签
- tsx直接使用字符串
return <div class="test">
,会导致样式文件会挂载到全局的style标签上,且类名没有任何转译,这样就会容易造成样式污染 - 要覆盖子组件内部的元素样式
cover-ant.scss
|
|
在路由中使用 defineAsyncComponent
动态引入组件 ⇧
原来
@/router/index.ts
|
|
import('xxx')
必须是静态字符串,不可动态拼接- 否则报错
The above dynamic import cannot be analyzed by vite
改为使用
defineAsyncComponent
API
- 返回
promise
defineAsyncComponent(() => {return new Promise((resolve, reject) => {...})})
- 使用
import
函数作为返回值:defineAsyncComponent(() => (import('./components/MyComponent.vue')))
- vue3 Async Components
@/router/index.ts
|
|
- 使用
defineAsyncComponent
动态加载组件时,会出现警告
|
|
- 代替原来的静态引入
import BlogIndex from '@/pages/blog/index/BlogIndex';
- 直接动态引入
() => import('./MyPage.vue'))
@/router/index.ts
|
|
参考与相关类似问题 ⇧
- [Vue warn]: Failed to resolve component when tried to create global component stackoverflow
- Dynamically Import Vue Component Based On URL Params stackoverflow
- Invalid VNode type: undefined (undefined) - when used with
- Vue js import components dynamically
- Vue warn: Invalid VNode type: undefined (undefined)
报错[Vue warn]: Invalid VNode type: undefined (undefined)
⇧
- 识别不出节点的类型
- 是由于我在JSX中写了不合法的注释节点
{{/*xxxxx*/}}
自定义组件 JSX 事件 ⇧
使用自定义事件
- 要声明一个自定义事件:
onHandleSubmit
- 子组件
- 声明选项
emits: ['handleSubmit',],
- 在
setup
选项中传参setup(props, ctx) {}
- 定义 发布方法
const clickHandler = () => {ctx.emit('handleSubmit');}
- 返回
return {clickHandler}
- 定义 发布方法
- 在
render
方法中使用render() {return <button onClick={this.clickHandler}></button>}
- 声明选项
- 父组件
- 在
setup
选项中- 定义 处理逻辑的方法
const clickHandler = () => {}
- 定义 处理逻辑的方法
- 在
render
方法中使用自定义事件<UserSubmitBtnTip onHandleSubmit={this.clickHandler}/>
- 在
判断键盘抬起时,键盘值
- 自定义组件中有
<input/>
,事件keyup
不能绑定在自定义组件上,而是绑定在内部的的<input/>
上 - 通过
props
传一个keyUpHandler
到内部 - 无修饰符,只能使用
event: KeyboardEvent
中的event.key
来判断,是否按下Enter
键["Enter"].includes(event.key)
UserInput.tsx
|
|
Login.tsx
|
|
参考
- Vue JS - Conditional keyup.enter is not working stackoverflow
- JSX Introduction by facebook
- Using Vue 3 with JSX and TypeScript
- Lightweight Components with Vue 3 and JSX
- Programming VIP Vue-3 props, $emit, slot, render, JSX and createElement
- Vue3 Listening to Events
- Vue3 Declaring Emitted Events
- Emitting and Listening to Events
- How to emit event from JSX functional component in Vuejs
- 在vue3中编写jsx的两种方式
- vue中正确使用jsx语法的姿势分享1
- vue中正确使用jsx语法的姿势分享2
- 在vue中使用jsx的正确姿势3
- vue使用typeScript+jsx报错问题
JSX不支持在
setup
方法中写defineEmits
- 必须换成选项写法
emits: ['xxx', 'update:xxx']
vite2 jsx/tsx 写vue提示:React is not defined
⇧
🚑 解决引入 module 类型报错 ⇧
- vuex4.0中使用typescript, vuex4.0中modules的ts使用,vue3 + vuex4.0 + typescript 使用详情
- vuex4 中 typescript 的使用,以及 store 的一些坑
- Vue状态管理:使用Pinia代替Vuex坑
- 抛弃 Vuex,使用 Pinia
- 赋予Vuex 4.x 更好的 TypeScript体验
- vuex@4 + TypeScript
- Vuex4 对 TypeScript 并不友好,所以我选择 Pinia
- 如何在TypeScript中使用Vuex
pinia 遇坑 ⇧
- 报错
Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
- 在
router
中使用的例子,必须在钩子函数中声明const store = useStore()
,而不是在钩子外 - Pinia官网示例
- Pinia官网示例 Using a store outside of a component
- Pinia官网示例 Using the store outside of setup()
- github issue #666 I can’t use pinia outside of component setup
- stackoverflow Vue: Can’t access Pinia Store in beforeEnter vue-router
|
|
@at-root
使用css预处理器写css时缩小嵌套层级 ⇧
嵌套过深
- css是从右到左解析的,所以层数越多对于解析会越不利
- 后代选择器会增加样式权重,造成样式权重越来越高的恶性循环
- 滥用 less sass 的嵌套写法会让代码不易于阅读
别让你的嵌套层级超过四层,不然就重构
- 在Sass中还提供了一个
@at-root
的功能,可以让你直接跳出去。这样也可以避免嵌套层级过深 - 命名方式上可以解决,如:BEM
- 提取公用逻辑
@at-root
|
|
相似问题:前端路由多层级嵌套太深且重复的问题
使用引入的组件时报错TS2604: JSX element type 'XXX' does not have any construct or call signatures.
⇧
- 是因为组件未使用
defineComponent
|
|
改为以下示例,即可
|
|
网站搜索只能搜到react的相关内容
https://stackoverflow.com/questions/53449101/typescript-type-definition-ts2604-jsx-element-type-something-does-not-have-a | javascript - Typescript type definition: TS2604: JSX element type ‘something’ does not have any construct or call signatures - Stack Overflow https://segmentfault.com/q/1010000040209283 | 我想在.ts文件中使用JSX.Element对象,要怎么写。 - SegmentFault 思否 https://www.jianshu.com/p/ece127ffc996 | (转载)使用TS报错:TS7026: JSX element implicitly has type ‘any’…处理总结 - 简书 https://stackoverflow.com/questions/46080760/error-ts2604-jsx-element-type-does-not-have-any-construct-or-call-signatu | reactjs - Error TS2604: JSX element type ‘…’ does not have any construct or call signatures - Stack Overflow https://stackoverflow.com/questions/31815633/what-does-the-error-jsx-element-type-does-not-have-any-construct-or-call | reactjs - What does the error “JSX element type ‘…’ does not have any construct or call signatures” mean? - Stack Overflow https://stackoverflow.com/questions/54143658/typescript-ts2604-jsx-element-type-drawer-does-not-have-any-construct-or-call | reactjs - Typescript TS2604: JSX element type ‘Drawer’ does not have any construct or call signatures - Stack Overflow https://stackoverflow.com/questions/53452966/typescript-3-jsx-element-type-component-does-not-have-any-construct-or-call-s | javascript - TypeScript 3: JSX element type ‘Component’ does not have any construct or call signatures. [2604] - Stack Overflow https://stackoverflow.com/questions/34971155/typescript-error-ts2604-how-to-fix | reactjs - Typescript Error: TS2604 - How to fix? - Stack Overflow https://github.com/Microsoft/TypeScript-React-Starter/issues/44 | error TS2604: JSX element type ‘Provider’ does not have any construct or call signatures. · Issue #44 · microsoft/TypeScript-React-Starter https://www.imooc.com/wenda/detail/629578 | 用于从字符串创建 JSX 元素的正确 TypeScript 类型_慕课猿问
setup()
中写return () => (JsxDOM)
和在render() {return (JsxDOM)}
选项中写 ⇧
setup()
中会覆盖掉render() {return (JsxDOM)}
IDE
WebStorm
警告 在未导入 React 的情况下使用 JSX ⇧
- reactjs - 使用jsx不导入react
- 设置中关闭警告即可,React17+ 中无需再提示
- reactjs - React JSX 无需导入 React 即可工作
- 无需导入 React 即可使用 JSX
- 关于reactjs:使用JSX react / react-in-jsx-scope时,’React’必须在范围内?
- 不引入react的情况下使用JSX
- React17 使用 JSX 的情况下无须再显式导入 React
- 在没有导入的情况下使用JSX在React中显示图像
- React17 使用 JSX 的情况下无须再显式导入 React
- 拥抱 Vue 3 系列之 JSX 语法
- 在Vue中使用JSX的正确姿势
引入无props
的组件时,报错 ⇧
.tsx
文件
|
|
TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & (Partial<{ [x: number]: string; } | {}> & Omit<(readonly string[] | Readonly<ExtractPropTypes<Readonly<ComponentObjectPropsOptions<Data>>>>) & (VNodeProps & ... 2 more ... & Readonly<...>), never>)'. Type '{}' is not assignable to type 'IntrinsicAttributes & Partial<{}> & Omit<(readonly string[] | Readonly<ExtractPropTypes<Readonly<ComponentObjectPropsOptions<Data>>>>) & (VNodeProps & ... 2 more ... & Readonly<...>), never>'. Type '{}' is missing the following properties from type 'Omit<(readonly string[] | Readonly<ExtractPropTypes<Readonly<ComponentObjectPropsOptions<Data>>>>) & (VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>), never>': concat, indexOf, lastIndexOf, slice, and 17 more.
解决方法
- 添加
props
在tsx
文件中写点击事件绑定方法时<Button onClick={xxx}>...</Button>
报类型错误 ⇧
... is not assignable to type '(((event: MouseEvent) => void) & ((...args: any[]) => any)) | undefined'.
|
|
- 解决方法:
<Button onClick={()=> {popMessage && popMessage.error('这是一条错误消息', 2)}}>博客首页</Button>
- 必须再套一层箭头函数
Try just wrapping the event handler in a fat arrow function:
onClick={() => {addClient()}}
- 参考github issue: Mutation and TypeScript: Error when using onClick attribute with already declared interface
错误的范例
|
|
<a onClick={(event: MouseEvent) => emit('click-thumb', event)}>...
|
|
项目根目录不支持驼峰式命名 ⇧
- 使用短杠
-
连接
端口号3000
被占用 ⇧
- 重启
win10
或win11
的winnat
服务 - Open PowerShell as Admin.
- stop winnat with command:
net stop winnat
- start winnat again with command:
net start winnat
- Error when starting dev server permission denied 127.0.0.1:3000 vite issue
- 使用
netstat -aon| findstr 3000
找到对应进程 - 使用
taskkill /F /PID 8888
杀死对应进程
误删了.idea
文件 ⇧
.idea
文件时webStorm
项目的配置文件,删除会导致IDE
识别文件目录,和布局错误- 如果误删了
.idea
文件,可以点击文件菜单中的 修复IDE选项,根据事件日志中的提示,点选即可,重新加载项目目录
只用一种运行器 yarn
| pnpm
⇧
pnpm
为首选,一律使用pnpm
yarn
,混用时,yarn
依赖优先