详解Vue基于 Nuxt.js 实现服务端渲染(SSR)


Posted in Javascript onApril 05, 2018

直接使用 Vue 构建前端单页面应用,页面源码时只有简单的几行 html,这并不利于网站的 SEO,这时候就需要服务端渲染

2016 年 10 月 25 日,zeit.co 背后的团队对外发布了一个 React 的服务端渲染应用框架 Next.js

几小时后,一个基于 Vue.js 的服务端渲染应用框架应运而生,与 Next.js 异曲同工,这就是Nuxt.js

一、快速模板

在已经安装了 vue-cli 的前提下,可以快速创建一个 nuxt 的项目模板

vue init nuxt-community/starter-template MyProject

其中 MyProject 是项目文件夹名称,可自定义

通过 npm install (似乎用 yarn install 更顺利) 安装依赖之后,可以直接 npm run dev 在 开发环境 启动项目

默认启动的地址为 http://localhost:3000/,可以在 package.json 中添加以下配置来修改主机端口号

"config": {
  "nuxt": {
   "host": "0.0.0.0",
   "port": "7788"
  }
 },

开发完成后执行 npm run build 打包代码,最后 npm start 启动服务

二、重要目录

生成的 项目目录 如下

详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

大部分文件夹名称 都是 nuxt 默认保留的,不可修改

其中比价比较关键的目录有三个:

1. components 组件目录

详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

一般用来存放 非页面级别 的组件,如 header、footer 等公共组件

该目录下的组件具有常规 vue 组件的方法和特性,不会被 nuxt.js 扩展特性

2. layouts 布局目录

详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

可以修改该目录下的 default.vue 来修改默认布局

<template>
 <div>
  <my-header></my-header>
  <nuxt/>
  <my-footer></my-footer>
 </div>
</template>

其中 <nuxt/> 是必需的,页面的主体内容会显示在这里 (类似于根节点的 <router-view/>)

此外还可以在目录下新增 error.vue 作为错误页面,具体的写法可以参考官方文档

3. pages 页面目录

详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

用于存放页面级别的组件,nuxt 会根据该目录下的页面结构生成路由

比如上图中的页面结构,会生成这样的路由配置:

router: {
 routes: [
  {
   name: 'index',
   path: '/',
   component: 'pages/index.vue'
  },
  {
   name: 'about',
   path: '/about',
   component: 'pages/about.vue'
  },
  {
   name: 'classroom',
   path: '/classroom',
   component: 'pages/classroom.vue',
   children: [
    {
     path: 'student',
     component: 'pages/classroom/student.vue',
     name: 'student'
    },
    { //定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件或目录
     path: ':id',
     component: 'pages/classroom/_id.vue',
     name: 'classroom-id'
    }
   ]
  }
 ]
}

此外,该目录下的 vue 组件还具备一些 Nuxt.js 提供的特殊功能特性

其中 asyncData 方法比较常用,支持异步数据处理

这个方法会在 页面组件 每次加载之前被调用,然后获取数据并返回给当前组件

asyncData ({ params, error }) {
  return axios.get(`api/posts/${params.id}`)
  .then((res) => {
   return { name: res.data.name}
  })
  .catch((e) => {
   error({ statusCode: 404, message: 'not found' })
  })
 }

asyncData 方法的第一个参数为上下文对象 context,具体属性可以 查看这里

由于asyncData方法是在组件初始化前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象

三、使用插件

如果项目中还需要引入其他的第三方插件,可以直接在页面中引入,这样在打包的时候,会将插件打包到页面对应的 js 里面

但要是别的页面也引入了同样的插件,就会重复打包。如果没有需要分页打包的需求,这时候可以配置 plugins

以 element-ui 为例,在安装了 element-ui 之后,在 plugins 目录下创建 elementUI.js

详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

然后在根目录的 nuxt.config.js 中添加配置项 build.vendor 和 plugins

build: {
  vendor: ['~/plugins/elementUI.js']
 },
 plugins: [
  {src: '~/plugins/elementUI.js'},
 ]

这里的 plugins 属性用来配置 vue.js 插件,也就是 可以用 Vue.user() 方法 的插件

默认只需要 src 属性,另外还可以配置 ssr: false,让该文件只在客户端被打包引入

如果是像 axios 这种第三方 (不能 use) 插件,只需要在 plugins 目录下创建 axios.js

// axios.js

import Vue from 'vue'
import axios from 'axios'

const service = axios.create({
 baseURL: '/api'
})

Vue.prototype.$ajax = axios
export default service

然后在 build.vendor  中添加配置 (不需要配置 plugins)

build: {
 vendor: ['~/plugins/axios.js']
}

这样在打包的时候,就会把 axios 打包到 vendor.js 中

四、Vuex 状态树

如果在 store 目录下创建了 index.js,nuxt.js 会根据该目录下的文件创建 Vuex 状态树

// store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import Axios from '~/plugins/axios.js';

Vue.use(Vuex)

const store = () => new Vuex.Store({
 state: {
  author: 'WiseWrong',
  info: ''
 },
 mutations: {
  setInfo (state, val) {
   state.info = val
  }
 },
 actions: {
  loadAboutMeInfo ({commit, state}) {
   return Axios.get(`/about`)
    .then(res => {
     console.log('ajax is success')
     console.log(res.data.info)
     commit('setInfo', res.data.info)
    })
    .catch(err => {
     console.log('error')
    })
  }
 }
})

export default store

Nuxt.js 内置引用了 vuex 模块,不需要额外安装

上面的代码中,我在 actions 中写了一个 loadAboutMeInfo() 方法,用来请求 /api/about 接口

然后在 about.vue 页面中调用

// about.vue 

<template>
 <section class="container">
  <div>
   <img src="~/assets/about.png" alt="">
  </div>
  <h1>{{$store.state.info}}</h1>
 </section>
</template>

<script>
export default {
 fetch({ store }) {
  return store.dispatch('loadAboutMeInfo')
 },
 name: 'about',
 data () {
  return {}
 }
}
</script>

成果演示:

详解Vue基于 Nuxt.js 实现服务端渲染(SSR) 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用JS在浏览器中创建下载文件
Mar 05 Javascript
JavaScript实现的链表数据结构实例
Apr 02 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
Sep 19 Javascript
js实现图片轮播效果
Dec 19 Javascript
JavaScript中数组的22种方法必学(推荐)
Jul 20 Javascript
jQuery实用小技巧_输入框文字获取和失去焦点的简单实例
Aug 25 Javascript
vue2导航根据路由传值,而改变导航内容的实例
Nov 10 Javascript
Vue.js实现数据响应的方法
Aug 13 Javascript
JavaScript实现动态添加、移除元素或属性的方法分析
Jan 03 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
Apr 29 Javascript
JavaScript Canvas编写炫彩的网页时钟
Oct 16 Javascript
Vue使用Three.js加载glTF模型的方法详解
Jun 14 Javascript
express默认日志组件morgan的方法
Apr 05 #Javascript
React Native悬浮按钮组件的示例代码
Apr 05 #Javascript
关于Google发布的JavaScript代码规范你要知道哪些
Apr 04 #Javascript
Angular HMR(热模块替换)功能实现方法
Apr 04 #Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
Apr 04 #Javascript
vue基于mint-ui实现城市选择三级联动
Jun 30 #Javascript
vue中mint-ui的使用方法
Apr 04 #Javascript
You might like
php录入页面中动态从数据库中提取数据的实现
2006/10/09 PHP
php 获取一个月第一天与最后一天的代码
2010/05/16 PHP
php之Memcache学习笔记
2013/06/17 PHP
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
有关JavaScript的10个怪癖和秘密分享
2011/08/28 Javascript
js修改原型的属性使用介绍
2014/01/26 Javascript
JQuery报错Uncaught TypeError: Illegal invocation的处理方法
2015/03/13 Javascript
JavaScript中用getDate()方法返回指定日期的教程
2015/06/09 Javascript
jQuery取得iframe中元素的常用方法详解
2016/01/14 Javascript
JavaScript常用正则验证函数实例小结【年龄,数字,Email,手机,URL,日期等】
2017/01/23 Javascript
利用ES6语法重构React组件详解
2017/03/02 Javascript
自带气泡提示的vue校验插件(vue-verify-pop)
2017/04/07 Javascript
angularjs实现猜数字大小功能
2020/05/20 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
2019/01/30 Javascript
JS实现的字符串数组去重功能小结
2019/06/17 Javascript
vue 移动端记录页面浏览位置的方法
2020/03/11 Javascript
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
在Python中使用base64模块处理字符编码的教程
2015/04/28 Python
python中随机函数random用法实例
2015/04/30 Python
Python动刷新抢12306火车票的代码(附源码)
2018/01/24 Python
基于pip install django失败时的解决方法
2018/06/12 Python
Python3使用SMTP发送带附件邮件
2020/06/16 Python
python pandas dataframe 去重函数的具体使用
2020/07/20 Python
中国电子产品外贸网站:MiniIntheBox
2017/02/06 全球购物
Julep官网:美容产品和指甲油
2017/02/25 全球购物
中东地区为妈妈们提供一切的头号购物目的地:Sprii
2018/05/06 全球购物
Groupon法国官方网站:特卖和网上购物高达-70%
2019/09/02 全球购物
武汉瑞得软件笔试题
2015/10/27 面试题
外语系毕业生找工作的求职信
2013/11/28 职场文书
《宋庆龄故居的樟树》教学反思
2014/04/07 职场文书
2014年十一国庆节活动方案
2014/09/16 职场文书
2017寒假社会实践心得体会范文
2016/01/14 职场文书
高中化学教学反思
2016/02/22 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书
PYTHON使用Matplotlib去实现各种条形图的绘制
2022/03/22 Python