Skip to content

nuxt3

🕒 Published at:

vue中如何使用SSR的

javascript
// 第 1 步:创建一个 Vue 实例
const Vue = require('vue');
const app = new Vue({
  template: `<div>Hello World</div>`
});
// 第 2 步:创建一个 renderer
const renderer = require('vue-server-renderer').createRenderer();
// 第 3 步:将 Vue 实例渲染为 HTML
renderer.renderToString(app, (err, html) => {
  if (err) throw err;
  console.log(html);
  // => <div data-server-rendered="true">Hello World</div>
});
// 在 2.5.0+,如果没有传入回调函数,则会返回 Promise:
renderer
  .renderToString(app)
  .then(html => {
    console.log(html);
  })
  .catch(err => {
    console.error(err);
  });

安装并启动nuxt

创建项目

打开 Visual Studio Code , 打开内置终端并输入下面命令创建一个 nuxt 项目:

js
//新建
npx create-nuxt-app <项目名>
npx nuxt init nuxt3-app

安装依赖

yarn
or
npm i

启动

以 开发模式启动 nuxt:

yarn dev
or
npm run dev

页面配置

属性名描述示例
watchQuery用于监视query参数变化并在更改时执行组件方法
(asyncData, fetch, validate, layout, ...)
watchQuery:true , //监视所有query参数
watchQuery:['aaa'], //监视部分query参数
asyncData使得你能够在渲染pages中的组件之前,
异步获取数据,然后将这些数据注入到组件的 data 中。

无法使用this

该方法的第一个参数为当前页面组件的上下文对象,对象中包括但不限于以下属性:
1. $axios(如果你安装了 @nuxtjs/axios 模块)
2. store(Vuex store 实例)
3. route(当前路由对象)
4. redirect(重定向到另一个路由)
5. error(触发错误,通常用于处理服务器端的错误)
6. params(路由参数)
7. query(查询字符串参数)
asyncData({params}{
return {params}
}

async asyncData({params}){
return $axios.get(path,params);
}
fetch用于在渲染页面之前获取数据填充应用的状态树(store)。

无法使用this

参数与asyncData相同
async fetch({ store, params }) {
const res=await axios.get(path)
store.commit('setStars', res)
}
head配置当前页面的head标签内容,使用vue-meta库

支持this
head(){
return {
title: '你好',
meta:[],
...
}
}![[Pasted image 20240718161443.png]]
layout指定当前页面使用的布局
参数与asyncData相同
layout(content){
return 'default'
}
middleware指定页面的中间件,
中间件会在页面渲染之前被调用
middleware:'xxx', //在pages或layouts中

router:{
middleware: 'xxx' //在 nuxt.config.js中
}
transition指定页面切换的过渡动效, 详情请参考页面过渡动效transition:
scrollToTop用于判定渲染页面前是否需要将当前页面滚动至顶部。
这个配置用于嵌套路由的应用场景。
scrollToTop:true
validate用于校验当前路由是否有效
参数同asyncData
validate({params}{
return true
}

async validate({params}{
return !!$axios.get(path,params);
}

内置组件

组件描述说明
<nuxt/>用于显示pages中的组件nuxtChildKey:将什么作为,默认是$route.path
<nuxt-child/>用于在pages页面中,展示child.vue组件
<nuxt-link/>可以理解为router-link<NuxtLink to="{path:'/login',params:{参数键值对},query:{参数键值对}}" />
<NuxtLink to="{name:'login',params:{参数键值对},query:{参数键值对}}" />
<ClientOnly/>用于包裹仅用于客户端渲染,不需要服务端渲染的组件<ClientOnly>不需要ssr的内容</ClientOnly>

目录结构

目录描述示例
.nuxt构建用于开发的程序,nuxt dev时会重新创建该目录
.output构建用于生产的程序,nuxt build时会重新创建该目录
static&assets不需要构建编译的静态文件存放到static中,打包后会放在根目录
components存放公共组件,Nuxt会自动引入并注册该目录下的所有组件组件的名称将基于自己的路径和文件名,并删除重复的段,异步组件需要添加Lazy前缀,比如:

1. an/an/Button.vue 组件名是 AnButton
2. base/foo/Button.vue 组件名是 BaseFooButton
3. base/foo/Button.vue 如果是异步组件,组件名是LazyBaseFooButton
layouts存放布局组件,Nuxt会自动引入并注册该目录下的所有组件1. layouts/default.vue用来扩展应用的默认布局
2. layouts/error.vue 用来定义应用的错误页面

其他用于自定义布局,通过在组件配置项中使用layout配置项决定使用的布局:
export default {
layout: 'error', //指定使用的布局
...
}
middleware存放中间件,中间件执行流程顺序:

1. nuxt.config.js
2. 匹配布局
3. 匹配页面

export default function ({ route }) {} //组件内默认导出,以文件名作为中间件

export function xxx({ route }) {} //组件内具名导出,以fn名字作为中间件
pages存放路由组件,Nuxt会根据pages的目录结构自动生成vue-router的路由配置1. pages/user/one.vue 普通路由,对应path为 /user/one
2. pages/users/_id.vue 动态路由,对应path为 /users/:id?

1. pages/users/_id/index.vue 动态路由,对应path为 /users/:id?
2. pages/users/_a/_b/index.vue 动态路由,对应path为 /users/:a?/:b?

4. pages/_slug/com.vue 动态路由,对应path为 /:slug/com.vue
composables存放公共方法,Nuxt会根据导出方式的不同,来注册对应名称的公共方法<template><div></div></template>
export default function () {} //组件内默认导出,以文件名作为公共方法

export const useFoo = () => {} //组件内具名导出,以fn名字作为公共方法
plugins存放插件

拓展组件库

使用 components:dirs 钩子进行组件扩展

定义

javascript
import { join } from 'pathe'
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  hooks: {
    'components:dirs'(dirs) {
      // Add ./components dir to the list
      dirs.push({
        path: join(__dirname, 'components'),
        prefix: 'awesome',
      })
    },
  },
})

注册

nuxt.config 文件中:

export default {
  buildModules: ['awesome-ui/nuxt'],
}

使用

<template>
  <div>
    My <AwesomeButton>UI button</AwesomeButton>!
    <awesome-alert>Here's an alert!</awesome-alert>
  </div>
</template>