基于Vue的服务端渲染框架Nuxt.js案例说明

做~自己de王妃 提交于 2020-04-19 17:15:29

背景

公司要开发新官网(教育公司),网站需要考虑引流、推广、关键字搜索排名等,所以网站需要做SEO。Vue.js 是构建客户端应用程序的框架,默认情况下可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM,像这种客户端渲染方式,并不利于SEO优化,特别是网站中使用ajax去获取新闻列表、新闻详情等信息,百度爬虫是没发抓取到的,所以官网需要考虑一种服务器端渲染(SSR)页面的方式。

Nuxt.js介绍

从头搭建一个服务端渲染的应用是相当复杂的。幸运的是,使用 Nuxt.js 让这一切变得较简单。Nuxt 是一个基于 Vue 生态的更高层的框架,为开发服务端渲染的 Vue 应用提供了极其便利的开发体验。 服务器端渲染 (SSR) 的优势主要在于:

  1. 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面
  2. 更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。

案例说明

以下所有介绍主要围绕官网所需功能来列举Nuxt.js的一些关键配置,并不包含Nuxt.js的所有功能。
DEMO地址:HelloNuxt

1. html头部

做SEO优化,不仅要考虑服务器端渲染,还要考虑页面的Meat标签,比如标题、描述、关键字等
默认全局配置放在nuxt.config.js文件中:

  head: {
    title: '*******官网',
    meta: [
      { hid: 'description', name: 'description', content: '任意描述信息' },
      { hid: 'keyword', name: 'keyword', content: '关键字1,关键字2......' }
    ]
  }

比如官网新闻详情页有特殊的标题或描述信息,可以在页面这么来设置

<template>
  <div class="content">
    <h3>新闻详情页面</h3>
</template>

<script>
export default {
  data () {
    return {
      data: {
        title: '新闻标题',
        description: '描述信息'
      }
    }
  },
  head () {
    return {
      title: this.data.title,
      meta: [
        { hid: 'description', name: 'description', content: this.data.description },
      ],
    }
  }
}
</script>

2. 布局

在layouts目录中添加一个布局文件,可以把页面公用部分放在布局文件中,默认布局文件:default.vue,别忘了在布局文件中添加 <nuxt/> 组件用于显示页面的主体内容。 假如我们创建一个 深色主题的布局 保存到layouts/dark.vue

<template>
  <div>
    <div>深色布局模版</div>
    <nuxt/>
  </div>
</template>

如需使用自定义布局的页面,需要在页面中指出:

<template>
<!-- Your template -->
</template>
<script>
export default {
  layout: 'dark'
}
</script>

3. 页面路由

不需要写路由文件,Nuxt依据 pages 目录结构自动生成 vue-router 模块的路由配置。 假设文件结构如下:

pages/
--| index.vue
--| news/
-----| index.vue
-----| _id.vue
-----| detail/
---------| _id.vue

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

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

news目录下面有动态路由(_id.vue),主要考虑新闻列表翻页传递的pageNum,也可以直接使用页面传参?pageNum=1的形式

4. 异步数据

Nuxt.js 增加了 asyncData 方法,可以在设置组件的数据之前能异步获取或处理数据。asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。

<template>
  <div>
    <h3>新闻中心</h3>
    <ul>
      <li v-for="item in news">
        <NLink :to="`/news/detail/${item.id}`">{{item.name}}</NLink>
      </li>
    </ul>
  </div>
</template>
<script>
import axios from 'axios' 
export default {
  asyncData ({ params, error }) {
    return axios.get(`eg/xxxx/news?pageSize=10&pageNum=${params.id || 1}`).then(res => {
      return {
        news: res.data.news,
        page: {
          total: res.data.total
        }
      }
    })
  }
}
</script>

Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。

5. vuex状态树

这个模块可能在公司官网中一般用不到,但我还是想拿出来讲一讲,Nuxt.js允许您拥有一个 store 目录,其中包含与模块对应的每个文件。 直接上例子,store/index.js:

export const state = () => ({
  news:[]
})

export const mutations = {
  SET_VISIT (state, data) {
    state.news = data
  }
}

export const getters={
  getNews(state){
    return state.news
  }
}

您可以拥有 store/other.js 模块:

export const state = () => ({
  list: []
})

Nuxt.js会根据store目录下定义的模块自动初始化store对象,然后绑定到框架;在组件中使用跟在Vue.js中基本没有区别

import {mapGetters } from 'vuex'
export default {
  computed: {
    otherList () {
      return this.$store.state.other.list
    },
...mapGetters({
    news: 'getNews'
  })
  }
}

6. 插件

使用第三方模块可以直接npm导入,然后在组件中去引入使用,比如上面的异步数据中使用axios的例子。
使用vue插件,比如element-ui,首先增加文件,plugins/element-ui.js

import Vue from 'vue'
import Element from 'element-ui'
Vue.use(Element)

然后, 在 nuxt.config.js 内配置 plugins 如下:

module.exports = {
  css: [
    'element-ui/lib/theme-chalk/index.css',
  ],
  plugins: [{ src: '@/plugins/element-ui' }],
  build: {
    extractCSS: { allChunks: true }
  }
 }

配置完成,就可以使用element-ui的组件了。项目中公用的css文件也可以在此处的css数组中去引入进来。
build/extractCSS此处配置,主要是为了帮助你从 HTML 中快速分离出 CSS,如果allChunks=false,样式文件不是以link的方式引入,而是都直接加载在页面的<style />标签中。

7. 其它

  1. 如果项目中需要使用sass,直接npm包导入即可,无需其它配置。
  2. Nuxt.js团队创建了脚手架工具,直接生成项目: npx create-nuxt-app <项目名>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!