欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue.js服务器端渲染的两种方式之 Nuxt.js 使用

程序员文章站 2022-07-15 14:04:19
...

vue.js服务器端渲染的两种方式:

  • vue-server-renderer
  • Nuxt.js

1. vue-server-renderer

vue-server-renderer插件,使用 Node.js server 的服务器端单页面应用程序渲染。将 Vue 服务器端渲染 (SSR) 与其他后端设置进行混合使用。

用法:安装 ==> 渲染一个 Vue 实例 ==> 与服务器集成

从头搭建一个服务端渲染的应用是相当复杂的。在工作中推荐使用 Nuxt.js 来完成服务端渲染。关于 vue-server-renderer 的使用方法在这里就不做详细的说明,感兴趣的话可以查看官方文档

2. Nuxt.js

2016 年 10 月 25 日,zeit.co 背后的团队对外发布了 Next.js,一个 React 的服务端渲染应用框架。几小时后,与 Next.js 异曲同工,一个基于 Vue.js 的服务端渲染应用框架应运而生,我们称之为:Nuxt.js。

2.1 介绍

  • Nuxt 是一个基于 Vue 生态的更高层的通用应用框架,为开发服务端渲染的 Vue 应用提供了极其便利的开发体验。
  • Nuxt.js 主要关注的是应用的 UI渲染。
  • Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。
  • 使用 nuxt generate 命令,可以为基于 Vue.js 的应用生成对应的静态代码,存放在根目录下的dist目录里。
  • Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作(如打包、代码分层、压缩等等)。

2.2 特性

  • 基于 Vue.js
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • ES2015+ 语法支持
  • 打包和压缩 JS 和 CSS
  • HTML 头部标签管理
  • 本地开发支持热加载
  • 集成 ESLint
  • 支持各种样式预处理器: SASS、LESS、 Stylus 等等
  • 支持 HTTP/2 推送

2.3 安装

通过脚手架工具 create-nuxt-app 可以快速创建一个 nuxt 项目
终端中输入以下命令,在当前目录创建 nuxt 项目
npx create-nuxt-app ./

创建时需要进行一些选择

$ npx create-nuxt-app ./

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in ./
? Project name nuxtJs								//项目名称
? Project description My astounding Nuxt.js project		//项目描述
? Author name 11111									//作者姓名
? Choose programming language JavaScript			//选择开发的语言 javascript or typescript
? Choose the package manager Yarn				//选择包管理的工具 npm or yarn
? Choose UI framework Element					//选择一个UI框架
? Choose custom server framework Express			//选择一种服务端框架
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection) //检查代码是否规范
? Choose test framework None						//选择一个测试框架
? Choose rendering mode Universal (SSR) 			//选择一种渲染模式 SSR or SPA
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
Warning: name can no longer contain capital letters

创建成功后,会输出下面的信息

????  Successfully created project nuxtJs

  To get started:

        yarn dev

  To build & start for production:

        yarn build
        yarn start

终端输入 yarn dev,启动项目,浏览器打开 http://localhost:3000/,页面出现以下内容,则项目创建成功。
vue.js服务器端渲染的两种方式之 Nuxt.js 使用

2.4 目录结构

vue.js服务器端渲染的两种方式之 Nuxt.js 使用
nuxt中默认设置的别名:

别名 目录
~ 或 @ srcDir
~~ 或 @@ rootDir

默认情况下,srcDir 和 rootDir 相同。

2.5 引入资源文件

在vuecli中,我们可以在入口文件中引入一些静态资源文件,比如scss文件等,在nuxt中,文件的引入需要在nuxt.config.js 配置文件中设置。修改配置文件后,需要重新启动服务。

比如:在assets目录下新建了 /css/style.scss 文件,在 nuxt.config.js配置文件中添加如下内容:
vue.js服务器端渲染的两种方式之 Nuxt.js 使用
重启服务后,发现报错了

 ERROR  Failed to compile with 1 errors                                               friendly-errors 19:20:30
This relative module was not found:                                                   friendly-errors 19:20:30                                                                                friendly-errors 19:20:30
* ../assets/css/style.scss in ./.nuxt/App.js                                          friendly-errors 19:20:30
ℹ Waiting for file changes                    

如果我们要想在项目中解析sass文件的话,需要手动安装sass-loader
yarn add node-sass sass-loader -D
安装完,不需要做别的配置,重新启动服务,就可以了。

2.6 路由

nuxtJs中并不需要手动配置路由,它可以依据 pages 目录结构自动生成 vue-router 模块的路由配置

<template>
  <nuxt-link to="/">首页</nuxt-link> 
   <!-- <nuxt-link> 相当于 <router-link> -->
  <nuxt-link to="/user">用户</nuxt-link>
  <nuxt/> 
   <!-- <nuxt/> 相当于 <router-view /> -->
</template>

2.6.1 基础路由

假设 pages 的目录结构如下:

pages/
	--| user/
		-----| index.vue
		-----| one.vue
	--| index.vue

那么,Nuxt.js 自动生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    }
  ]
}

2.6.2 动态路由

在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。

通过$route.params.id获取路由参数。

假设 pages 的目录结构如下:

pages/
	--| _slug/
		-----| comments.vue
		-----| index.vue
	--| users/
		-----| _id.vue
	--| index.vue

那么,Nuxt.js 自动生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'users-id',
      path: '/users/:id?',
      component: 'pages/users/_id.vue'
    },
    {
      name: 'slug',
      path: '/:slug',
      component: 'pages/_slug/index.vue'
    },
    {
      name: 'slug-comments',
      path: '/:slug/comments',
      component: 'pages/_slug/comments.vue'
    }
  ]
}

2.6.3 嵌套路由

  • 创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
  • 在父组件(.vue文件) 内增加 用于显示子视图内容。

假设 pages 的目录结构如下:

pages/
	--| users/
		-----| _id.vue
		-----| index.vue
	--| users.vue

那么,Nuxt.js 自动生成的路由配置如下:

router: {
  routes: [
    {
      path: '/users',
      component: 'pages/users.vue',
      children: [
        {
          path: '',
          component: 'pages/users/index.vue',
          name: 'users'
        },
        {
          path: ':id',
          component: 'pages/users/_id.vue',
          name: 'users-id'
        }
      ]
    }
  ]
}

2.7 请求数据

  • Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。
  • Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。
  • 由于asyncData方法是在组件初始化前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

例如在组件中请求数据,可以这么写:

<template>
  <div>
    {{result}}
  </div>
</template>

<script>
import axios from "axios"

export default {
  async asyncData() {
    let rs = await axios.get("/data/list.json")
    return {
      result: rs.data
    }
  }
}
</script>

2.8 vuex

  • 在store目录下创建的 index.js 文件,nuxtJs 会自动将该文件引入到项目里。
  • 如果有多个模块,就新建多个js文件,每个文件对应一个模块,不需要再做额外的关联。
  • 在组件中操作vuex中的数据时,和在vueJs中使用方法一样。
  • 与在vueJs中使用vuex不同的是,在index.js 文件中,state、mutation等方法需要以函数的形式导出。

nuxtJs中使用vuex:

export const state = () => ({
  counter: 100
})

export const mutations = {
  increment (state) {
    state.counter++
  }
}

vueJs中使用vuex:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    counter: 100
  },
  mutations: {
    increment (state) {
	    state.counter++
	  }
  },
})

在组件中操作vuex数据:

<template>
  <div>
   {{$store.state.counter}}
   <button @click="$store.commit('increment')">increment</button>
  </div>
</template>

2.9 视图

页面模板,默认使用 layouts目录下的 default.vue 组件,这个组件将用于所有未指定布局的页面。

如果需要自定义页面模板,可以在 layouts 目录下创建一个自定义布局,在页面中设置 layout 属性,指定这个页面模板。

例如,在layouts 目录下新建了 dialog.vue 文件:

<template>
	<div>
		<nuxt />
	</div>
</template>

然后,我们必须告诉页面(即pages目录下的组件)使用这个自定义布局:

<template>
	<div> </div>
</template>
<script>
	export default {
	  layout:"dialog"
	}
</script>

在工作中如果已经使用vuecli开发完成了一个项目,不建议再使用Nuxt.js 来做服务器端渲染,因为迁移的成本是很高的。可以使用php或者java在服务器端生成静态页面,再输出到浏览器。

参考资料:https://nuxtjs.org/guide

相关标签: vue