Nuxt.js開啟SSR渲染
第一節:nuxt.js相關概述
nuxt.js簡單的說是Vue.js的通用框架,最常用的就是用來作SSR(伺服器端渲染).Vue.js是開發SPA(單頁應用)的,Nuxt.js這個框架,用Vue開發多頁應用,並在服務端完成渲染,可以直接用命令把我們製作的vue專案生成為靜態html。
1.那伺服器端渲染到底有什麼好處呢?
主要的原因時SPA(單頁應用)不利於搜尋引擎的SEO操作,Nuxt.js適合作新聞、部落格、電影、諮詢這樣的需要搜尋引擎提供流量的專案。如果你要作移動端的專案,就沒必要使用這個框架了。
2.什麼是SSR?
SSR,即伺服器渲染,就是在伺服器端將對Vue頁面進行渲染生成html檔案,將html頁面傳遞給瀏覽器。
SSR兩個優點:
(1)SEO 不同於SPA的HTML只有一個無實際內容的HTML和一個app.js,SSR生成的HTML是有內容的,這讓搜尋引擎能夠索引到頁面內容。
(2)更快內容到達時間 傳統的SPA應用是將bundle.js從伺服器獲取,然後在客戶端解析並掛載到dom。而SSR直接將HTML字串傳遞給瀏覽器。大大加快了首屏載入時間。
Nuxt.js的官方網站是這樣介紹的:
Nuxt.js 是一個基於 Vue.js 的通用應用框架。 通過對客戶端/服務端基礎架構的抽象組織,Nuxt.js 主要關注的是應用的 UI渲染。
Nuxt.js是特點(優點):
- 基於 Vue.js
- 自動程式碼分層
- 服務端渲染
- 強大的路由功能,支援非同步資料
- 靜態檔案服務
- ES6/ES7 語法支援
- 打包和壓縮 JS 和 CSS
- HTML頭部標籤管理
- 本地開發支援熱載入
- 整合ESLint
- 支援各種樣式前處理器: SASS、LESS、 Stylus等等
第二節:Nuxt環境搭建
1.nuxt.js安裝
在使用npm前你需要安裝Node到系統中。
(1)用npm來安裝vue-cli這個框架。
npm install vue-cli -g
安裝完成後可以使用vue -V 來測試是否安裝成功。(注意:這裡要使用大寫的V,小寫無效)。
(2)使用vue安裝 nuxt
安裝好vue-cli後,就可以使用init命令來初始化Nuxt.js專案。
vue init nuxt/starter
這時候他會在github上下載模版,然後會詢問你專案的名稱叫什麼,作者什麼的,這些完全可以根據自己的愛好填寫。
(3)使用npm install安裝依賴包
npm install
這個過程是要等一會的,如果你這個過程安裝失敗,可以直接誒刪除專案中的node_modules資料夾後,重新npm install進行安裝。
(4)使用npm run dev 啟動服務
(5)在瀏覽器輸入 localhost:3000,可以看到結果。
第三節 :Nuxt目錄結構
第四節:Nuxt常用配置項
1.配置IP和埠
開發中經常會遇到埠被佔用或者指定IP的情況。我們需要在根目錄下的package.json裡對config項進行配置。比如現在我們想把IP配置成127.0.0.1,埠設定1000。
/package.json
"config":{ "nuxt":{ "host":"127.0.0.1", "port":"1000" } },
配置好後,我們在終端中輸入npm run dev,然後你會看到服務地址改為了127.0.0.1:1000.
2.配置全域性CSS
在開發多頁專案時,都會定義一個全域性的CSS來初始化我們的頁面渲染,比如把padding和margin設定成0,網上也有非常出名的開源css檔案normailze.css。要定義這些配置,需要在nuxt.config.js裡進行操作。
比如現在我們要把頁面字型設定為紅色,就可以在assets/css/normailze.css檔案,然後把字型設定為紅色。
/assets/css/normailze.css
html{ color:red; }
/nuxt.config.js
css:['~assets/css/normailze.css'],
設定好後,在終端輸入npm run dev 。然後你會發現字型已經變成了紅色。
3.配置webpack的loader
在nuxt.config.js裡是可以對webpack的基本配置進行覆蓋的,比如現在我們要配置一個url-loader來進行小圖片的64位打包。就可以在nuxt.config.js的build選項裡進行配置。
build: { loaders:[ { test:/\.(png|jpe?g|gif|svg)$/, loader:"url-loader", query:{ limit:10000, name:'img/[name].[hash].[ext]' } } ], /* ** Run ESLint on save */ extend (config, { isDev, isClient }) { if (isDev && isClient) { config.module.rules.push({ enforce: 'pre', test: /\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules)/ }) } } }
第五節:Nuxt的路由配置和引數傳遞
Nuxt.js的路由並不複雜,它給我們進行了封裝,讓我們節省了很多配置環節。
1.簡單路由Demo
我們現在根目錄的pages檔案下新建兩個資料夾,about和news(模仿關於我們和新聞的功能模組)。
(1)在about資料夾下新建index.vue檔案,並寫入下面的程式碼:
<template> <div> <h2>About Index page</h2> <ul> <li><a href="/">Home</a></li> </ul> </div> </template>
(2)在news資料夾下新建index.vue檔案,並寫入下面的程式碼:
<template> <div> <h2>News Index page</h2> <ul> <li><a href="/">Home</a></li> </ul> </div> </template>
(3)修改原來的pages資料夾下的index.vue,刪除沒用的程式碼,寫入下面連結程式碼:
<template> <div> <ul> <li><a href="/">HOME</a></li> <li><a href="/about">ABOUT</a></li> <li><a href="/news">NEWS</a></li> </ul> </div> </template> <script> export default { components: { } } </script> <style> </style>
由於Nuxt.js都為我們作好了,不用寫任何配置程式碼。所以我們可以在頁面上實現相關跳轉。
2. <nuxt-link>
標籤
雖然上面的例子跳轉已經成功,但是Nuxt.js並不推薦這種 <a>
標籤的作法,它為我們準備了 <nuxt-link>
標籤(vue中叫元件)。我們先把首頁的 <a>
標籤替換成 <nuxt-link>,改造如下:
<template> <div> <ul> <li><nuxt-link :to="{name:'index'}">HOME</nuxt-link></li> <li><nuxt-link :to="{name:'about'}">ABOUT</nuxt-link></li> <li><nuxt-link :to="{name:'news'}">NEWS</nuxt-link></li> </ul> </div> </template> <script> export default { components: { } } </script> <style> </style>
我們再次預覽頁面,也是可以進行正常跳轉的,在實際開發中儘量使用標籤的方法跳轉路由。
3.params傳遞引數
路由經常需要傳遞引數,我們可以簡單的使用params來進行傳遞引數,我們現在向新聞頁面(news)傳遞個引數,然後在新聞頁面進行簡單的接收。
(1)我們先修改pages下的Index.vue檔案,給新聞的跳轉加上params引數,傳遞3306。
<template> <div> <ul> <li><nuxt-link :to="{name:'index'}">HOME</nuxt-link></li> <li><nuxt-link :to="{name:'about'}">ABOUT</nuxt-link></li> <li><nuxt-link :to="{name:'news',params:{newsId:3306}}">NEWS</nuxt-link></li> </ul> </div> </template> <script> export default { components: { } } </script> <style> </style>
(2)在news資料夾下的index.vue裡用$route.params.newsId進行接收,程式碼如下。
<template> <div> <h2>News Index page</h2> <p>NewsID:{{$route.params.newsId}}</p> <ul> <li><a href="/">Home</a></li> </ul> </div> </template>
成功實現引數的傳遞。
第六節:Nuxt的動態路由和引數校驗
1.動態路由,其實動態路由就是帶引數的路由。比如我們現在新聞模組下面有很多新聞詳細頁,這時候就需要動態路由的幫助了。
(1)新聞詳細頁面: 我在news資料夾下面新建了 _id.v ue的檔案,以下畫線為字首的Vue檔案就是動態路由,然後在檔案裡邊有 $route.params.id來接收引數。
/pages/news/_id.vue
<template> <div> <h2>News-Content [{{$route.params.id}}]</h2> <ul> <li><a href="/">Home</a></li> </ul> </div> </template>
(2)修改新聞首頁路由
我們在/pages/news/index.vue進行修改,增加兩個詳細頁的路由News-1和News-2。
<template> <div> <h2>News Index page</h2> <p>NewsID:{{$route.params.newsId}}</p> <ul> <li><a href="/">Home</a></li> <li><a href="/news/123">News-1</a></li> <li><a href="/news/456">News-2</a></li> </ul> </div> </template>
程式碼寫好後,開啟npm run dev 進行檢視,我們已經進入了新聞詳細頁,並在詳細頁中取得了傳遞過來的新聞id。
2.引數校驗
進入一個頁面,對引數傳遞的正確性校驗是必須的,Nuxt.js也貼心的為我們準備了校驗方法validate( )。
(1)在接受引數的頁面新增
/pages/news/_id.vue
export default { validate ({ params }) { // Must be a number return /^\d+$/.test(params.id) } }
使用了validate方法,並把params傳遞進去,然後用正則進行了校驗,如果正則返回了true正常進入頁面,如果返回false進入404頁面。
第七節: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資料夾下的主體頁面了。需要注意的是HEAD和APP都需要大寫,如果小寫會報錯的。
注意:如果你建立了預設模板後,記得要重啟伺服器,否則顯示不會成功;但是預設佈局是不用重啟伺服器的。
2.預設佈局
預設模板類似的功能還有預設佈局,但是從名字上你就可以看出來,預設佈局主要針對於頁面的統一佈局使用。它在位置根目錄下的layouts/default.vue。需要注意的是在預設佈局裡不要加入頭部資訊,只是關於 <template>
標籤下的內容統一訂製。
需求:我們在每個頁面的最頂部放入“學習nuxt.js” 這幾個字,看一下在預設佈局裡的實現。
<template> <div> <p>學習nuxt.js</p> <nuxt/> </div> </template>
這裡的 <nuxt/>
就相當於我們每個頁面的內容,你也可以把一些通用樣式放入這個預設佈局裡,但會增加頁面的複雜程度。
總結:要區分預設模版和預設佈局的區別,模版可以訂製很多頭部資訊,包括IE版本的判斷;模版只能定製 <template>
裡的內容,跟佈局有關係。在工作中修改時要看情況來編寫程式碼。
第九節: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的設定非常重要,比如你現在要作個新聞頁面,那為了搜尋引擎對新聞的收錄,需要每個頁面對新聞都有不同的title和meta設定。直接使用head方法來設定當前頁面的頭部資訊就可以了。我們現在要把New-1這個頁面設定成個性的meta和title。
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,讓它根據傳遞值變成獨特的meta和title標籤。
<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)建立遠端資料
在這裡製作一些假的遠端資料,我選擇的網站是myjson.com,它是一個json的簡單倉庫,學習使用是非常適合的。 我們開啟網站,在對話空中輸入JSON程式碼,這個程式碼可以隨意輸入,key和value均採用字串格式建立。
{ "name": "Nuxt", "age": 18, "interest": "I love coding!" }
輸入後儲存,網站會給你一個地址,這就是你這個JSON倉庫的地址了。https://api.myjson.com/bins/1ctwlm
(2)安裝Axios
Vue.js官方推薦使用的遠端資料獲取方式就Axios,所以我們安裝官方推薦,來使用Axios。這裡我們使用npm 來安裝 axios。 直接在終端中輸入下面的命令:
npm install axios --save
1.ansycData的promise方法
我們在pages下面新建一個檔案,叫做ansyData.vue。然後寫入下面的程式碼:
<template> <div> <h1>姓名:{{info.name}}</h1> <h2>年齡:{{info.age}}</h2> <h2>興趣:{{info.interest}}</h2> </div> </template> <script> import axios from 'axios' export default { data(){ return { name:'hello World', } }, asyncData(){ return axios.get('https://api.myjson.com/bins/1ctwlm') .then((res)=>{ console.log(res) return {info:res.data} }) } } </script>
這時候我們可以看到,瀏覽器中已經能輸出結果了。asyncData的方法會把值返回到data中。是元件建立(頁面渲染)之前的動作,所以不能使用this.info,
return {info:res.data}相當於在data中多了一個info:''。
2.ansycData的await方法
當然上面的方法稍顯過時,現在都在用ansyc…await來解決非同步,改寫上面的程式碼。
<template> <div> <h1>姓名:{{info.name}}</h1> <h2>年齡:{{info.age}}</h2> <h2>興趣:{{info.interest}}</h2> </div> </template> <script> import axios from 'axios' export default { data(){ return { name:'hello World', } }, async asyncData(){ let {data}=await axios.get('https://api.myjson.com/bins/8gdmr') return {info: data} } } </script>
第十一節:靜態資源和打包
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>
這時候在npm run dev 下是完全正常的。
2.打包
用Nuxt.js製作完成後,你可以打包成靜態檔案並放在伺服器上,進行執行。
在終端中輸入:
npm run generate
然後在dist資料夾下輸入live-server就可以了。
總結:Nuxt.js框架非常簡單,因為大部分的事情他都為我們做好了,我們只要安裝它的規則來編寫程式碼。