工作好几年了,都只是撸撸关键词,画个图之类的,从来没撸过一整篇的东西,今天算是迈出了自己的第一步。不断告诉自己不要太追求完美牛逼xxx什么的,先撸出来行不行?
创建项目
打开一个终端,或者在vscode打开内置终端后,输入下面命令行即可创建一个nuxt项目
npx nuxi init nuxt3-app
注意:Node的版本需要高于v14.16.0
安装依赖
yarn install
因为我这边使用了taobao的镜像源,出现了无法建立隧道的问题,使用yarn安装的过程中报了个错误
error An unexpected error occurred: "https://registry.npm.taobao.org/@nuxt%2fschema-edge: connect ECONNREFUSED xxx.xx.xx.xxx:443",所以我这边将镜像源还原后就解决了
npm config set registry https://registry.npmjs.org
启动项目
yarn dev
脚手架默认使用的是Vite构建工具,跟Nuxt2绑定的Webpack相比,开发体验提升巨大,基本上是秒开。
以下是作者原话:
Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 rollup 打包。虽然现在还比较粗糙,但这个方向我觉得是有潜力的,做得好可以彻底解决改一行代码等半天热更新的问题。
摘取几个点加深下印象:
基于原生ES imports:在项目中不能使用require的引入方式,需要使用ES Module
浏览器解析imports:在dev下,访问view-source可以发现html里有 <script type="module">的代码,当遇到这个标签会自动解析import导入的代码(使用http请求)。Vite利用浏览器原生支持模块化导入(ESM),把本来需要通过Webpack打包后才能执行的代码直接放在浏览器执行,这样做去除了打包步骤不需要生成bundle,并实现按需加载。
服务器端按需编译: 在Koa中间里拿到浏览器发起的请求,编译对应的请求模块;
完全跳过了打包这个概念,...热更新不会变慢:Webapck打包是把多个module合并成一个bundle给浏览器使用,如果改变了其中一个文件,那这个bundle就得重新生成,随着模块的增多会变慢。Vite现在不需要打包,自然不会有变慢的问题,但如果请求的模块很多,还是会有请求的瓶颈问题,但这是另外个话题了。
现在还比较粗糙:大部分第三方模块导出的还是cjs包,没有设置默认导出esm。所以Vite的配置还需要做处理,使得能编译成符合esm模块规范的包。目前大部分人会讲Vite和Webpack结合适应,取长补短。
最小应用
app.vue是Nuxt3应用的入口组件,如果没有pages目录,那么不会加载vue-router。相当于是单一的一个页面,如果需要使用pages/显示不同的页面,需要使用<NuxtPage>路由出口组件
pages目录
动态路由
我们除了会遇到访问一个固定的地址外,还会有以下几种情况:
-
http://Localhost:3000/aticle/{{id}}
http://Localhost:3000/aticle/1、http://Localhost:3000/aticle/2、http://Localhost:3000/aticle/3
-
http://Localhost:3000/aticle-{{type}}/{{id}}
http://Localhost:3000/aticle-1/1、http://Localhost:3000/aticle-3/2、http://Localhost:3000/aticle-2/100
├── pages
│ ├── article
│ │ └── [id].vue
│ ├── articles-[type]
│ │ └── [id].vue
│ └── hello.vue
我们在pages/articles-[type]/[id].vue文件中可以通过$route对象访问组件中的参数type和id
<template>
{{ $route.params.type }}
{{ $route.params.id }}
</template>
导航
<NuxtLink>可以看作是<RouterLink>,类似于<a>标签;
当跳转的是应用内的链接时用
<NuxtLink>组件,跳转到外部网站时使用回<a>标签
<template>
<h3>首页hello</h3>
<div>
<NuxtLink to="/articles-2/108">第2种类型的第108篇文章</NuxtLink>
<br />
<a href="https://www.baidu.com">外部应用的链接</a>
</div>
</template>
嵌套路由
假设我想要像在vue-router一样,使用类似<RouterView>的方式嵌套一个路由(parent.vue下嵌套一个child.vue),我需要在pages新建以下文件目录
-| pages/
---| parent/
------| child.vue
---| parent.vue
查看.nuxt生成的路由,已经生成了children
{
"name": "parent",
"path": "/parent",
"file": "nuxt3-app/pages/parent.vue",
"children": [
{
"name": "parent-child",
"path": "child",
"file": "nuxt3-app/pages/parent/child.vue",
"children": [],
"component": () => __vite_ssr_dynamic_import__('/pages/parent/child.vue')
}
],
"component": () => __vite_ssr_dynamic_import__('/pages/parent.vue')
}
但是打开http://localhost:3000/parent/child,只看到了parent的内容,并没有child的页面。还需要再插入一个 <NuxtChild>组件,就也可以看到child的页面了。
当只访问http://localhost:3000/parent,只能访问到parent的内容,因为parent目录下缺少了index的页面作为子路由页面,可以在parent目录下加一个index.vue即可