一、问题汇总
1.控制台中报错 Hydration node mismatch: - Client vnode: div - Server rendered DOM
该问题其实是由于在开发阶段本地服务器的代码与浏览器的代码不一致导致的问题,可以执行一次 build
命令,可以解决该问题,实际到部署之后并未复现该问题。
2.Nuxt3+Vue3 + Element-plus 打包后报错 @popperjs/core
问题:
更新 Element-plus 后,运行时需要安装 @popperjs/core
依赖。
如果正常执行 npm install @popperjs/core
,那么,打包时,就会出现下面报错。
解决:
把 node_modules
删除,在 package.json
把 @popperjs/core
版本号改为 "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7"
(esm 的包)重新 npm install
,即可。
3.npm i 报错
PS C:\Users\Administrator\Desktop\nuxt3-blog> npm i @nuxtjs/composition-api@0.34.0
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: nuxt-app@1.0.0
npm error Found: nuxt@3.15.4
npm error node_modules/nuxt
npm error dev nuxt@"^3.15.4" from the root project
npm error
npm error Could not resolve dependency:
npm error peer nuxt@"^2.17.3" from @nuxtjs/composition-api@0.34.0
npm error node_modules/@nuxtjs/composition-api
npm error @nuxtjs/composition-api@"0.34.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
原因:
这个错误是由于你正在尝试安装的 @nuxtjs/composition-api@0.34.0
版本与当前的 nuxt@3.15.4
版本不兼容。@nuxtjs/composition-api
需要 nuxt@^2.17.3
,而你使用的是 Nuxt 3
。
要解决这个问题,你有以下几种选择:
升级到
Nuxt 3
的Composition API
:Nuxt 3
已经内置了Composition API
,因此不需要单独安装@nuxtjs/composition-api
。你可以直接使用Nuxt 3
的Composition API
功能。降级
Nuxt
版本:如果你必须使用@nuxtjs/composition-api
,你可以考虑将Nuxt
降级到2.x
版本,但这可能不适合你的项目。
4.控制台中报错 Deprecation Warning [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
20 │ @import "./global.scss";
│ ^^^^^^^^^^^^^^^
╵
src\assets\css\theme\common.scss 20:9 @import
src\assets\css\global-common.scss 23:9 @use
src\components\outline.vue 1:1 root stylesheet
Deprecation Warning [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
More info and automated migrator: https://sass-lang.com/d/import
这个警告是由于你在使用 Sass
时使用了 @import
语句,而 @import
在 Dart Sass 3.0.0 中将被弃用。建议你使用 @use
和 @forward
来替代 @import
。这样可以提升代码的模块化和可维护性。
以下是如何进行迁移的基本步骤:
- 使用
@use
替代@import
:
如果你有一个文件 global.scss
,你可以在需要引入的地方使用 @use
语句。例如:
// 原来的写法
@import "./global.scss";
// 替换为
@use "./global.scss";
- 调整命名空间:
使用 @use
时,所有引入的样式都会被放入一个命名空间中。你可以通过指定命名空间来使用这些样式。例如:
// 使用命名空间
@use "./global.scss" as *; // 将所有样式引入当前作用域
- 更新引用:
如果你的 global.scss
文件中有变量、混合宏或函数等,你需要在使用它们时加上命名空间,除非你使用 as *
。
- 检查项目中的所有
@import
:
确保你的项目中没有其他地方使用 @import
,并将其全部替换为 @use
或 @forward
。
warning:
@use rules must be written before any other rules.
使用@use 时,所有的@use 规则必须写在其他规则之前。
更多关于如何迁移的信息可以参考 Sass 官方文档。这样可以确保你的代码在未来的版本中不会因为弃用而出现问题。
5.解决 navigator.mediaDevices
报错问题
背景:
项目中使用电脑摄像头拍照,调用 navigator.mediaDevices
方法,报错。
原因:
navigator.mediaDevices
在目前以下情况中可以正常获取到
- 地址为
localhost://
访问 - 协议为
https
- 为文件访问
file://
测试环境和生产环境使用的都是 http
协议,因此无法调用
解决方法:
- 本地使用
localhost://
访问 - 线上采用
https
方案
6.提示new dependencies optimized
具体如下:
下午7:01:09 [vite] ✨ new dependencies optimized: element-plus/es/components/message-box/style/index
下午7:01:09 [vite] ✨ optimized dependencies changed. reloading
下午7:01:23 [vite] ✨ new dependencies optimized: element-plus/es/components/form/style/index
下午7:03:57 [vite] vite.config.ts changed, restarting server...
new dependencies optimized
信息通常出现在使用 Vite 进行项目开发时,表示 Vite 正在优化新的依赖项。
背景信息:
Vite
是一个现代化的前端构建工具,它利用浏览器原生支持的 ES 模块功能,实现了快速的冷启动和即时模块热更新。Vite
通过按需加载模块,避免了传统构建工具如 Webpack
在启动时需要加载所有模块的缺点,从而提高了开发效率。然而,按需加载也带来了一些问题,例如在开发过程中可能会看到大量的依赖项被优化,导致页面频繁重新加载
具体表现:
在开发过程中,当Vite
检测到新的依赖项时,会在控制台输出new dependencies optimized
的信息。例如,当使用Element-Plus
组件库时,Vite
会优化这些依赖项,并在控制台显示相关信息,如new dependencies optimized: element-plus/es/components/divider/style/css
。这些信息表明Vite
正在处理新的依赖项,并进行优化
优化方法:
为了减少new dependencies optimized
信息的出现频率,可以尝试以下优化方法:
全局加载组件:在开发环境下,可以暂时全局加载组件,避免按需加载带来的频繁重新加载问题。在打包时再执行按需加载。
优化
Vite
配置:可以通过修改vite.config.ts
文件,包含更多的依赖项路径,减少优化时的重新加载次数。例如,可以通过fs
模块遍历node_modules/element-plus/es/components
目录,将所有相关的依赖项包含进优化配置中。
具体代码如下:
// vite.config.ts
// 需要引入fs
import { defineConfig, loadEnv } from "vite";
import { resolve } from "path";
import fs from "fs";
export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) }; //生成包括自定义的环境变量
//解决optimized dependencies changed. reloading
const optimizeDepsElementPlusIncludes: Array<string> = ["element-plus/es"];
if (process.env.VITE_ENV === "development") {
fs.readdirSync("node_modules/element-plus/es/components").map((dirname) => {
fs.access(
`node_modules/element-plus/es/components/${dirname}/style/css.mjs`,
(err) => {
if (!err) {
optimizeDepsElementPlusIncludes.push(
`element-plus/es/components/${dirname}/style/css`
);
}
}
);
});
}
return defineConfig({
optimizeDeps: {
include: optimizeDepsElementPlusIncludes,
// exclude: ["element-plus"],//反向使用,更简单
},
});
};
更多查看:
7.linux 修改环境变量后需要重启吗
在 Linux
系统中,修改环境变量通常不需要重启。环境变量是一种用于存储系统配置信息的变量,它们控制着系统的行为和应用程序的执行方式。当你修改了环境变量,系统会立即生效,无需重启。
当你修改环境变量时,系统会在当前会话中立即使用新的值。这意味着你可以立即在终端中使用新的环境变量设置,而不需要重新启动系统。
需要注意的是,修改环境变量只会在当前会话中生效。如果你希望新的环境变量设置在所有会话中都生效,你需要将其添加到适当的配置文件中。
在大多数 Linux
发行版中,常见的配置文件是~/.bashrc
或~/.bash_profile
(对于个人用户)以及/etc/profile
或/etc/environment
(对于系统级用户)。你可以使用文本编辑器打开这些文件,并在其中添加或修改环境变量的设置。
在修改配置文件后,你需要重新加载配置文件或重新启动终端,以使新的环境变量设置生效。你可以使用以下命令来重新加载配置文件:
#修改profile
source /etc/profile
#修改.bashrc
source ~/.bashrc
#或者使用以下命令重新启动终端:
exec bash
这样,新的环境变量设置将在所有终端会话中生效。
二、知识汇总
1.vite build 和 preview 区别
Vite
是一个现代化的前端构建工具,它提供了快速的开发服务器和热更新功能,以及高效的生产环境构建。在 Vite
中,vite build
和 vite preview
是两个常用的命令,它们各自有不同的功能和用途。
1.vite build
vite build
命令用于为生产环境构建项目。当你准备好将你的项目部署到生产环境时,你会使用这个命令。它会执行以下操作:
编译和优化:Vite
会使用 Esbuild
或其他工具来编译和优化你的代码,包括 JavaScript
、CSS
、图片等资源。
生成输出:编译后的文件会被输出到一个指定的目录(通常是 /dist
),这些文件是优化过的,适合在生产环境中使用。
代码分割:Vite
会根据你的代码依赖关系进行代码分割,以减少初始加载时间并提高性能。
2.vite preview
vite preview
命令用于本地预览生产构建产物。在你使用 vite build
命令生成了生产环境的构建产物后,你可以使用 vite preview
命令来启动一个本地服务器,该服务器会从 /dist
目录提供预览服务。这允许你在将项目部署到生产环境之前,在本地预览构建后的效果。
使用 vite preview
的好处包括:
快速预览:无需将构建产物上传到远程服务器,即可在本地快速预览。
模拟生产环境:由于 vite preview
使用的是生产环境的构建产物,因此它可以模拟生产环境的加载速度和性能。
方便调试:在预览过程中,如果发现任何问题或需要调整的地方,你可以立即回到开发环境进行修改,然后重新构建和预览。
3.总结
vite build
:用于为生产环境构建项目,生成优化后的代码和资源。vite preview
:用于本地预览生产构建产物,允许在部署前在本地查看构建后的效果。
在使用这两个命令时,请确保你已经安装了 Vite
并正确配置了项目。同时,注意在生产环境中部署时,可能需要额外的配置和步骤来确保项目的安全和性能。
2.SSR
模式下存在 2 种打包方式
nuxt.js
是vue SSR
框架。SSR
给前端带来的主要受益在于更快的首页加载和SEO
友好。
Nuxt.js
支持 SPA
,但主要以 SSR
模式为主。
SSR
模式下存在 2 种打包方式,分别是 npm run build
和 npm run generate
。那这 2 种打包有何区别?
1.build
一般情况下,build
打包用的更多。build
打包生成的 .nuxt
文件,发布时,需要拷贝 node_modules
等文件/文件夹,一般使用 node.js
环境下的 pm2
运行发布。
需要注意:
build
模式下发包发布,发布时需要将.nuxt
、static
、node_modules
等文件夹,以及package.json
、nuxt.config.js
等文件拷贝出来,使用pm2
启动运行发布。
2.generate
generate
打包用于将首页静态化(首页的 nuxt-link
也会被静态化),打包后生成 dist
文件夹(类似于 vue
一般性打包)。发布时,只需要将 dist
文件夹发布即可(同 vue
项目发布)。
需要注意:
- 当首页内容发生变化时,需要重新
generate
打包发布 - 打包生成的文件仍需要容器(如 Nginx)部署方可正常访问
- 打包过程中需要访问
API
后台获取数据
3.sass 和 node-sass 的区别
sass
和 node-sass
都是用于编译 Sass
(一种流行的 CSS
预处理器)到 CSS
的库,但它们有一些关键区别。
1. 实现
node-sass
:node-sass
是 LibSass(Sass
的C/C++
实现)的Node.js
绑定。- 因为是用
C/C++
编写的,所以通常编译和运行速度都很快。 - 可能会遇到平台相关的问题,特别是在安装和构建时。
sass
(也称为Dart Sass
):Dart Sass
是Sass
的官方Dart
实现。- 从
node-sass
切换到Dart Sass
通常只需改变安装的包名。 Dart Sass
的目的是完全符合Sass
的原始语法,并成为所有未来开发的首选版本。
2. 兼容性
node-sass
:- 可能不会总是与
Sass
的最新特性保持同步。 - 在某些系统上可能会遇到编译问题。
- 可能不会总是与
sass
:- 由于它是官方维护的版本,所以通常会更快地支持新特性和修复错误。
- 作为纯
JavaScript
包,兼容性通常更好。
3. 维护状态
node-sass
:- 自 2020 年后,
node-sass
的维护已逐渐减少。 - 社区可能会继续支持,但官方推荐使用
Dart Sass
。
- 自 2020 年后,
sass
:- 作为官方版本,持续得到维护和更新。
4.总结
如果你正在开始一个新项目或考虑迁移现有项目,推荐使用 sass
(Dart Sass
),因为它是官方维护的版本,并且在兼容性和未来特性支持方面可能会更可靠。如果你的项目已经使用了 node-sass
并且没有遇到问题,那么迁移可能不是必需的,但仍然值得考虑,特别是如果你想要利用 Sass
的最新特性。
sass-loader
: 这是一个Webpack
加载器,用于将Sass
语言编写的样式文件编译成CSS
文件。
Nuxt
会按照约定,带有 .client
后缀的文件,会被设置成在客户端渲染。比如 elment-plus.ts
和 element-plus.client.ts
Nuxt3
默认首屏 SSR
,由服务端渲染,可以通过配置 ssr:false
来取消服务端渲染。
// nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
// ssr:false, //页面全部为客户端渲染
routerRules: {
// 指定路由页面为客户端渲染
"/home": {
ssr: false,
},
},
});
根据 vue
的声明周期,只有 setup
、 beforeCreate
、 Created
里的内容会在服务端执行,所以如果是首屏服务端渲染时,需要将获取数据方法写到这几个生命周期之中
Nuxt3
有封装好的 $fetch
方法做数据请求,可以不需要引入第三方 axios
或者 fetch
做数据请求,否则可能会出现多个请求数据混乱问题。
4.使用字体
将本地字体文件放在 ~/public/
目录中,例如~/public/fonts
。然后可以在样式表中使用 url()
引用它们。
@font-face {
font-family: "FarAwayGalaxy";
src: url("/fonts/FarAwayGalaxy.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: swap;
}
项目中使用@keyframes
无效的问题,
样式本身是行内模式,即不是display: block;
或inline-block
或display: flex;
或是给父盒子添加一个一个display: flex;
nuxt3
里不能直接用 window
、document
这种客户端的 api
,在使用前,要用 process.client||process.server
来判断环境,否则会报错。
if (process.client) {
window.localStorage.getItem("test");
}
5.前端开发中的页面渲染与页面水合有何不同
页面渲染和页面水合是前端开发中的两个重要概念,它们在实现页面的动态性和交互性上有一定的区别。
页面渲染是指将 HTML
、CSS
和 JavaScript
代码转换为可见的网页的过程。在这个过程中,浏览器接收到服务器发送的 HTML
文件后,会解析并执行其中的 JavaScript
代码,同时应用 CSS
样式,最终生成用户可以看到的页面。这个过程是由浏览器完成的,因此也被称为客户端渲染(Client-side Rendering
,CSR)。
页面水合(也称为页面 hydration
)则是指将服务器端渲染(Server-side Rendering
,SSR)的 HTML
发送到客户端后,通过 JavaScript
代码将静态的 HTML
转换为具有交互性和动态性的页面的过程。在这个过程中,客户端接收到服务器发送的 HTML
文件后,会通过 JavaScript
代码注入到页面中,从而添加交互性和其他动态功能。这个过程是由 JavaScript
代码完成的,因此也被称为页面水合。
总的来说,页面渲染和页面水合的主要区别在于:页面渲染是由浏览器解析 HTML
、CSS
和 JavaScript
代码并生成可见的页面,而页面水合是由 JavaScript
代码将静态的 HTML
转换为具有交互性和动态性的页面。
6.useFetch
1.参数
URL
:要获取的 URL。Options
(扩展自unjs/ofetch
选项和AsyncDataOptions
):method
:请求方法。query
:使用ufo将查询搜索参数添加到 URL。params
:query
的别名。body
:请求体 - 自动转换为字符串(如果传递的是对象)。headers
:请求头。baseURL
:请求的基本 URL。
所有的 fetch 选项都可以给定
computed
或ref
值。如果它们被更新,将自动进行新的请求。
Options
(来自useAsyncData
):key
:一个唯一的键,用于确保数据获取可以在请求之间正确去重。如果未提供,将根据使用useAsyncData
的静态代码位置生成。server
:是否在服务器上获取数据(默认为true
)。lazy
:是否在加载路由后解析异步函数,而不是阻止客户端导航(默认为false
)。immediate
:如果设置为false
,将阻止立即发出请求(默认为true
)。default
:一个工厂函数,用于设置data
的默认值,在异步函数解析之前使用 - 与lazy: true
或immediate: false
选项一起使用。transform
:在解析后可以用于更改handler
函数结果的函数。pick
:仅从handler
函数结果中选择指定的键。watch
:监听一组响应式源,并在它们发生变化时自动刷新获取的结果。默认情况下,会监听fetch
选项和 URL。您可以通过使用watch: false
来完全忽略响应式源。结合immediate: false
,可以实现完全手动的useFetch
。deep
:以深层ref
对象的形式返回数据(默认为true
)。可以将其设置为false
,以在浅层ref
对象中返回数据,如果您的数据不需要深层响应,则可以提高性能。
如果您将函数或
ref
作为url
参数,或者如果您将函数作为options
参数的参数传递给useFetch
调用,即使选项似乎相同,该调用也不会与代码库中的其他useFetch
调用匹配。如果您希望强制匹配,可以在options
中提供自己的键。
2.返回值
data
:传入的异步函数的结果。pending
:一个布尔值,指示数据是否仍在获取中。refresh
/execute
:一个可以用于刷新handler
函数返回的数据的函数。error
:如果数据获取失败,则为错误对象。status
:表示数据请求的状态的字符串(”idle”、”pending”、”success”、”error”)。
默认情况下,Nuxt 会等待refresh
完成后才能再次执行。
如果您没有在服务器上获取数据(例如,使用
server: false
),那么直到水合完成之前,数据将不会被获取。这意味着即使在客户端上等待useFetch
,data
也将在<script setup>
中保持为 null。
7.http 中 body、query 和 params 的区别
在路由中,参数可以通过不同的方式传递,包括 body
、query
和 params
。这些参数在使用时有一些区别:
- @Body
Body
参数是通过请求的主体部分传递的数据。通常用于传递较大的数据,例如JSON
或XML
格式的数据。在HTTP
请求中,Body
参数通常与POST
或PUT
方法一起使用。 - @Query
Query
参数是通过URL
的查询字符串传递的数据。查询字符串是URL
中问号后面的部分,包含了键值对的形式。例如,对于URL
http://example.com/search?keyword=apple
,查询参数是keyword=apple
。Query
参数通常用于传递较小的数据,例如搜索关键字、过滤条件等。 - @Params
Params
参数是通过URL
路径的一部分传递的数据。通常用于标识资源的唯一性或层级关系。例如,对于URL
http://example.com/users/123
,其中的123
就是一个Params
参数,用于标识用户ID
为123
的用户。Params
参数通常用于 RESTful 风格的API
中。
8.vue3 中 markRaw 的使用
作用:将一个对象标记为不可以被转化为代理对象。返回该对象本身。
应用场景:
- 有些值不应被设置成响应式时,例如复杂的第三方类库等
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能
- 在动态渲染组件的时候我们就可以使用
markRaw
包裹。
9.definePageMeta
1.参数
definePageMeta(meta: PageMeta) => void
interface PageMeta {
validate?: (route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>
redirect?: RouteRecordRedirectOption
name?: string
path?: string
alias?: string | string[]
pageTransition?: boolean | TransitionProps
layoutTransition?: boolean | TransitionProps
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
[key: string]: unknown
}
2.元数据的对象
- meta:类型
PageMeta
,接受以下页面元数据的对象:name
:类型string
- 你可以为此页面的路由定义一个名称。默认情况下,名称是根据
pages/
目录内的路径生成的。
- 你可以为此页面的路由定义一个名称。默认情况下,名称是根据
path
:类型string
- 如果你有一个比文件名更复杂的模式,你可以定义一个路径匹配器。
alias
:类型string | string[]
- 记录的别名。允许定义额外的路径,这些路径将像记录的副本一样工作。允许使用类似
/users/:id
和/u/:id
的路径简写。所有的alias
和path
值必须共享相同的参数。
- 记录的别名。允许定义额外的路径,这些路径将像记录的副本一样工作。允许使用类似
keepalive
:类型boolean
|KeepAliveProps
- 在切换路由或使用
KeepAliveProps
时,设置为true
以保留页面状态,或进行精细控制。
- 在切换路由或使用
key
:类型false
|string
|((route: RouteLocationNormalizedLoaded) => string)
- 当你需要更多地控制何时重新渲染``组件时,设置
key
值。
- 当你需要更多地控制何时重新渲染``组件时,设置
layout
:类型false
|LayoutKey
|Ref
|ComputedRef
- 为每个路由设置静态或动态布局的名称。如果需要禁用默认布局,可以将其设置为
false
。
- 为每个路由设置静态或动态布局的名称。如果需要禁用默认布局,可以将其设置为
layoutTransition
:类型boolean
|TransitionProps
- 设置当前布局应用的过渡名称。你也可以将此值设置为
false
以禁用布局过渡。
- 设置当前布局应用的过渡名称。你也可以将此值设置为
middleware
:类型MiddlewareKey
|NavigationGuard
|Array
- 在
definePageMeta
内直接定义匿名或命名中间件。了解更多关于路由中间件的信息。
- 在
pageTransition
:类型boolean
|TransitionProps
- 设置当前页面应用的过渡名称。你也可以将此值设置为
false
以禁用页面过渡。
- 设置当前页面应用的过渡名称。你也可以将此值设置为
redirect
:类型RouteRecordRedirectOption
- 如果直接匹配路由,将重定向到何处。重定向发生在任何导航守卫之前,并触发以新目标位置进行的新导航。
validate
:类型(route: RouteLocationNormalized) => boolean | Promise | Partial | Promise>
- 验证给定的路由是否可以使用此页面有效地呈现。如果有效,则返回
true
,否则返回false
。如果找不到其他匹配,这将意味着 404。你还可以直接返回一个带有statusCode
/statusMessage
的对象,以立即以错误响应(不会检查其他匹配)。
- 验证给定的路由是否可以使用此页面有效地呈现。如果有效,则返回
scrollToTop
:类型boolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean
- 告诉 Nuxt 在渲染页面之前是否滚动到顶部。如果你想覆盖 Nuxt 的默认滚动行为,可以在
~/app/router.options.ts
中进行设置(参见文档)。
- 告诉 Nuxt 在渲染页面之前是否滚动到顶部。如果你想覆盖 Nuxt 的默认滚动行为,可以在
[key: string]
:类型any
- 除了上述属性外,你还可以设置自定义元数据。你可能希望以类型安全的方式通过扩充
meta
对象的类型来实现。
- 除了上述属性外,你还可以设置自定义元数据。你可能希望以类型安全的方式通过扩充
10.navigateTo 源码解析
export const navigateTo = (to, options) => {
if (!to) {
to = "/";
}
const toPath =
typeof to === "string"
? to
: withQuery(to.path || "/", to.query || {}) + (to.hash || "");
if (options?.open) {
if (import.meta.client) {
const { target = "_blank", windowFeatures = {} } = options.open;
const features = Object.entries(windowFeatures)
.filter(([_, value]) => value !== void 0)
.map(([feature, value]) => `${feature.toLowerCase()}=${value}`)
.join(", ");
open(toPath, target, features);
}
return Promise.resolve();
}
const isExternal =
options?.external || hasProtocol(toPath, { acceptRelative: true });
if (isExternal) {
if (!options?.external) {
throw new Error(
"Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`."
);
}
const protocol = parseURL(toPath).protocol;
if (protocol && isScriptProtocol(protocol)) {
throw new Error(`Cannot navigate to a URL with '${protocol}' protocol.`);
}
}
const inMiddleware = isProcessingMiddleware();
if (import.meta.client && !isExternal && inMiddleware) {
return to;
}
const router = useRouter();
const nuxtApp = useNuxtApp();
if (import.meta.server) {
if (nuxtApp.ssrContext) {
const fullPath =
typeof to === "string" || isExternal
? toPath
: router.resolve(to).fullPath || "/";
const location2 = isExternal
? toPath
: joinURL(useRuntimeConfig().app.baseURL, fullPath);
const redirect = async function (response) {
await nuxtApp.callHook("app:redirected");
const encodedLoc = location2.replace(/"/g, "%22");
nuxtApp.ssrContext._renderResponse = {
statusCode: sanitizeStatusCode(options?.redirectCode || 302, 302),
body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
headers: { location: location2 },
};
return response;
};
if (!isExternal && inMiddleware) {
router.afterEach((final) =>
final.fullPath === fullPath ? redirect(false) : void 0
);
return to;
}
return redirect(
!inMiddleware ? void 0 : /* abort route navigation */ false
);
}
}
if (isExternal) {
nuxtApp._scope.stop();
if (options?.replace) {
location.replace(toPath);
} else {
location.href = toPath;
}
if (inMiddleware) {
if (!nuxtApp.isHydrating) {
return false;
}
return new Promise(() => {});
}
return Promise.resolve();
}
return options?.replace ? router.replace(to) : router.push(to);
};
可以看出,navigateTo
最终还是使用了 router
进行处理
<NuxtLink>
是 Vue Router
的 <RouterLink>
组件和 HTML 的 <a>
标签的替代品。它能智能地确定链接是内部链接还是外部链接,并根据可用的优化(预加载、默认属性等)进行渲染。
11.export * from
用法
// a.js
export const x = 1;
export const y = 2;
export const z = 3;
// b.js
export * from "./a.js";
// c.js or c.vue
import { x, y, z } from "b.js";
console.log(x + y + z); // 6
.prettierrc
文件 配置
{
"printWidth": 100, //每行最多多少个字符换行
"tabWidth": 4, //格式化时tab缩进大小,默认为2
"useTabs": false, //格式化时使用tab缩进,默认false
"semi": false, //格式化时不加分号,默认true
"singleQuote": true, //用单引号替换双引号,默认false(在jsx中配置无效, 默认都是双引号)
//对象后面默认添加逗号,默认none,可选 none|es5|all
//es5 包括es5中的数组、对象
//all 包括函数对象等所有可选
"trailingComma": "all",
//箭头函数参数括号 默认avoid 可选 avoid| always
//avoid 能省略括号的时候就省略 例如x => x
//always 总是有括号
"arrowParens": "avoid"
}
12.控制台样式
console.log(
`%c页面加载耗时:1111ms | Theme By Dream `,
"color:#fff; background: linear-gradient(270deg, #986fee, #8695e6, #68b7dd, #18d7d3); padding: 8px 15px; border-radius: 0 15px 0 15px"
);
console.log(
"%c 页面加载耗时:" + Math.round(e) + " ms",
"padding: 6px 8px;color:#fff;background:linear-gradient(270deg, #4edb21, #f15206);border-radius: 3px;"
);
13.简单的 css
弹性布局小游戏-小青蛙
14.简单的 css
网格布局小游戏
15.简单的 css
网格布局代码生成器
更多查看: