简述SSR服务端渲染之使用Nuxt搭建一个vue从0到1的项目!

3,364 阅读7分钟

导读

vue的高效开发不言而喻,但是单纯的使用vue-cli开发是否经常遇到页面不被收录,爬虫抓取不到页面的苦恼呢?那我们一起来看看nuxt-vuejs的通用框架。 本文主要讲述使用nuxt.js搭建vue项目的一个从0到1的过程。

如有错误,还请各位大佬订正。

GITHUB直通车

github直通车

什么是SSR

SSR,即服务器渲染,就是在服务器端将对Vue页面进行渲染生成html文件,将html页面传递给浏览器,最后显示在客户端。

Nuxt.js的定义

Nuxt.js 是一个基于 Vue.js 的通用应用框架。 通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI渲染。

Nuxt.js的特性

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

使用nuxt搭建项目

中文文档

nuxt中文文档

安装vue-cli脚手架

vue-cli的脚手架还是必不可少的,我这里使用的是2.9.6

// 全局安装最新版
npm install vue-cli -g 
// 安装指定版本 只需要声明需要安装的版本号即可
npm install vue-cli@2.9.6 -g

安装好vue-cli只有就可以直接使用init指令来初始化nuxt项目

初始化项目

整个过程和vue-cli创建项目的过程基本一致,如果你也想试试,只需要跟着以下的指令依次执行就可以体验安装过程。

// 创建项目文件夹
mkdir nuxt-demo
// 初始化项目
vue init nuxt/starter
// 安装依赖
npm install
// 运行项目
npm run dev

项目就成功的跑起来了。那我们来看看文件目录。

文件配置目录
作用 名称 解释
资源目录 assets 组织未编译的静态资源如 LESS、SASS 或 JavaScript。
布局目录 layouts 组织应用的布局组件
中间件目录 middleware 存放应用的中间件
页面目录 pages 路由及视图,nuxt会自动生成路由配置
插件目录 plugins 需要在根vue.js应用实例化之前需要运行的JavaScript插件
静态文件目录 static 静态文件,不会被调用到webpack进行构建编译处理
vuex状态树 store vuex状态树文件,状态管理器
配置文件 nuxt.config.js 应用的个性化配置,以便覆盖默认配置
包管理 package.json 依赖和对外暴露的脚本接口

再熟悉了基本的文件目录结构之后我们再来自信看看nuxt.config.js里面的内容。

module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    title: 'nuxt',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'this is nuxt project demo' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress bar color
  */
  loading: { color: '#3B8070' },
  /*
  ** Build configuration
  */
  build: {
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}

head:配置页面的头部信息meta、title等

loading:个性化定制 Nuxt.js 使用的加载组件

build:允许你在自动生成的 vendor.bundle.js 文件中添加一些模块,以减少应用 bundle 的体积,如果你不会配置,你可以移步我的webpack系列文章《大声对webpack4.0说声你好之webpack的基本使用(一)

此外你还可以增加自己的其他配置,以下为大家例举常用的几点

css: 全局css,数组形式,支持多个。 dev:开发模式或生产模式 env:客户端和服务端的环境变量 router:覆盖默认router配置 transtion: 过度属性的默认值

修改项目

全局配置

配置信息为大家介绍的差不多了,接下来我们就开始修改我们的项目信息,让他像普通的html一样跑起来,首先我新建一个css文件,然后在修改一下我们的nuxt.config.js中的一些配置,为大家演示。

// 新建assets/css/style.css样式文件
*{
  margin: 0;
  padding: 0;
}
body{
  background: #f8f8f8;
  color: #333;
}

//配置 nuxt.config.js
head: {
    title: '使用nuxt搭建的项目',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'this is nuxt project demo' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  css: ['~assets/css/style.css'],

然后我们在浏览器中重新运行。按住f12检查源代码。

nice!兄die。我们的东西成功的浏览器渲染到了页面上。这第一步我们就成功了。

接下来我将为您介绍一些项目中比较常用的问题,希望对新手有所帮助。

路由

相比于vue的router-link,nuxt也为我们提供了自己的跳转方式,nuxt-link

// index.vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ desc }}</p>

    <div>
      <nuxt-link to="/notice">文章详情</nuxt-link>
    </div>
    <div>
      <nuxt-link :to="{name:'member',params:{id:999}}">会员中心</nuxt-link>
    </div>
    <div>
      <nuxt-link :to="{name:'other',query:{id:666}}">其他页面</nuxt-link>
    </div>

  </div>
</template>

<script>

export default {
  data(){
    return {
      title: '首页',
      desc: 'this is my nuxt demo.'
    }
  }
}
</script>

<style>

</style>

我们来详细的看看这个例子

  • 当我们新建组件的时候,我们是无需配置路由的,因为nuxt会自动帮我们生成路由,所以我们就可以直接跳转。
  • 跳转我们可以使用路径和对象的方法,name是路由名称,params携带路由参数,我们可以通过**$route.params.id**拿到页面携带的参数。注意刷新页面参数会消失。
  • query是页面参数,我们可以通过**$route.query.id**获取到,刷新页面不会消失。
单个页面配置head

通过路由我们已经可以实现页面的切换已经传参,那么我们到其他的页面如何单独的配置独立的head信息,例如title、meta等?

head(){
    return {
      title: '这个是我的新闻资讯',
      meta: [{
        hid: "description",
        name: "description",
        content: "this is my notice page"
      },{
        hid: 'viewport',
        name: 'viewport',
        content: 'width=device-width, initial-scale=1.0'
      }]
    }
  },

在js中,我们可以通过head方法来单独的配置每个页面的信息。然后f12检查源码之后,我们都是渲染的独立配置的信息。

配置路由动画

vue的页面可以使用transform来实现过度效果。那我们在nuxt中又是如何去配置页面的动画效果呢?

其实我们之前在全局中引入了一个style.css文件,我们将它修改,增加以下代码。

.page-enter-active,.page-leave-active{
  transition: opacity 0.5s;
}
.page-enter,.page-leave{
  opacity: 0;
}

page开头的是定义的全局配置,和vue的几个路由进入相似。这样配置的话是我们每个页面都会按照这种动画效果切换路由。

那么又是如何单独的配置路由切换动画的呢?

.only-enter-active,.only-leave-active{
  transition: opacity 1s;
}
.only-enter,.only-leave{
  opacity: 0;
}

在style.css 中新增一个only开头的切换效果。然后在想设置的页面中添加transition属性。

transition:'only',

ok,这样就设置成功了。

默认模板和布局

模板是我们经常用到的一个东西,如果你的网站整体都是一个结构,只有你的body会改变,那么使用模板布局最好不过了。

新建app.html

<!DOCTYPE html>
<html lang="en">
<head>
  {{ HEAD }}
</head>
<body>
  {{ APP }}
</body>
</html>

head 是我们的公共配置head信息,app是页面主体。

layouts 就是我们处理布局的文件,具体可以参考官网或者目录下面的default.vue文件,这里就不多做解释。

设置错误页面

在网站中,我们经常会自定义404页面,那我们在使用nuxt的时候怎么去操作这个技巧呢?

在layouts目录下面新建error.vue文件,即可自定义我们的404拦截。

<template>
  <p>404</p>
</template>

只要我们的页面没有路径,或者路由输入错误,我们就会给用户展示我们自己的404页面。

ansycData

我是准备将这个写成子目录,但是因为他对我们来说,实在是不要太爽了,所以我把它单独提出来。他的作用是什么?

你可能想要在服务器端获取并渲染数据。
Nuxt.js添加了asyncData方法使得你能够在渲染组件之前异步获取数据。

asyncData方法会在组件(限于页面组件)每次加载之前被调用。
它可以在服务端或路由更新之前被调用。
在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据并返回给当前组件。

这个方法能让你爽到什么程度呢?

假设现在是这么一个场景:一个新闻列表有15条数据,每一个数据有一个id,点击进去只有是独立的新闻详情。那么我们如何给自己的新闻详情设置独立的title或者description?让浏览器通过不同的url收录我们更多的页面?

ok,在我们刚才做过的给每个页面独立的设置head信息,我们在他的基础上再稍加完善。这个时候我们就会用到我们的ansycData

首先我们按照axios

npm install axios -S

因为我们这里是没有准备接口的,所以我使用的是easy-mock来模拟一些数据。给大家做一些演示。

// head
title: this.title,

// js
asyncData(){
    return axios.get('https://www.easy-mock.com/mock/5abdd9ce7a17b12a1c9965c5/example/news')
    .then(res=>{
      console.log(res)
      return { title: res.data.title }
    })
  }

在使用的过程中,我们已经能有明显的进度条加载动画了。这个时候就是我们想要的页面标题,那么一个参数就会对应一个标题,这样的效果简直nice极了。

但是,我们的代码好像很乱啊,那我们就继续来改改。

async asyncData (){
    let { data } = await axios.get('https://www.easy-mock.com/mock/5abdd9ce7a17b12a1c9965c5/example/news')
    return { title: data.data.title,content: data.data.content }
}

打包

npm run generate

如果你的打包之后资源找不到,页面404等,请在nuxt.config.js中参考以下配置。

router: {
    base: '/dist'
},

总结

nuxt的强大不言而喻,他在我们的开发中给我们提供了一个服务器预渲染的方式,让我们将服务器返回的数据提前渲染到浏览器后再将页面展示给用户,还可以在每个页面配置自己的页面信息。

最后希望本节笔记能给你带来你想要的信息。如果对您有帮助,还请不吝赐赞👍。