Nuxt3的探索之旅(一)安装使用、vite的浅原理认识和Nuxt的开箱即用功能初识

3,180 阅读4分钟

工作好几年了,都只是撸撸关键词,画个图之类的,从来没撸过一整篇的东西,今天算是迈出了自己的第一步。不断告诉自己不要太追求完美牛逼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模块规范的包。目前大部分人会讲ViteWebpack结合适应,取长补短。

最小应用

app.vue是Nuxt3应用的入口组件,如果没有pages目录,那么不会加载vue-router。相当于是单一的一个页面,如果需要使用pages/显示不同的页面,需要使用<NuxtPage>路由出口组件

pages目录

动态路由

我们除了会遇到访问一个固定的地址外,还会有以下几种情况:

  1. http://Localhost:3000/aticle/{{id}}

    http://Localhost:3000/aticle/1、http://Localhost:3000/aticle/2、http://Localhost:3000/aticle/3

  2. 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对象访问组件中的参数typeid

<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即可