學成在線(第12天)

 搜索前端技術需求

採用vue.js開發搜索界面則SEO不友好,須要解決SEO的問題。javascript

seo是網站爲了提升自已的網站排名,得到更多的流量,對網站的結構及內容進行調整優化,以便搜索引擎
(百度,google等)更好抓取到更優質的網站的內容。html

 服務端渲染和客戶端渲染

採用什麼技術有利於SEO?要解答這個問題須要理解服務端渲染和客戶端渲染。
什麼是服務端渲染?
咱們用傳統的servlet開發來舉例:瀏覽器請求servlet,servlet在服務端生成html響應給瀏覽器,瀏覽器展現html
的內容,這個過程就是服務端渲染,以下圖:前端

 服務端渲染的特色:vue

1 )在服務端生成html網頁的dom元素。
2)客戶端(瀏覽器)只負責顯示dom元素內容。java

當初隨着web2.0的到來,AJAX技術興起,出現了客戶端渲染:客戶端(瀏覽器) 使用AJAX向服務端發起http請
求,獲取到了想要的數據,客戶端拿着數據開始渲染html網頁,生成Dom元素,並最終將網頁內容展現給用戶,
以下圖:react

客戶端渲染的特色:
1)在服務端只是給客戶端響應的了數據,而不是html網頁
2)客戶端(瀏覽器)負責獲取服務端的數據生成Dom元素。webpack

兩種方式各有什麼優缺點?

客戶端渲染:
1) 缺點
不利於網站進行SEO,由於網站大量使用javascript技術,不利於spider抓取網頁。
2) 優勢
客戶端負責渲染,用戶體驗性好,服務端只提供數據不用關心用戶界面的內容,有利於提升服務端的開發效率。
3)適用場景
對SEO沒有要求的系統,好比後臺管理類的系統,如電商後臺管理,用戶管理等。git


服務端渲染:
1) 優勢
有利於SEO,網站經過href的url將spider直接引到服務端,服務端提供優質的網頁內容給spider。
2) 缺點
服務端完成一部分客戶端的工做,一般完成一個需求須要修改客戶端和服務端的代碼,開發效率低,不利於系統的
穩定性。程序員

3 )適用場景
對SEO有要求的系統,好比:門戶首頁、商品詳情頁面等github

Nuxt.js 介紹

移動互聯網的興起促進了web先後端分離開發模式的發展,服務端只專一業務,前端只專一用戶體驗,前端大量運
用的前端渲染技術,好比流行的vue.js、react框架都實現了功能強大的前端渲染。
可是,對於有SEO需求的網頁若是使用前端渲染技術去開發就不利於SEO了,有沒有一種即便用vue.js、react的前
端技術也實現服務端渲染的技術呢?其實,對於服務端渲染的需求,vue.js、react這樣流行的前端框架提供了服務
端渲染的解決方案。

從上圖能夠看到:
react框架提供next.js實現服務端渲染。
vue.js框架提供Nuxt.js實現服務端渲染。

Nuxt.js 工做原理

下圖展現了從客戶端請求到Nuxt.js進行服務端渲染的總體的工做流程:

一、用戶打開瀏覽器,輸入網址請求到Node.js
二、部署在Node.js的應用Nuxt.js接收瀏覽器請求,並請求服務端獲取數據
三、Nuxt.js獲取到數據後進行服務端渲染
四、Nuxt.js將html網頁響應給瀏覽器

Nuxt.js使用了哪些技術?
Nuxt.js使用Vue.js+webpack+Babel三大技術框架/組件

Babel 是一個js的轉碼器,負責將ES6的代碼轉成瀏覽器識別的ES5代碼。
Webpack是一個前端工程打包工具。
Vue.js是一個優秀的前端框架。

Nuxt.js的特性有哪些?

  • 基於 Vue.js
  • 自動代碼分層
  • 服務端渲染
  • 強大的路由功能,支持異步數據
  • 靜態文件服務
  • ES6/ES7 語法支持
  • 打包和壓縮 JS 和 CSS
  • HTML 頭部標籤管理
  • 本地開發支持熱加載
  • 集成 ESLint
  • 支持各類樣式預處理器: SASS、LESS、 Stylus等等

Nuxt.js 基本使用

 建立Nuxt工程

nuxt.js有標準的目錄結構,官方提供了模板工程,能夠模板工程快速建立nuxt項目。
模板工程地址:https://github.com/nuxt-community/starter-template/archive/master.zip
本項目提供基於 Nuxt.js的封裝工程,基於此封裝工程開發搜索前端,見「資料」--》xc-ui-pc-portal.zip,解壓
xc-ui-pc-portal.zip到本項目前端工程目錄下。
本前端工程屬於門戶的一部分,將承載一部分考慮SEO的非靜態化頁面。
本工程基於Nuxt.js模板工程構建,Nuxt.js使用1.3版本,並加入了從此開發中所使用的依賴包,直接解壓本工程即
可以使用。

 目錄結構

  ‐ 資源目錄
資源目錄 assets 用於組織未編譯的靜態資源如 LESS、SASS 或 JavaScript。
‐ 組件目錄
組件目錄 components 用於組織應用的 Vue.js 組件。Nuxt.js 不會擴展加強該目錄下 Vue.js 組件,即這些組件不
會像頁面組件那樣有 asyncData 方法的特性。
‐ 佈局目錄
佈局目錄 layouts 用於組織應用的佈局組件。
該目錄名爲Nuxt.js保留的,不可更改。
‐ 中間件目錄
middleware 目錄用於存放應用的中間件。
‐ 頁面目錄
頁面目錄 pages 用於組織應用的路由及視圖。Nuxt.js 框架讀取該目錄下全部的 .vue 文件並自動生成對應的路由配
置。
該目錄名爲Nuxt.js保留的,不可更改。
‐ 插件目錄
插件目錄 plugins 用於組織那些須要在 根vue.js應用 實例化以前須要運行的 Javascript 插件。
‐ 靜態文件目錄
靜態文件目錄 static 用於存放應用的靜態文件,此類文件不會被 Nuxt.js 調用 Webpack 進行構建編譯處理。 服務
器啓動的時候,該目錄下的文件會映射至應用的根路徑 / 下。
舉個例子: /static/logo.png 映射至 /logo.png
該目錄名爲Nuxt.js保留的,不可更改。
‐ Store 目錄
store 目錄用於組織應用的 Vuex 狀態樹 文件。 Nuxt.js 框架集成了 Vuex 狀態樹 的相關功能配置,在 store 目
錄下建立一個 index.js 文件可激活這些配置。
該目錄名爲Nuxt.js保留的,不可更改。
‐ nuxt.config.js 文件
nuxt.config.js 文件用於組織Nuxt.js 應用的個性化配置,以便覆蓋默認配置。
該文件名爲Nuxt.js保留的,不可更改。
‐ package.json 文件
package.json 文件用於描述應用的依賴關係和對外暴露的腳本接口。
該文件名爲Nuxt.js保留的,不可更改。

nuxt.js  提供了目錄的別名,方便在程序中引用:

 路由

基礎路由

Nuxt.js 依據 pages 目錄結構自動生成 vue-router 模塊的路由配置。
Nuxt.js根據pages的目錄結構及頁面名稱定義規範來生成路由,下邊是一個基礎路由的例子:
假設 pages 的目錄結構以下:

pages/
‐‐| user/
‐‐‐‐‐| index.vue
‐‐‐‐‐| one.vue

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

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

index.vue 代碼以下:

<template>
  <div>
    用戶管理首頁
  </div>
</template>
<script>
export default{
   layout:"test"
}
</script>
<style>
</style>

one.vue代碼以下:

<template>
  <div>
    one頁面
  </div>
</template>
<script>
export default{
   layout:"test"
}
</script>
<style>
</style>

嵌套路由

你能夠經過 vue-router 的子路由建立 Nuxt.js 應用的嵌套路由。
建立內嵌子路由,你須要添加一個 Vue 文件,同時添加一個與該文件同名的目錄用來存放子視圖組件。
別忘了在父級 Vue 文件內增長 <nuxt -child/> 用於顯示子視圖內容。
假設文件結構如:

pages/
‐‐| user/
‐‐‐‐‐| _id.vue
‐‐‐‐‐| index.vue
‐‐| user.vue

Nuxt.js 自動生成的路由配置以下:

router: {
  routes: [
    {
      path: '/user',
      component: 'pages/user.vue',
      children: [
        {
          path: '',
          component: 'pages/user/index.vue',
          name: 'user'
        },
        {
          path: ':id',
          component: 'pages/user/_id.vue',
          name: 'user‐id'
        }
      ]
    }
  ]
}

將user.vue文件建立到與user目錄的父目錄下,即和user目錄保持平級。

<template>
  <div>
    用戶管理導航,<nuxt‐link :to="'/user/101'">修改</nuxt‐link>
    <nuxt‐child/>
  </div>
</template>
<script>
  export default{
    layout:"test"
  }
</script>
<style>
</style>

_id.vue頁面實現了向頁面傳入id參數,頁面內容以下:

<template>
  <div>
     修改用戶信息{{id}}
  </div>
</template>
<script>
  export default{
    layout:"test",
    data(){
        return {
            id:''
        }
    },
    mounted(){
      this.id = this.$route.params.id;
      console.log(this.id)
    }
  }
</script>
<style>
</style>

測試:http://localhost:10000/user

 點擊修改:

  獲取數據

asyncData 方法

Nuxt.js 擴展了 Vue.js,增長了一個叫 asyncData 的方法, asyncData 方法會在組件(限於頁面組件)每次加載
以前被調用。它能夠在服務端或路由更新以前被調用。 在這個方法被調用的時候,第一個參數被設定爲當前頁面的
上下文對象,你能夠利用 asyncData 方法來獲取數據,Nuxt.js 會將 asyncData 返回的數據融合組件 data 方法
返回的數據一併返回給當前組件。
注意:因爲 asyncData 方法是在組件 初始化 前被調用的,因此在方法內是沒有辦法經過 this 來引用組件的實例
對象。

例子:
在上邊例子中的user/_id.vue中添加,頁面代碼以下:

  <template>
  <div>
 修改用戶信息{{id}},名稱:{{name}}
  </div>
</template>
<script>
  export default{
    layout:'test',
    //根據id查詢用戶信息
    asyncData(){
      console.log("async方法")
      return {
        name:'黑馬程序員'
      }
    },
    data(){
      return {
        id:''
      }
    },
    mounted(){
      this.id = this.$route.params.id;
    }
 }
</script>
<style>
</style>

此方法在服務端被執行,觀察服務端控制檯打印輸出 「async方法」。
此方法返回data模型數據,在服務端被渲染,最後響應給前端,刷新此頁面查看頁面源代碼能夠看到name模型數
據已在頁面源代碼中顯示。

async /await方法

使用async 和 await配合promise也能夠實現同步調用,nuxt.js中使用async/await實現同步調用效果。

一、先測試異步調用,增長a、b兩個方法,並在mounted中調用。

methods:{
    a(){
        return new Promise(function(resolve,reject){
          setTimeout(function () {
            resolve(1)
          },2000)
        })
    },
    b(){
      return new Promise(function(resolve,reject){
        setTimeout(function () {
          resolve(2)
        },1000)
      })
    }
},
    mounted(){
        this.a().then(res=>{
            alert(res)
          console.log(res)
        })
        this.b().then(res=>{
          alert(res)
          console.log(res)
        })
    }

觀察客戶端,並無按照方法執行的順序輸出,使用Promise實現了異步調用。

2 、使用async/await完成同步調用

async asyncData({ store, route }) {
          console.log("async方法")
      var a = await new Promise(function (resolve, reject) {
        setTimeout(function () {
          console.log("1")
          resolve(1)
        },2000)
      });
      var a = await new Promise(function (resolve, reject) {
        setTimeout(function () {
          console.log("2")
          resolve(2)
        },1000)
      });
      return {
            name:'黑馬程序員'
      }
    },

觀察服務端控制檯發現是按照a、b方法的調用順序輸出一、2,實現了使用async/await完成同步調用。

相關文章
相關標籤/搜索