欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

超详细的 Nuxt 入门、实践与总结

最编程 2024-07-18 07:34:32
...

Nuxt入门&实践总结

一、nuxt简介及安装

Nuxt.js 官方介绍:

Nuxt.js 是一个基于 Vue.js 的通用应用框架。通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js,Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据加载、中间件支持、布局支持等。

1、nuxt简介

1)、那服务器端渲染的益处

nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染)Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用Vue开发多页应用,并在服务端完成渲染,可以直接用命令把我们制作的vue项目生成为静态html

主要的原因时SPA(单页应用)不利于搜索引擎的SEO操作,Nuxt.js适合作新闻、博客、电影、咨询这样的需要搜索引擎提供流量的项目。如果你要作移动端的项目,就没必要使用这个框架了。

2)、什么是SSR?

  • SSR 就是 服务器渲染,什么是 服务器渲染?
  • 由 服务器 组装好 DOM 元素,生成 HTML 字符串给到浏览器,也就是在浏览器里面是可以看到整个页面的 DOM 源码的。

3)、SSR解决的问题:

  • SEO:搜索引擎的优先爬取级别是页面的 HTML 结构,当我们使用 SSR 的时候,服务端已经生成了与业务相关联的 HTML,这样的信息对于 SEO 是很友好的。

  • 内容呈现:客户端无需等待所有的 JS 文件加载完成即可看见渲染的业务相关视图(压力来到了服务端这边,这也是需要做权衡的地方,需要区分哪些由服务端渲染,哪些可以交给客户端)。

4)、SSR相关的弊端:

  • 代码兼容:对于开发人员来讲,需要去兼容代码在不同环境的运行 Vue SSR 所需要的服务端环境是 Node,有一些客户端的对象,比如 domwindows 之类的则无法使用。

  • 服务器负载:相对于前后端分离模式下服务器只需要提供静态资源来说,SSR 需要的服务器负载更大,所以在项目中使用 SSR 模式要慎重,比如一整套图表页面,相对于服务端渲染,可能用户不会在乎初始加载的前几秒,可以交由客户端使用类似于骨架屏,或者懒加载之类的提升用户体验。

5)、Vue 与 Vue SSR 与 原生 HTML 页面源码区别对比

  • 在网页上右键查看源码:Vue SSR与 原生HTML是可以看到源码标签的

  • 在认识SSR之前,首先对CSRSSR之间做个对比。

    • 首先看一下传统的web开发,传统的web开发是,客户端向服务端发送请求,服务端查询数据库,拼接HTML字符串(模板),通过一系列的数据处理之后,把整理好的HTML返回给客户端,浏览器相当于打开了一个页面。这种比如我们经常听说过的jspPHPaspx也就是传统的MVC的开发。

    • SPA应用,到了VueReact,单页面应用优秀的用户体验,逐渐成为了主流,页面整体是javaScript渲染出来的,称之为客户端渲染CSRSPA渲染过程。由客户端访问URL发送请求到服务端,返回HTML结构(但是SPA的返回的HTML结构是非常的小的,只有一个基本的结构,如第一段代码所示)。客户端接收到返回结果之后,在客户端开始渲染HTML,渲染时执行对应javaScript,最后渲染template,渲染完成之后,再次向服务端发送数据请求,注意这里时数据请求,服务端返回json格式数据。客户端接收数据,然后完成最终渲染。(请求两次,百度搜索引擎不能抓取SPA页面的数据)

    • SPA虽然给服务器减轻了压力,但是也是有缺点的:

      • 首屏渲染时间比较长:必须等待JavaScript加载完毕,并且执行完毕,才能渲染出首屏。
      • SEO不友好:爬虫只能拿到一个div元素,认为页面是空的,不利于SEO。 为了解决如上两个问题,出现了SSR解决方案,后端渲染出首屏的DOM结构返回,前端拿到内容带上首屏,后续的页面操作,再用单页面路由和渲染,称之为服务端渲染(SSR)。
  • SSR渲染流程是这样的,客户端发送URL请求到服务端,服务端读取对应的url的模板信息,在服务端做出html和数据的渲染,渲染完成之后返回html结构,客户端这时拿到的之后首屏页面的html结构。所以用户在浏览首屏的时候速度会很快,因为客户端不需要再次发送ajax请求。并不是做了SSR我们的页面就不属于SPA应用了,它仍然是一个独立的spa应用。

  • SSR是处于CSRSPA应用之间的一个折中的方案,在渲染首屏的时候在服务端做出了渲染,注意仅仅是首屏,其他页面还是需要在客户端渲染的,在服务端接收到请求之后并且渲染出首屏页面,会携带着剩余的路由信息预留给客户端去渲染其他路由的页面。

6)、Nuxt.js是特点(优点):

  • 基于`Vue``
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • EcmaScript6EcmaScript7的语法支持
  • 打包和压缩JavaScriptCSS
  • HTML头部标签管理
  • 本地开发支持热加载
  • 集成ESLint
  • 支持各种样式预编译器SASSLESS等等
  • 支持HTTP/2推送

2、nuxt安装

1)、安装

// 全局安装npx
npm install npx -g

// 使用npx创建nuxt项目
npx create-nuxt-app 项目名

Project name                                //  项目名称
Project description                         //  项目描述
Use a custom server framework               //  选择服务器框架
Choose features to install                  //  选择安装的特性
Use a custom UI framework                   //  选择UI框架
Use a custom test framework                 //  测试框架
Choose rendering mode                       //  渲染模式
Universal                                   //  渲染所有连接页面
Single Page App                             //  只渲染当前页面

当一个客户端请求进入的时候,服务端有通过nuxtServerInit这个命令执行在Storeaction中,在这里接收到客户端请求的时候,可以将一些客户端信息存储到Store中,也就是说可以把在服务端存储的一些客户端的一些登录信息存储到Store中。之后使用了中间件机制,中间件其实就是一个函数,会在每个路由执行之前去执行,在这里可以做很多事情,或者说可以理解为是路由器的拦截器的作用。然后再validate执行的时候对客户端携带的参数进行校验,在asyncDatafetch进入正式的渲染周期,asyncData向服务端获取数据,把请求到的数据合并到Vue中的data

2)、目录结构

└─my-nuxt-demo
  ├─.nuxt               // Nuxt自动生成,临时的用于编辑的文件,build
  ├─assets              // 用于组织未编译的静态资源如LESS、SASS或JavaScript,对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中
  ├─components          // 用于自己编写的Vue组件,比如日历组件、分页组件
  ├─layouts             // 布局目录,用于组织应用的布局组件,不可更改
  ├─middleware          // 用于存放中间件
  ├─node_modules
  ├─pages               // 用于组织应用的路由及视图,Nuxt.js根据该目录结构自动生成对应的路由配置,文件名不可更改
  ├─plugins             // 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。
  ├─static              // 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时                            候,该目录下的文件会映射至应用的根路径 / 下。文件夹名不可更改。
  └─store               // 用于组织应用的Vuex 状态管理。文件夹名不可更改。
  ├─.editorconfig       // 开发工具格式配置
  ├─.eslintrc.js        // ESLint的配置文件,用于检查代码格式
  ├─.gitignore          // 配置git忽略文件
  ├─nuxt.config.js      // 用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。文件名不可更改。
  ├─package-lock.json   // npm自动生成,用于帮助package的统一设置的,yarn也有相同的操作
  ├─package.json        // npm 包管理配置文件
  ├─README.md

3)、配置文件nuxt.config.js

注意:

  • export default在一个模块中只能有一个,当然也可以没有。export在一个模块中可以有多个。
  • export default的对象、变量、函数、类,可以没有名字。export的必须有名字。
  • export default对应的importexport有所区别
  • module变量代表当前模块。这个变量是一个对象,module对象会创建一个叫exports的属性,这个属性的默认值是一个空的对象

Node为每个模块提供一个exports变量,指向module.exports,两个是相等的关系,但又不是绝对相当的关系,module.exports可以直接导出一个匿名函数或者一个值,但是export的必须有名字,故不行,export defaultexport名字可以

const pkg = require('./package')
module.exports = {
  mode: 'universal',    // 当前渲染使用模式,分为universal和spa,既然是nuxt开发,那就是universal
  // 全局页头配置 (https://go.nuxtjs.dev/config-head)
  head: {       // 页面head配置信息
    title: pkg.name,        // title
    meta: [         // meat
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
      // 这里可以添加网站验证码信息
      // { name: 'google-site-verification', content: 'xxx' },
      // 实测百度无法通过验证,此问题还没解决
      // { name: 'baidu-site-verification', content: 'code-xxx' },
    ],
    link: [  // favicon,若引用css不会进行打包处理
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  // nuxt 加载进度条配置 (https://zh.nuxtjs.org/api/configuration-loading)
  loading: { color: '#fff' },   // 页面进度条
  // 全局css (https://go.nuxtjs.dev/config-css)
  css: [    // 全局css(会进行webpack打包处理)
    'element-ui/lib/theme-chalk/index.css'  
  ],
   // 配置后,会在页面渲染之前加载 (https://go.nuxtjs.dev/config-plugins)
  plugins: [        // 插件
    '@/plugins/element-ui'
  ],
  // 工具module (https://go.nuxtjs.dev/config-modules)
  modules: [        // 模块
    '@nuxtjs/axios',
  ],
 // 如果添加了@nuxt/axios则会需要此配置来覆盖默认的一些配置 (https://go.nuxtjs.dev/config-axios)
  axios: {
    https: true, 
    progress: true, // 是否显示加载进度条
    credentials: true, // 请求携带cookie
    baseURL: 'https://www.abeille.top/api',
    proxy: true // 请求代理,开发中跨域问题解决方法
  },
  // 打包配置 (https://go.nuxtjs.dev/config-build)
  build: {      // 打包
    transpile: [/^element-ui/],
    extend(config, ctx) {       // webpack自定义配置
    }
  }
}

4)、Nuxt运行命令

{
  "scripts": {
    //  开发环境
    "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
    //  打包
    "build": "nuxt build",
    //  在服务端运行
    "start": "cross-env NODE_ENV=production node server/index.js",
    //  生成静态页面
    "generate": "nuxt generate"
  }
}

二、nuxt常用配置

1、配置IP和端口

第一种 nuxt.config.js :

module.exports = { 
    server: { 
        port: 8000, 
        host: '127.0.0.1' 
    } 
} 

第二种 package.json :

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

2、配置全局CSS

在开发多页项目时,都会定义一个全局的CSS来初始化我们的页面渲染,比如把paddingmargin设置成0,网上也有非常出名的开源css文件normailze.css。要定义这些配置,需要在nuxt.config.js里进行操作。

比如现在我们要把页面字体设置为红色,就可以在assets/css/common.css文件,然后把字体设置为红色。

/assets/css/common.css

html{ 
    color:red; 
} 
body { 
    margin:0; 
    padding:0;
}

/nuxt.config.js

css:['~assets/css/normailze.css']

设置好后,在终端输入pm run dev。然后你会发现字体已经变成了红色。

三、Nuxt的路由配置和参数传递

1、路由

Nuxt.js的路由并不复杂,它给我们进行了封装,让我们节省了很多配置环节。

Nuxt会自动生成路由,故而只需使用<nuxt-link :to=""> </nuxt-link>,而非<router-link :to=""> </router-link>

页面跳转方式:

  • 不要写成a标签,因为是重新获取一个新的页面,并不是SPA
  • <nuxt-link to="/users"></nuxt-link>
  • this.$router.push('/users')

动态路由:

  • Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
  • 获取动态参数{{$route.params.id}}

2、路由传参

this.$route.query.key的方式参数显示在地址栏上, 但是并不是我们想要的,:id?id=``?所以建议还是尽量使用router-link来实现跳转来解决地址栏的变化,更方便网站的优化

1)、nuxt-link中传递参数

方式一
传参:
<nuxt-link :to="{path:'/about',query:{index:id}}" target="_blank" ><nuxt-link>
地址栏显示:
loaclhost:3000/about/id
接收地址栏参数:
this.$route.query.index
 
方式二
传参: 
<nuxt-link target="_blank" :to="{name: 'log-id', params:{id: n.id,key:value}}"></nuxt-link>
地址栏显示:
loaclhost:3000/about/id
接收:
async asyncData ({ params }) { //  params.id 就是我们传进来的值}// 或者 created () { this.$route.params.xxx}`

2)、在方法中传递

方式一
跳转:
getDescribe(id) {
    // 直接调用$router.push 实现携带参数的跳转
    this.$router.push({
      path: `/describe/${id}`,
    })   
接收:
$route.params.id

方式二
注意:
页面之间的跳转使用query 不然的话刷新页面后会找不到参数
跳转:
 this.$router.push({
          path: '/describe',
          query: {
            id: id
          }
})
接收:
$route.query.id

3、路由传参校验

Nuxt.js 可以让你在动态路由对应的页面组件中配置一个validate方法用于校验动态路由参数的有效性。该函数有一个布尔类型的返回值,如果返回true则表示校验通过,如果返回false则表示校验未通过。

export default {
  // nuxt中使用validate方法进行路由参数校验,这个方法必须返回一个布尔值,为true表示校验通过,为false表示校验失败。注意validate不能写到methods属性中。
  validate(obj) {
    // console.log(obj);
    // return true
    return /^\d+$/.test(obj.params.id)
  }
}

4、路由嵌套

注意:

nuxt框架中,在 nuxt.config.jscomponents: true已开启了组件自动导入,故而不需要在vue文件中通过importcomponents来导入组件,只需在template中写入相应组件的组件名即可

  • 添加一个Vue文件,作为父组件
  • 添加一个与父组件同名的文件夹来存放子视图组件
  • 在父文件中,添加组件,用于展示匹配到的子视图

5、Nuxt的路由动画效果

路由的动画效果,也叫作页面的更换效果。Nuxt.js提供两种方法为路由提供动画效果,一种是全局的,一种是针对单独页面制作。

1)、全局路由动画

全局动画默认使用page来进行设置,例如现在我们为每个页面都设置一个进入和退出时的渐隐渐现的效果。我们可以先在根目录的assets/css下建立一个normailze.css文件。

(1)添加样式文件

/assets/css/normailze.css(没有请自行建立)

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

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

(2)文件配置

然后在nuxt.config.js里加入一个全局的css文件就可以了。

css:['assets/css/main.css']

这时候在页面切换的时候就会有2秒钟的动画切换效果了,但是你会发现一些页面是没有效果的,这是因为你没有是<nuxt-link>组件来制作跳转链接。你需要进行更改。

<li><nuxt-link :to="{name:'news-id',params:{id:123}}">News-1</nuxt-link></li>

2)、单独设置页面动效

想给一个页面单独设置特殊的效果时,我们只要在css里改变默认的page,然后在页面组件的配置中加入transition字段即可。例如,我们想给about页面加入一个字体放大然后缩小的效果,其他页面没有这个效果。

(1)在全局样式assets/main.css 中添加以下内容

.test-enter-active, .test-leave-active {
    transition: all 2s;
    font-size:12px;
}
.test-enter, .test-leave-active {
    opacity: 0;
    font-size:40px;
}

(2)然后在about/index.vue组件中设置

export default {
  transition:'test'
}

这时候就有了页面的切换独特动效了。

总结:在需要使用的页面导入即可。

四、Nuxt的默认模版和默认布局

在开发应用时,经常会用到一些公用的元素,比如网页的标题是一样的,每个页面都是一模一样的标题。这时候我们有两种方法,第一种方法是作一个公用的组件出来,第二种方法是修改默认模版。这两种方法各有利弊,比如公用组件更加灵活,但是每次都需要自己手动引入;模版比较方便,但是只能每个页面都引入。

1、默认模板

Nuxt为我们提供了超简单的默认模版订制方法,只要在根目录下创建一个app.html就可以实现了。现在我们希望每个页面的最上边都加入“学习nuxt.js” 这几个字,我们就可以使用默认模版来完成。

app.html中:

<!DOCTYPE html>
<html lang="en">
<head>
   {{ HEAD }}
</head>
<body>
    <p>学习nuxt.js</p>
    {{ APP }}
</body>
</html>

这里的{{ HEAD }}读取的是nuxt.config.js里的信息,{{APP}} 就是我们写的pages文件夹下的主体页面了。需要注意的是HEADAPP都需要大写,如果小写会报错的。

注意:如果你建立了默认模板后,记得要重启服务器,否则显示不会成功;但是默认布局是不用重启服务器的。

2.默认布局 默认模板类似的功能还有默认布局,但是从名字上你就可以看出来,默认布局主要针对于页面的统一布局使用。它在位置根目录下的layouts/default.vue。需要注意的是在默认布局里不要加入头部信息,只是关于<template>标签下的内容统一订制。

需求:我们在每个页面的最顶部放入“学习nuxt.js” 这几个字,看一下在默认布局里的实现。

<template>
  <div>
    <p>学习nuxt.js</p>
    <nuxt/>
  </div>
</template>

这里的<nuxt/>就相当于我们每个页面的内容,你也可以把一些通用样式放入这个默认布局里,但会增加页面的复杂程度。

总结:要区分默认模版和默认布局的区别,模版可以订制很多头部信息,包括IE版本的判断;模版只能定制<template>里的内容,跟布局有关系。在工作中修改时要看情况来编写代码。

五、Nuxt插件的使用

1、ElementUI使用

(1)、下载npm i element-ui -S

(2)、在plugins文件夹下面,创建ElementUI.js文件

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

(3)、在nuxt.config.js中添加配置

css: [
  'element-ui/lib/theme-chalk/index.css'
],
plugins: [
  {src: '~/plugins/ElementUI', ssr: true }
],
build: {
  vendor: ['element-ui']
}

2、Element按需引入

1)、下载依赖:

# 先下载element-ui

npm install element-ui --save

# 如果使用按需引入,必须安装babel-plugin-component(官网有需要下载说明,此插件根据官网规则不同,安装插件不同)

npm install babel-plugin-component --save-dev

安装好以后,按照nuxt.js中的规则,你需要在 plugins/ 目录下创建相应的插件文件

文件根目录创建(或已经存在)plugins/目录,创建名为:element-ui.js的文件,内容如下:

import Vue from 'vue'

import { Button } from 'element-ui'    //引入Button按钮

export default ()=>{
    Vue.use(Button)
}

2)、引入插件

nuxt.config.js中,添加配置为:plugins

css:[ 
    'element-ui/lib/theme-chalk/index.css' 
], 
plugins:[ 
    '~/plugins/element-ui' 
]

默认为:开启SSR,采用服务端渲染,也可以手动配置关闭SSR,配置为:

css:[
    'element-ui/lib/theme-chalk/index.css'
],
plugins:[
    {
        src:'~/plugins/element-ui',
        ssr:false    //关闭ssr
    }
]

3)、配置babel选项

nuxt.config.js中,配置在build选项中,规则为官网规则:

build: {
      babel:{        //配置按需引入规则
          "plugins":[
              [
                  "component",
                  {
                      "libraryName":"element-ui",
                      "styleLibraryName":"theme-chalk"
                  }
              ]
          ]
      },
    /*
     ** Run ESLINT on save
     */
    extend (config, ctx) {
      if (ctx.isClient) {
        config.module.rules.push({
           enforce: 'pre',
           test: /\.(js|vue)$/,
           loader: 'eslint-loader',
           exclude: /(node_modules)/
        })
      }
    }
 }

3、axios的使用

(1)、安装npm install --save axios

(2)、使用

import axios from 'axios'

asyncData(context, callback) {
  axios.get('http://localhost:3301/in_theaters')
    .then(res => {
      console.log(res);
      callback(null, {list: res.data})
    })
}

(3)、为防止重复打包,在nuxt.config.js中配置

module.exports = {
  build: {
    vendor: ['axios']
  }
}

4、vuex的使用

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

Nuxt.js 会找到应用根目录下的 store 目录,如果该目录存在,它将做以下的事情:

  • 引用 vuex 模块
  • 将 vuex 模块 加到 vendors 构建配置中去
  • 设置 Vue 根实例的 store 配置项

Nuxt.js 支持两种使用 store 的方式,你可以择一使用:

  • 模块方式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块)
  • 普通方式: store/index.js 返回一个 Vuex.Store 实例(官方不推荐)

模块方式

状态树还可以拆分成为模块,store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块

使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,而应该直接将 state、mutations 和 actions暴露出来:

index.js

export const state = () => ({
    articleTitle: [],
    labelList: []
})

export const mutations = {
    // 设置热门文章标题
    updateArticleTitle(state, action) {
        state.articleTitle = action
    },
    // 设置标签列表数据
    updateLabel(state, action){
        state.labelList = action
    }
}

export const actions = {
    // 获取热门文章标题
    fetchArticleTitle({ commit }) {
        return this.$axios
            .$get('http://localhost:3000/article/title')
            .then(response => {
                commit('updateArticleTitle', response.data)
            })
    },
    // 获取标签
    fetchLabel({ commit }) {
        return this.$axios
            .$get('http://localhost:3000/label/list')
            .then(response => {
                commit('updateLabel', response.data)
            })
    }
}

index.vue
fetch方法中触发异步提交状态事件

<script>
import ArticleList from '~/components/archive/list'
import Banner from '~/components/archive/banner'


export default {
  components: {
    ArticleList,
    Banner,
  },
  async asyncData({ app }){
    //获取文章列表数据
    let article = await app.$axios.get(`http://localhost:3000/article/list?pageNum=1&pageSize=5`)
    return {articleList: article.data.data}
  },
  async fetch({ store }) {
      return Promise.all([
          store.dispatch('common/fetchArticleTitle'),
          store.dispatch('common/fetchLabel')
      ])
  },
  computed: {

  },
  methods: {

  }
}
</script>

对应组件中通过computed 方法获取状态数据

computed: {
      labelList(){
            return this.$store.state.common.labelList
      }
}

六、Nuxt的错误页面和个性meta设置

当用户输入路由错误的时候,我们需要给他一个明确的指引,所以说在应用程序开发中404页面是必不可少的。Nuxt.js支持直接在默认布局文件夹里建立错误页面。

1、建立错误页面

在根目录下的layouts文件夹下建立一个error.vue文件,它相当于一个显示应用错误的组件。

<template>
  <div>
      <h2 v-if="error.statusCode==404">404页面不存在</h2>
      <h2 v-else>500服务器错误</h2>
      <ul>
          <li><nuxt-link to="/">HOME</nuxt-link></li>
      </ul>
  </div>
</template>

<script>
export default {
  props:['error']
}
</script>

代码用v-if进行判断错误类型,需要注意的是这个错误是你需要在<script>里进行声明的,如果不声明程序是找不到error.statusCode的。

这里我也用了一个<nuxt-link>的简单写法直接跟上路径就可以了。

2、个性meta设置

页面的Meta对于SEO的设置非常重要,比如你现在要作个新闻页面,那为了搜索引擎对新闻的收录,需要每个页面对新闻都有不同的titlemeta设置。直接使用head方法来设置当前页面的头部信息就可以了。我们现在要把New-1这个页面设置成个性的metatitle

(1)、我们先把pages/news/index.vue页面的链接进行修改一下,传入一个title,目的是为了在新闻具体页面进行接收title,形成文章的标题。

/pages/news/index.vue

<li><nuxt-link :to="{name:'news-id',params:{id:123,title:'nuxt.com'}}">News-1</nuxt-link></li>

(2)、第一步完成后,我们修改/pages/news/_id.vue,让它根据传递值变成独特的metatitle标签。

<template>
  <div>
      <h2>News-Content [{{$route.params.id}}]</h2>
      <ul>
        <li><a href="/">Home</a></li>
      </ul>
  </div>
</template>

<script>
export default {
  validate ({ params }) {
    // Must be a number
    return /^\d+$/.test(params.id)
  },
  data(){
    return{
      title:this.$route.params.title,
    }
  },
//独立设置head信息
  head(){
      return{
        title:this.title,
        meta:[
          {hid:'description',name:'news',content:'This is news page'}
        ]
      }
    }
}
</script>

注意:为了避免子组件中的meta标签不能正确覆盖父组件中相同的标签而产生重复的现象,建议利用 hid 键为meta标签配一个唯一的标识编号。

七、asyncData方法获取数据

Nuxt.js贴心的为我们扩展了Vue.js的方法,增加了anyncData,异步请求数据。

1、三种方式

Nuxt.js 提供了几种不同的方法来使用 asyncData 方法,你可以选择自己熟悉的一种来用:

  • 返回一个 Promise, nuxt.js会等待该Promise被解析之后才会设置组件的数据,从而渲染组件
  • 使用 async 或 await
  • 使用回调函数

返回Promise

export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        return { title: res.data.title }
      })
  }
}

使用async或await

export default {
  async asyncData ({ params }) {
    const { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}

使用回调函数

export default {
  asyncData ({ params }, callback) {
    axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        callback(null, { title: res.data.title })
      })
  }
}

安装Axios Vue.js官方推荐使用的远程数据获取方式就Axios,所以我们安装官方推荐,来使用Axios。这里我们使用npm 来安装 axios。 直接在终端中输入下面的命令: npm install axios --save

2、ansycData的promise方法

我们在pages下面新建一个文件,叫做ansyData.vue。然后写入下面的代码:

<script>
import axios from 'axios'
export default {
  data(){
     return {
         name:'hello World',
     }
  },
  asyncData(){
      return axios.get('接口')
      .then((res)=>{
          console.log(res)
          return {info:res.data}
      })
  }
}
</script>

asyncData的方法会把值返回到data中。是组件创建(页面渲染)之前的动作,所以不能使用this.info

return的重要性

一定要return出去获取到的对象,这样就可以在组件中使用,这里返回的数据会和组件中的data合并。这个函数不光在服务端会执行,在客户端同样也会执行。

3、ansycData的promise并发应用

async asyncData(context) {
  let [newDetailRes, hotInformationRes, correlationRes] = await Promise.all([
    axios.post('http://www.huanjingwuyou.com/eia/news/detail', {
      newsCode: newsCode
    }),
    axios.post('http://www.huanjingwuyou.com/eia/news/select', {
      newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
      start: 0, // 从第0条开始
      pageSize: 10,
      newsRecommend: true
    }),
    axios.post('http://www.huanjingwuyou.com/eia/news/select', {
      newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
      start: 0, // 从第0条开始
      pageSize: 3,
      newsRecommend: false
    })
  ])
  return {
    newDetailList: newDetailRes.data.result,
    hotNewList: hotInformationRes.data.result.data,
    newsList: correlationRes.data.result.data,
    newsCode: newsCode,
    newsType: newsType
  }
}

4、ansycData的await方法

当然上面的方法稍显过时,现在都在用ansyc…await来解决异步,改写上面的代码。

<script>
import axios from 'axios'
export default {
  data(){
     return {
         name:'hello World',
     }
  },
  async asyncData(){
      let {data}=await axios.get('接口')
      return {info: data}
  }
}
</script>

5、注意事项+生命周期:

  • asyncData 方法会在组件(限于页面组件)每次加载之前被调用
  • asyncData 可以在服务端或路由更新之前被调用
  • 第一个参数被设定为当前页面的上下文对象
  • Nuxt会将 asyncData 返回的数据融合到组件的data方法返回的数据一并返回给组件使用
  • 对于 asyncData 方式是在组件初始化前被调用的,所以在方法内饰没办法通过this来引用组件的实例对象

八、静态资源和打包

1、静态资源

(1)直接引入图片

在网上任意下载一个图片,放到项目中的static文件夹下面,然后可以使用下面的引入方法进行引用

<div><img src="~static/logo.png" /></div>

“~”就相当于定位到了项目根目录,这时候图片路径就不会出现错误,就算打包也是正常的。

(2)CSS引入图片

如果在CSS中引入图片,方法和html中直接引入是一样的,也是用“~”符号引入。

<style>
  .diss{
    width: 300px;
    height: 100px;
    background-image: url('~static/logo.png')
  }
</style>

																				
															

推荐阅读