NuxtJS快速入門

RopeHuo發表於2020-09-21

伺服器端渲染(SSR)

知識儲備

  • ES6
  • Nodejs
  • Vue
  • React
  • Angular

什麼是伺服器端渲染

  • 前端渲染:html頁面作為靜態檔案存在,前端請求時後端不對該檔案做任何內容上的修改,直接以資源的方式返回給前端,前端拿到頁面後,根據寫在html頁面上的js程式碼,對該html的內容進行修改。
  • 服務端渲染:前端發出請求後,後端在將HTML頁面返回給前端之前,先把HTML頁面中的特定區域,用資料填充好,再將完整的HTML返回給前端。在SPA場景下,服務端渲染都是針對第一次get請求,它會完整的html給瀏覽器,瀏覽器直接渲染出首屏,用不著瀏覽器端多一個AJAX請求去獲取資料再渲染。

為什麼使用伺服器端渲染

優點:

  • 更好的 SEO,因為傳統的搜尋引擎只會從 HTML 中抓取資料,這會導致前端渲染的頁面無法被抓取。
  • 更快的內容到達時間(time-to-content),特別是對於緩慢的網路情況或執行緩慢的裝置 。頁面首屏時間大概有80%消耗在網路上,剩下的時間在後端讀取資料以及瀏覽器渲染,顯然要優化後面的20%是比較困難的,優化網路時間是效果最明顯的手段。傳統的Ajax請求是先請求js再由js發起資料請求,兩項時間再加上瀏覽器渲染時間才是首屏時間。而SSR能將兩個請求合併為一個。

缺點:

  • 更多的伺服器端負載。
  • 伺服器端和瀏覽器環境差異帶來的問題,例如document等物件找不到的問題。

如何選擇

建議:如果注重SEO的站點,非強互動的頁面,建議用SSR;像後臺管理頁面這類強互動的應用,建議使用前端渲染。

1. Nuxt.js伺服器端渲染

學習目標

  • 瞭解Nuxt.js的作用
  • 掌握Nuxt.js中的路由
  • 掌握layouts、pages以及components的區別
  • 能夠在Nuxt.js專案中使用element-ui
  • 掌握Nuxt.js中非同步獲取資料的方式
  • 完成小專案
  • 掌握SEO的優化

1.1 Nuxt.js入門

1.1.1 什麼是Nuxt.js

Vue服務端渲染官網

Nuxt.js官網

Nuxt.js 是一個基於 Vue.js 的通用應用框架。

1.1.2 第一個Nuxt應用程式

npm i create-nuxt-app -g
create-nuxt-app my-nuxt-demo
cd my-nuxt-demo
npm run dev

1.1.3 檔案結構分析

└─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

1.2 頁面和路由

1.2.1 基本路由

Nuxt.js 依據 pages 目錄結構自動生成 vue-router 模組的路由配置。

假設 pages 的目錄結構如下

└─pages
    ├─index.vue
    └─user
      ├─index.vue
      ├─one.vue

那麼,Nuxt.js 自動生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    }
  ]
}

1.2.2 頁面跳轉

  1. 不要寫成a標籤,因為是重新獲取一個新的頁面,並不是SPA
  2. <nuxt-link to="/users"></nuxt-link>
  3. this.$router.push('/users')

1.2.3 動態路由

  • 在 Nuxt.js 裡面定義帶引數的動態路由,需要建立對應的以下劃線作為字首的 Vue 檔案 或 目錄。
  • 獲取動態引數{{$route.params.id}}

1.2.4 路由引數校驗

Nuxt.js 可以讓你在動態路由對應的頁面元件中配置一個validate方法用於校驗動態路由引數的有效性。該函式有一個布林型別的返回值,如果返回true則表示校驗通過,如果返回false則表示校驗未通過。

validate(data) {
  cosole.log(data)
  return true
}

1.2.5 巢狀路由

  1. 新增一個Vue檔案,作為父元件
  2. 新增一個與父元件同名的資料夾來存放子檢視元件
  3. 在父檔案中,新增元件,用於展示匹配到的子檢視

1.3 layouts & pages & components

1.3.1 建立layout

  1. 去layouts資料夾下面新建一個新的layout元件,例如teachers.vue,並在這個元件中新增元件,這樣,所有和teachers相關的頁面都會有公共的layout
  2. 給需要用到teachers.vue的元件新增layout屬性,並指定需要使用的layout,例如:layout: 'teachers'

1.3.2 建立特殊layout : error

layouts資料夾下面新建error.vue,error是關鍵字

1.3.3 新建一個元件

在components資料夾下面新建一個Header.vue元件
引入元件,注意路徑的~符號,表示根目錄
layout中也能使用元件

1.3.4 樣式配置

nuxt.config.js中設定全域性css樣式的檔案路徑

1.4 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']
    }
    

1.5 非同步資料

Nuxt.js 擴充套件了 Vue.js,增加了一個叫 asyncData 的方法,使得我們可以在設定元件的資料之前能非同步獲取或處理資料。asyncData方法會在元件(限於頁面元件)每次載入之前被呼叫。它可以在服務端或路由更新之前被呼叫。所以需要注意這個函式中不能使用this

注意:常規寫法如果在created鉤子中寫非同步,是在客戶端渲染的而不是在服務端

使用方法:asyncData(context, callback) {callback(null, data)}

context.route.params.xxx獲取引數

callback(new Error(), data)渲染出錯的頁面

注意:這個方法在伺服器端執行和在客戶端執行的區別

1.6 axios的使用

安裝npm install --save axios

使用

import axios from 'axios'

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

為防止重複打包,在nuxt.config.js中配置

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

nuxt中axios如何跨域獲取資料

  • 參考文件:https://axios.nuxtjs.org/
  • 參考文件:https://github.com/nuxt-community/proxy-module
  • ajax 跨域問題
    • 首先推薦:CORS 處理跨域,只需要服務端做一些配置就好了,客戶端可以直接使用
    • 其次:配置服務端(任何Web伺服器)代理
      • Apache
      • nginx
      • tomcat
      • Node
      • webpack 中的 webpack-dev-server
    • nuxt 中使用 axios 發請求
      • 配置 nuxt
      • nuxt 提供了一個模組 @nuxtjs/axios
      • 這個模組內建了 Node 的一個 http-proxy-middleware 中介軟體

1.7 小案例(豆瓣電影列表)

介面

http://api.douban.com/v2/movie/top250

http://api.douban.com/v2/movie/top250?start=0&count=100

獲取電影列表:http://localhost:3301/in_theaters (in_theaters可以替換為coming_soon及top250)

獲取電影詳情:http://localhost:3301/in_theaters/1?_embed=details

http://localhost:3301/in_theaters
http://localhost:3301/coming_soon
http://localhost:3301/top250
http://localhost:3301/details

1.7.1 豆瓣電影首頁建立

1.7.2 豆瓣電影列表頁面建立

1.7.3 電影詳情頁面

1.8 SEO優化

1.8.1 全域性

在nuxt.config.js配置檔案中修改

head: {
	title: pkg.name,
	meta: [
		{ charset: 'utf-8' },
		{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
		{ hid: 'description', name: 'description', content: pkg.description }
	],
  link: [
    { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
  ]
},

1.8.2 區域性

head(){
  return{
    title:'豆瓣電影',
    meta:[{
    'name':'keywords',
    'content': '電影、經典電影、熱映、電視劇、美劇、影評、電影院、電影票、排行、推薦'
    }]
  }
}