亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

服務端預渲染之Nuxt(使用篇)

2024-05-06 16:49:39
字體:
來源:轉載
供稿:網友

現在大多數開發都是基于 Vue 或者 React 開發的,能夠達到快速開發的效果,也有一些不足的地方, Nuxt 能夠在服務端做出渲染,然后讓搜索引擎在爬取數據的時候能夠讀到當前頁面。

首先要說明一點,我們可以認為我們所編寫的 Vue 項目是一個服務端的項目,雖然編寫的還是 Vue 項目,但是 Nuxt 是基于服務器環境的。

就簡單的說一下 Nuxt 使用?;A只是還是以官方文檔為主,如果博客中哪里有問題,歡迎留言指正。

說了這么多,進入正題。

路由

與傳統的 Vue 項目不同的是,我們在使用 Vue 的時候需要配置 Vue-Router 信息,在 Nuxt 有很關鍵的一點就是 約定優于配置 。 page 目錄下的所有 *.vue 文件會自動生成路由配置。

在項目初始化之后,在 pages 下面默認有一個 index.vue 文件,所以當我們使用 npm run dev 啟動項目,并且使用 http://localhost:3000/ 訪問的時候能夠正常訪問路由。

為了證實上面這一點,在 pages 下面創建一個信息 about.vue 文件,并且 http://localhost:3000/about 去訪問剛剛寫的頁面。我們可以按照正常的 Vue 頁面去開發就好了。

page目錄

├─page│ ├─index.vue└───└─about.vue

about.vue

<template> <div>  <h2>This About</h2> </div></template>

創建完成之后使用 http://localhost:3000/about 訪問該頁面,頁面能夠正常的渲染出來了。就會看到 This About 顯示在頁面中。

做到這一步之后就應該實現路由之間的跳轉了。 Vue 開發過程中,都是使用 router-link 標簽完成路由之間的跳轉,在 Nuxt 也同樣可以使用 router-link ,但是 Nuxt 仍然推薦使用 nuxt-link , nuxt-link 與 router-link 的功能是等效的。

可能會有一些疑問,既然是等效的,為什么要使用 nuxt-link 呢?官方文檔中是這樣說的:將來我們會為 nuxt-link 組件增加更多的功能特性,例如資源預加載,用于提升 nuxt.js 應用的響應速度。顯然嘛,官方不會無緣無故的就做出這么一個東西來,肯定實在其中做了很多的優化工作的。

稍微的改動一下剛才的 about.vue 在里面添加兩個標簽,一個使用 nuxt-link ,一個使用 router-link 看下能否正常完成跳轉。

about.vue - 更改后

<template> <div>  <h2>This About</h2>  <nuxt-link to="/">首頁</nuxt-link>  <router-link to="/">首頁</router-link> </div></template>

既然從路由開始那么就不得不說到子路由,全局路由守衛這些都些在路由中經常用到的應該怎么處理?該怎么解決這些問題。

前面既然說到了 Nuxt 會把 pages 文件夾下面的所有 *.vue 文件編譯成路由,那么子路由需要使用文件夾嵌套才行。

接下來就嘗試一下。首先要更改一下 pgeas 目錄結構。

page目錄

├─page│ ├─about│ │ ├─detail.vue│ │ └─index.vue└───└─index.vue

注意上面的 about 目錄,是 index.vue 而并非 about.vue ,這里的 index.vue 指的是 about 路由下的首頁,也就是最開始放在與 index.vue 同級的那個 about.vue 是一樣的效果。

about/index.vue

<template> <div>  <h2>This About</h2>  <nuxt-link to="/">首頁</nuxt-link>  <router-link to="/">首頁</router-link> </div></template>about/detail.vue<template> <div> <h2>This Detail</h2> </div></template>

現在如果我們想要訪問剛才的那兩個路由地址分別就是 http://localhost:3000/about 和 http://localhost:3000/about/detail 就能看到剛才編寫的 page 頁面了。

如果想要看路由生成到底是什么樣子的?可以在根目錄下有一個 .nuxt 文件夾,在里面可以看到一個 router.js ,這個文件夾下面就是 Nuex 生成好的路由信息。

打開文件后翻到最后會有一段這樣的代碼,是不是很眼熟?這是不就是在編寫 Vue 項目的時候配置的哪些路由文件么?

router.js

export function createRouter() { return new Router({ mode: 'history', base: decodeURI('/'), linkActiveClass: 'nuxt-link-active', linkExactActiveClass: 'nuxt-link-exact-active', scrollBehavior, routes: [{  path: "/about",  component: _9ceb4424,  name: "about" }, {  path: "/about/detail",  component: _18146f65,  name: "about-detail" }, {  path: "/",  component: _d3bf5a4e,  name: "index" }], fallback: false })}

有了這個文件的話我們就可以清楚的知道,路由的結構了。不僅僅這樣,還可以使用 name 去實現路由的跳轉了。

需要注意的是,如果你的路由是有文件夾嵌套的話, Nuxt 是用使用 - 來拼接路由的 name 名稱的(如: about-detail ),但是文件夾內部的 index.vue 會直接已文件夾的名字作為 name 。一旦知道了路由的 name ,這樣我們就可以使用命令的方式跳轉路由了。

再次更改一下 about/index.vue 。

about/index.vue

<template> <div>  <h2>This About</h2>  <nuxt-link :to="{name:'about-detail'}">詳情</nuxt-link>  <router-link :to="{name:'index'}">首頁</router-link>  <button @click="onClick">跳轉到詳情</button> </div></template><script>export default { methods: { onClick() {  this.$router.push({name:"about-detail"}) } }}</script>

使用路由訪問 http://localhost:3000/about 地址,分別點擊詳情、首頁與 button ,都是能夠正常跳轉的,與之前的 Vue 開發是完全沒有任何區別的。在 vue-router 中有一個很重要的一個點就是 動態路由 的概念,如果想要實現動態路由應該怎么處理呢?

如果想要在 Nuxt 中使用動態路由的話,需要在對應的路由下面添加一個 _參數名.vue 的文件,在 about 文件下面添加一個 _id.vue

page目錄

├─page│ ├─about│ │ ├─detail.vue│ │ ├─_id.vue│ │ └─index.vue└───└─index.vue

新建完成之后在去 router.js 中看一下更改后的路由結構

export function createRouter() { return new Router({ mode: 'history', base: decodeURI('/'), linkActiveClass: 'nuxt-link-active', linkExactActiveClass: 'nuxt-link-exact-active', scrollBehavior, routes: [{  path: "/about",  component: _9ceb4424,  name: "about" }, {  path: "/about/detail",  component: _18146f65,  name: "about-detail" }, {  path: "/about/:id",  component: _6b59f854,  name: "about-id" }, {  path: "/",  component: _d3bf5a4e,  name: "index" }], fallback: false })}

可以明顯的看到在 /about/:id 這個路由,明顯的變化不止這些變動的還有 name: "about-id" 不再是之前的 name:about 了。如果想要使用這個 id 的話必須在 _id.vue 中才能獲取到。

**_id.vue**

<template> <div> {{$route.params.name}} {{$route.params.id}} </div></template>

在 _id.vue 中編寫以上代碼并使用 http://localhost:3000/about/ABC ,可以看到在頁面中已經展示了當前的 id 值。

在實際開發過程當中可能 params 可能會有多個參數,又應該怎么處理呢?

調整目錄結構

// id為可選參數├─page│ ├─about│ │ ├─_name| | | └─_id| | |  └─index.vue│ │ └─index.vue└───└─index.vue

**about - _name - _id.vue**

<template> <div> {{$route.params.name}} {{$route.params.id}} </div></template>

弄完之后看下 router.js 的變化

export function createRouter() { return new Router({ mode: 'history', base: decodeURI('/'), linkActiveClass: 'nuxt-link-active', linkExactActiveClass: 'nuxt-link-exact-active', scrollBehavior, routes: [{  path: "/about",  component: _9ceb4424,  name: "about" }, {  path: "/about/detail",  component: _18146f65,  name: "about-detail" }, {  path: "/about/:name",  component: _2ec9f53c,  name: "about-name" }, {  path: "/about/:name/:id",  component: _318c16a4,  name: "about-name-id" }, {  path: "/",  component: _d3bf5a4e,  name: "index" }], fallback: false })}

這里展示的是第二種情況, id 為必選參數的情況,路由被編譯的結果。

雖然路由已經添加了參數,但是 id 屬性不是必填屬性,這樣的話不能滿足項目需求又要如何處理呢?很簡單的,在 _id.vue 文件同目錄下添加一個 index.vue 文件就可以了。

// id為必選參數├─page│ ├─about│ │ ├─_name| | | ├─_id.vue| | | └─index.vue│ │ └─index.vue└───└─index.vue

需要注意的是,一定要在 _id.vue 文件中使用傳入的參數,直接獲取在 index.vue 中是拿不到任何信息的。但是如果訪問 http://localhost:3000/about/ABC 這樣的路由的話,實在 index.vue 中是可以獲取到 name 參數的。

在剛才的 router.js 文件中生成的所有的路由都是平級的,如何實現路由的嵌套,如果想要實現嵌套路由的話,必須有和當前路由同名的文件夾存在,才能完成路由的嵌套。

page目錄

├─page│ ├─about| | ├─_id.vue| | └─detaile.vue│ ├─about.vue└───└─index.vue

router.js

export function createRouter() { return new Router({ mode: 'history', base: decodeURI('/'), linkActiveClass: 'nuxt-link-active', linkExactActiveClass: 'nuxt-link-exact-active', scrollBehavior, routes: [{  path: "/about",  component: _76687814,  children: [{  path: "",  component: _9ceb4424,  name: "about"  }, {  path: ":id",  component: _6b59f854,  name: "about-id"  }] }, {  path: "/",  component: _d3bf5a4e,  name: "index" }], fallback: false })}

更改完目錄結構,那我們嵌套的路由應該如何展示?在 vue.js 中開發的時候使用 router-view 這個標簽完成的。為了性能的優化 Nuxt 也提供了一個對應的標簽 nuxt-child 。

如果想實現嵌套路由傳參需要稍微的改動一下目錄結構,按照上面的方法實現就好了,下面是一個路由結構的例子。

page目錄

├─page│ ├─about│ │ ├─detail| | | ├─_id.vue| | | └─index.vue│ │ └─index.vue└───└─index.vue

router.js

export function createRouter() { return new Router({ mode: 'history', base: decodeURI('/'), linkActiveClass: 'nuxt-link-active', linkExactActiveClass: 'nuxt-link-exact-active', scrollBehavior, routes: [{  path: "/about",  component: _76687814,  name: "about",  children: [{  path: "detail",  component: _0a09b97d,  name: "about-detail"  }, {  path: "detail/:id?",  component: _fa7c11b6,  name: "about-detail-id"  }] }, {  path: "/",  component: _d3bf5a4e,  name: "index" }], fallback: false })}

在 _id.vue 中則可以使用id這個參數了。訪問路由 http://localhost:3000/about/detail/123 ,依然可以拿到傳入的 id 為 123 的這個參數。

說了這么多了,還有很多問題沒得說完,關于路由的全局守衛又應該如何去使用?在 Nuxt 根目錄下有個 plugins 文件夾。首先要做的是在里面創建一個名為 router.js 文件。

plugins-router.js

export default ({app}) => { app.router.beforeEach((to,form,next) => { console.log(to) next(); });}

導出了一個函數,在這個函數中可以通過結構拿到 vue 的實例對象名叫 app 。需要注意的是,這個 beforeEach 函數的執行,有可能會在服務端也會有可能在客戶端輸出??蛻舳耸状卧L問的頁面會在服務端做輸出,一旦渲染完成之后,則不會再在服務端輸出,則會一直在客戶端進行輸出了。

說到這里做個小插曲,那么又該怎么區分當前是在客戶端環境還是服務端環境呢?可以使用 process.server 獲取到當前的運行環境,其得到的是 Boolean 值, true 服務端, fasle 客戶端。

做了這些之后去訪問路由,仿佛沒有任何輸出,無論實在客戶端還是在服務端,都沒有任何打印輸出,中間缺少了步驟,需要在根目錄下找到 nuxt.config.js 對插件進行配置。

nuxt.config.js

const pkg = require('./package')module.exports = { plugins: [ '@/plugins/element-ui', '@/plugins/router' ]}

由于更改了 Nuxt 配置需要重啟一下服務,才能正常執行剛剛寫入的插件。然后訪問剛剛寫入的路由,會看在服務端初次渲染的時候,會輸出我們想要的那些東西,進行路由跳轉的話,會在客戶端輸出,這也就證明了 Nuxt 只會做首屏的服務器渲染。

路由說了這么接下來需要說一下 Nuxt 是如何為指定的路由配置數據做渲染的。其實 Nuxt 在做渲染的時候包裹了很多層。首先有一個 Document 作為其模板,然后再去尋找其布局的頁面,找到對應的頁面之后,再根據引用去找到相關的組件進行渲染,數據請求與數據掛載,一系列完成之后,把剩余的路由信息返還給客戶端,渲染完成,這個就是 Nuxt 簡單的渲染流程。

在上面提到了一個 布局頁面 ,這個東西應該去哪里找?又應該怎么做呢?它對于項目而言對于開發又有什么好處?在 Nuxt 根目錄下有一個 layouts 文件夾,下面有一個 default.vue 這個文件就是上面提到的渲染頁面,也就同等于 vue 開發中的 App.vue ,在這里可以做很多事情。例如添加一個全局的導航。

在 layouts 文件夾添加一個 about.vue 文件寫入如下內容,接下來需要在 pages 下面的 about.vue 中通知,對應 pages 使用哪個布局頁面,不寫則使用默認,然后訪問 http://localhost:3000/about 相關的頁面,只要是和 about 相關的頁面,都會展示這個內容。

layouts - about.vue

<template> <div> <h2>Aaron 個人博客主頁</h2> <nuxt></nuxt> </div></template>

pages - about.vue

<template> <div>  <h2>About</h2>  <nuxt-child></nuxt-child> </div></template><script>export default { layout:"about"}</script>

訪問一下所有與 about 頁面有關的頁面,都會看到 Aaron個人博客主頁 這個字樣,若訪問根路由則無法看到的。

如果做過 mvc 開發的話,如果頁面發生錯誤會跳轉到一個錯誤頁面的。 Nuxt 也是有默認的錯誤頁面的,但是全是英文而且樣式也不太好看,不能自定義樣式。如何自定義錯誤頁面呢?

在 layouts 文件夾中新建一個 error.vue 文件。

layouts - error.vue

<template> <div>  <h1>這里是錯誤頁面</h1>  <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>

在 error.vue 中可以通過 props 拿到一個 error 對象,獲取到 error 錯誤信息之后能做任何想要做的事情。需要注意的一點是,自定意的錯誤頁面,只能在客戶端訪問失效的時候才會響應到該頁面,若在服務端的話,是無法直接渲染這個頁面的。

更改頁面配置 Nuxt 中有些全局的配置,配置信息在 nuxt.config.js 更改其全局配置, pages 文件夾中的 *.vue 文件也是可以配置的,頁面私有的配置會覆蓋掉全局的配置。

舉例:

export default { layout:"about", head: {  title:"About" }}

在這些全局配置中最重要的一個就是 asyncData 這個屬性。 asyncData 到底是用來做什么的呢?這個數據可以在設置組件的數據之前能一步獲取或者處理數據。也就是說在組件渲染之前先獲取到數據,然后等待掛載渲染。

舉個例子:

<template> <div>   <h2>姓名:{{userInfo.name}}</h2>   <h2>年齡:{{userInfo.age}}</h2>   <nuxt-child></nuxt-child> </div></template><script>let getUserInfo = () => { return new Promise(resolve => {  setTimeout(() => {   let data = {"name":"Aaron","age":18};   resolve(data);  }) })}export default { layout:"about", head: {  title:"About" }, async asyncData(){  const userInfo = await getUserInfo();  return {userInfo} }}</script>

一定要 return 出去獲取到的對象,這樣就可以在組件中使用,這里返回的數據會和組件中的 data 合并。這個函數不光在服務端會執行,在客戶端同樣也會執行。

注意事項:

1.asyncData 方法會在組件(限于頁面組件)每次加載之前被調用
2.asyncData 可以在服務端或路由更新之前被調用
3.第一個參數被設定為當前頁面的上下文對象
4.Nuxt會將 asyncData 返回的數據融合到組件的data方法返回的數據一并返回給組件使用
5.對于 asyncData 方式實在組件初始化前被調用的,所以在方法內飾沒辦法通過this來引用組件的實例對象

剛剛提到了一點就是上下問對象,在上線文對象中可以獲取到很多東西,如路由參數,錯誤信息等等等,這里就不作太多贅述了,有了這些可以做一些頁面的重定向或者其他工作,比如參數校驗,安全驗證等工作。

路由扯了一大堆,接下來說一下如何在 Nuxt 中融入 axios 的使用。

安裝 axios

npm install @nuxtjs/axios --save-dev

安裝完成后更改配置信息:

nuxt.config.js

module.exports = {  modules: [    // Doc: https://axios.nuxtjs.org/usage    '@nuxtjs/axios',  ],  axios: {    proxy:true // 代理  },  proxy: {    "/api/":"http://localhost:3001/"  // key(路由前綴):value(代理地址)  }}

主要說名一下 proxy 這里, /api/ 在請求的時候遇到此前綴則會只指向的代理地址去請求數據。

既然說到了 axios ,就不得不提到的一個東西就是攔截器,很是有用在項目開發過程中必不可少的。

舉個例子:

module.expores{  plugins: [    '@/pluginx/axios'  ]}plugins/axios.jsexport default ({$axios,request}) => {  $axios. onRequest((config) => {    config.headers.token = "Aaron"  })}

總結

說了這么多也許會有些紕漏,或者遺漏的知識點,若有什么錯誤的地方可以留言,盡快做出改正。謝謝大家花費這么長時間閱讀這篇文章。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品少妇一区二区30p| 琪琪亚洲精品午夜在线| 欧美黑人极品猛少妇色xxxxx| 美日韩在线视频| 久久夜色精品国产| 亚洲自拍偷拍在线| 欧美成人中文字幕在线| 久久久国产精品亚洲一区| 午夜精品一区二区三区在线视| 成人福利在线观看| 26uuu久久噜噜噜噜| 亚洲免费av电影| 国内精品美女av在线播放| 欧美激情亚洲激情| 日韩av影视在线| 久久久久久久一区二区| 日本道色综合久久影院| 欧美一级淫片videoshd| 欧美日韩一区二区免费在线观看| 中日韩美女免费视频网站在线观看| 成人精品视频久久久久| 日韩av中文在线| 91超碰中文字幕久久精品| 在线观看日韩欧美| 欧美午夜精品伦理| 欧美尤物巨大精品爽| 91精品视频免费观看| 国产精品女主播| 在线观看日韩欧美| 国产精品免费福利| 国产99久久精品一区二区 夜夜躁日日躁| 国产一区二区日韩精品欧美精品| 亚洲激情 国产| 国产成人精品国内自产拍免费看| 狠狠久久亚洲欧美专区| 7777kkkk成人观看| 日韩免费不卡av| 97在线视频观看| 亚洲成人性视频| 日韩少妇与小伙激情| 久久久久久久亚洲精品| 成人一区二区电影| 在线视频免费一区二区| 动漫精品一区二区| 亚洲精品一区在线观看香蕉| 中文字幕亚洲专区| 亚洲成av人乱码色午夜| 国产精品久久久久久久久久尿| 精品丝袜一区二区三区| 国产精品久久久久久搜索| 国产亚洲欧美aaaa| 91中文在线观看| 欧美精品videosex牲欧美| 欧美日韩性视频| 色樱桃影院亚洲精品影院| 日韩欧美一区二区三区| 国产欧美日韩视频| 国产人妖伪娘一区91| 欧美大尺度激情区在线播放| 欧美性视频精品| 欧美成人午夜剧场免费观看| 久久999免费视频| 日韩中文理论片| 欧美日韩国产在线看| 国产精品电影观看| 97精品国产97久久久久久免费| 色偷偷av一区二区三区| 性欧美激情精品| 国产精品久久久999| 国产精品入口免费视| 久久久久久国产精品三级玉女聊斋| 国产视频在线一区二区| 欧美网站在线观看| 欧美成人在线免费| 国产精品偷伦免费视频观看的| 热99精品只有里视频精品| www.99久久热国产日韩欧美.com| 欧美成人h版在线观看| 欧美一区二区三区图| 日韩欧美一区二区三区久久| 亚洲黄色在线看| 91精品国产综合久久香蕉| 亚洲美女精品久久| 国产精品久久久久久久9999| 精品一区二区三区四区在线| 亚洲精品电影网在线观看| 91超碰caoporn97人人| 黄色成人av在线| 亚洲第一免费播放区| 久久精品国产91精品亚洲| 日韩欧美一区二区三区久久| 午夜精品一区二区三区在线播放| 日韩av电影免费观看高清| 欧美日韩午夜剧场| 欧美日韩精品在线播放| 国产精品jizz在线观看麻豆| 亚洲男人天堂九九视频| 欧洲成人在线观看| 中文字幕亚洲字幕| 午夜精品在线观看| 日韩电视剧在线观看免费网站| 精品一区二区三区四区| 亚洲综合最新在线| 国产欧美精品日韩| 成人免费网站在线| 久久精品电影一区二区| 国产欧美婷婷中文| 91精品视频在线免费观看| 精品福利在线看| 亚洲精品资源美女情侣酒店| 国产一区私人高清影院| 美女性感视频久久久| 欧美激情喷水视频| 欧美在线亚洲在线| 欧美在线视频在线播放完整版免费观看| 日韩欧美一区二区三区| xxav国产精品美女主播| 96pao国产成视频永久免费| 国产精品久久二区| yellow中文字幕久久| 欧美性猛交xxxx黑人猛交| 国产一区二区三区日韩欧美| 国产成一区二区| 成人h片在线播放免费网站| 国产成人精品午夜| 欧美福利小视频| 亚洲精品视频在线观看视频| 久久成人精品视频| 日韩在线视频导航| 欧美在线免费视频| 亚洲国产精品yw在线观看| 高清欧美电影在线| 欧美最猛性xxxxx免费| 在线观看国产成人av片| 一本色道久久综合亚洲精品小说| 深夜福利国产精品| 亚洲国内高清视频| 国产丝袜高跟一区| 久久久久久久久91| 国产精品久久久久久久久久久久久久| 亚洲男子天堂网| 亚洲精品永久免费| 97精品国产91久久久久久| 久久91精品国产91久久久| 俺也去精品视频在线观看| 91在线免费看网站| 狠狠色香婷婷久久亚洲精品| 欧美视频二区36p| 中文字幕综合在线| 精品亚洲精品福利线在观看| 成人啪啪免费看| 欧美xxxx综合视频| 久久这里只有精品99| 亚洲香蕉av在线一区二区三区| 4p变态网欧美系列| 疯狂蹂躏欧美一区二区精品| 久久视频免费观看| 欧美一级大胆视频| 久久91亚洲人成电影网站| 国内精品模特av私拍在线观看| 亚洲人成网站999久久久综合| 欧美极品少妇xxxxⅹ裸体艺术| 91精品免费久久久久久久久| 国产精品久久久久免费a∨大胸|