nuxt.js面试篇

介绍

  • 基于 Vue.js 的通用应用框架。
  • SSR 服务端渲染。在服务端生成html发送至客户端
  • 特性:异步数据加载、中间件支持、布局支持等。
  • 优点:有利于SEO,加载速度快,自动配置路由
  • 依赖 node 和 npm npx(npx在NPM版本5.2.0默认安装)

SSR的优势

  1. 更利于SEO。

不同爬虫工作原理类似,只会爬取源码,不会执行网站的任何脚本(Google除外,据说Googlebot可以运行javaScript)。使用了React或者其它MVVM框架之后,页面大多数DOM元素都是在客户端根据js动态生成,可供爬虫抓取分析的内容大大减少(如图一)。另外,浏览器爬虫不会等待我们的数据完成之后再去抓取我们的页面数据。服务端渲染返回给客户端的是已经获取了异步数据并执行JavaScript脚本的最终HTML,网络爬中就可以抓取到完整页面的信息。

  1. 更利于首屏渲染

首屏的渲染是node发送过来的html字符串,并不依赖于js文件了,这就会使用户更快的看到页面的内容。尤其是针对大型单页应用,打包后文件体积比较大,普通客户端渲染加载所有所需文件时间较长,首页就会有一个很长的白屏等待时间。

SSR的局限

  1. 服务端压力较大

本来是通过客户端完成渲染,现在统一到服务端node服务去做。尤其是高并发访问的情况,会大量占用服务端CPU资源;

  1. 开发条件受限

在服务端渲染中,只会执行到componentDidMount之前的生命周期钩子,因此项目引用的第三方的库也不可用其它生命周期钩子,这对引用库的选择产生了很大的限制;

  1. 学习成本相对较高

除了对webpack、React要熟悉,还需要掌握node、Koa2等相关技术。相对于客户端渲染,项目构建、部署过程更加复杂。

实现原理

服务端渲染是先向后端服务器请求数据,然后生成完整首屏html返回给浏览器;而客户端渲染是等js代码下载、加载、解析完成后再请求数据渲染,等待的过程页面是什么都没有的,就是用户看到的白屏。就是服务端渲染不需要等待js代码下载完成并请求数据,就可以返回一个已有完整数据的首屏页面。

初始化项目

  • $ npx create-nuxt-app <项目名> (Nuxt.js团队创建了脚手架工具 create-nuxt-app)
  • $ npm run dev (http://localhost:3000)

配置ip地址端口号

若端口号冲突,或想运行在本机ip,在package.json中添加config配置

{
    
    
	"config":{
    
    
		"nuxt":{
    
    
			"host":"127.0.0.1",
			"port":"1818"	
		}
	}
}

重启项目即可

路由

  • 根据目录结构自动生层router.js

  • 标签跳转

<nuxt-link to="/">跳转首页</nuxt-link>
<nuxt-link :to="{name: 'news',query:{id:'1'}}">跳转新闻页</nuxt-link>
  • params 传值(id会显示地址栏,其他参数不会显示在地址栏)
this.$router.push({
    
     
	name: 'log-id',
	params:{
    
    
		id:12,
		key:value
	}) 
//接受
async asyncData ({
    
     params }) {
    
     
	//  params.id 就是我们传进来的值
}
// 或者 
created () {
    
     
	this.$route.params.xxx
}
  • query传值(所有的参数都会显示在地址栏)
this.$router.push({
    
     
	name: 'log-id',
	query:{
    
    
		id:12,
		key:value
	}) 
//接收
async asyncData ({
    
    app,query }) {
    
     
	//  pquery.id 就是我们传进来的值
}
// 或者 
created () {
    
     
	this.$route.query.xxx
}

动态路由

  • 动态路由是不同的商品详情对应不同的路由地址,便于搜索引擎收录更多,被搜到的几率更大
  • 文件需以 _ 开头
//目录结构:goods文件夹下面动态路由_id文件
--| goods/
-----| _id.vue
-----| index.vue
//index.vue传参
<nuxt-link :to="{name: 'goods-id', params:{id: 1}}">苹果详情</nuxt-link>
<nuxt-link :to=" '/goods/2' ">橘子详情</nuxt-link>
//_id.vue接受参数,并校验参数,若参数不合格,将会跳转到404页面
<script>
	export default {
    
    
		validate({
    
    params}){
    
      //params相当于url中的pathname , 而query是路由携带的参数?type=1
			return \^\d+$\.test(params.id)
		}
	}
</script>

嵌套路由

//路由结构:如下users.vue是父路由,其子路由需要放在与他同名的文件夹下users/

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

父组件(.vue文件) 内增加 用于显示子视图内容

路由切换添加过渡动画

全局动画

  • 在assets文件下新建全局样式文件
  • 在 nuxt.config.js 中配置全局common.css
module.exports = {
    
    
  css: [ '@assets/common.css' ]
}
//common.css
.page-enter-active, .page-leave-active {
    
    
  transition: opacity .5s;
}
.page-enter, .page-leave-active {
    
    
  opacity: 0;
}

单个页面动画

  • 在全局样式里定义单独的过渡样式,然后在所需组件内transition 属性的值设置为 news
//common.css
.news-enter-active, .news-leave-active {
    
    
  transition: all .5s;
  color:red;
}
.news-enter, .news-leave-active {
    
    
  opacity: 0;
  color:blue;
}
//news.vue
export default {
    
    
  transition: 'news'
}

默认模板和默认布局(优选)

默认模板

  • 在根目录下新建一个app.html 文件
<!DOCTYPE html>
<html {
    
    {
    
     HTML_ATTRS }}>
  <head {
    
    {
    
     HEAD_ATTRS }}>
    {
    
    {
    
     HEAD }} //nuxt.config.js中配置的head
  </head>
  <body {
    
    {
    
     BODY_ATTRS }}>
  	//可以在这写一段固定的代码,这样机会在每个页面都显示,例如:
  	<h1>欢迎光临</h1>
    {
    
    {
    
     APP }} //pages中的页面
  </body>
</html>

默认布局

  • 可通过添加根目录下 layouts/default.vue 文件来扩展应用的默认布局
<template>
  //在默认布局中可以定义pc网站的头部和底部,这样就会在每个页面中显示
  <nuxt/>
</template>

自定义布局

  • 在根目录的layouts文件夹下可以定义特殊的布局,例如某个页面需要特殊的头部
// layouts/blog.vue
<template>
  <div>
    <div>我的博客导航栏在这里</div>
    <nuxt/>
  </div>
</template>
  • 在所需要的页面中引入自定义的布局
<template>
<!-- Your template -->
</template>
<script>
export default {
    
    
  layout: 'blog'
  // page component definitions
}
</script>

自定义错误页面

  • 在layouts文件夹爱下创建 error.vue 文件 layouts/error.vue ,当404 或 500 的时候跳转
<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">页面不存在</h1>
    <h1 v-else>应用发生错误异常</h1>
    <nuxt-link to="/">首 页</nuxt-link>
  </div>
</template>

<script>
export default {
    
    
  props: ['error'], //nuxt自己传递的error对象(包含statusCode)
  layout: 'blog' // 你可以为错误页面指定自定义的布局
}
</script>

基本页面

  • asyncData
  • 渲染组件之前异步获取数据,即在服务端获取数据并生成页面
    • 如果在mounted中掉接口,则是在组件渲染之后获取到数据,然后通过js渲染在客户端
    • 返回一个数据对象给当前组件,可以直接使用,无需再data中定义
    • 由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象
  • 同步调用 async/await
  • axios返回的是promise对象,是异步调用
  • async/await是同步调用,在数据返回成功之后,才会执行后边的操作
<template>
  <h1 class="red">Hello {
    
    {
    
     name }}!</h1>
</template>

<script>
export default {
    
    
  data(){
    
    
  	return {
    
    
  		title:this.$route.params.title
  	}
  },
  props:['name'],
  async asyncData (context) {
    
    
  
    // 每次组件加载之前调用,可以在这里调接口,设置组件的数据
    const {
    
     data } = await axios.get('')
    return {
    
     initdata:data } //initdata可以像data重数据一样直接使用
  },
  async fetch ({
    
     store, params }) {
    
    
  // 在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。
    let {
    
     data } = await axios.get('http://my-api/stars')
    store.commit('setStars', data)
  }
  head () {
    
    
    // 每个页面单独设置meta,title和content
    title:this.title,
    meta:{
    
    
		content:'描述',
		name:'',
		hid:'' //唯一标识,跟原来的一样可以覆盖原来的meta
	}
  },
  // and more functionality to discover
  ...
}
</script>

<style>
.red {
    
    
  color: red;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_43848576/article/details/115674982