亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解Nuxt.js 實戰集錦

發布時間:2020-09-08 07:59:59 來源:腳本之家 閱讀:495 作者:潔本佳人 欄目:web開發

讀本文前,請先熟讀nuxt官方文檔,并且具備一定的vue.js相關開發經驗

中文文檔
英文文檔
vue SSR指南

一、CSR和SSR對比

SPA之前的時代,我們傳統的Web架構大都是SSR,如:Wordpress(PHP)JSP技術、JavaWeb等這些程序都是傳統典型的SSR架構,即:服務端取出數據和模板組合生成 html輸出給前端,前端發生請求時,重新向服務端請求html資源。

SPA(CSR):

SPA應用,到了VueReact,單頁面應用優秀的用戶體驗,逐漸成為了主流,頁面整體是javaScript渲染出來的,稱之為客戶端渲染CSRSPA渲染過程。由客戶端訪問URL發送請求到服務端,返回HTML結構(但是SPA的返回的HTML結構是非常的小的,只有一個基本的結構)。客戶端接收到返回結果之后,在客戶端開始渲染HTML,渲染時執行對應javaScript,最后渲染template,渲染完成之后,再次向服務端發送數據請求,注意這里時數據請求,服務端返回json格式數據。客戶端接收數據,然后完成最終渲染。

CSR原理圖

詳解Nuxt.js 實戰集錦

CSR多數是基于webpack構建的項目,編譯出來的html文件,資源文件都被打包到js中,這樣的頁面是不利于搜索引擎優化(SEO, Search Engine Optimization),并且內容到達時間(time-to-content) (或稱之為首屏渲染時長)也有很大的優化空間

簡單來講,SPA雖然給服務器減輕了壓力,也存在比較明顯的兩個缺點:

  • 首屏渲染時間比較長:必須等待JavaScript加載完畢,并且執行完畢,才能渲染出首屏。
  • SEO不友好:爬蟲只能拿到一個div元素,認為頁面是空的,不利于SEO

什么是SEO呢?SEO即通過各種技術(手段)來確保,你的Web內容被搜素引擎最大化收錄,最大化提高權重,帶來更多流量。大部分的搜索引擎僅能抓取URI直接輸出的數據資源,對于 Ajax 類的異步請求的數據無法抓取

因此,對于那些展示宣傳型頁面,如官網,必須進行服務端渲染

SSR:

為了解決如上兩個問題,出現了SSR解決方案,后端渲染出首屏的DOM結構返回,前端拿到內容帶上首屏,后續的頁面操作,再用單頁面路由和渲染,稱之為服務端渲染(SSR)

SSR渲染流程是這樣的,客戶端發送URL請求到服務端,在服務端做出html數據的渲染,渲染完成之后返回html結構,客戶端拿到頁面的html結構渲染首屏。所以用戶在瀏覽首屏的時候速度會很快,因為客戶端不需要再次發送ajax請求。并不是做了SSR我們的頁面就不屬于SPA應用了,它仍然是一個獨立的spa應用。

SSR原理圖

詳解Nuxt.js 實戰集錦

SSR是處于CSRSPA應用之間的一個折中的方案,在渲染首屏的時候在服務端做出了渲染,注意僅僅是首屏,其他頁面還是需要在客戶端渲染的,在服務端接收到請求之后并且渲染出首屏頁面,會攜帶著剩余的路由信息預留給客戶端去渲染其他路由的頁面。

vueSSR

將本來要放在瀏覽器執行創建的組件,放到服務端先創建好,然后生成對應的html將它們直接發送到瀏覽器,最后將這些靜態標記"激活"為客戶端上完全可交互的應用程序。

在瀏覽器第一次訪問某個URI資源的時候(首屏),Web服務器根據路由拿到對應數據渲染并輸出,且輸出的數據中包含兩部分:

  • 路由頁對應的頁面及已渲染好的數據
  • 完整的SPA程序代碼

在首屏渲染完成之后,此時我們看到的其實已經是一個和之前的SPA相差無幾的應用程序了,接下來我們進行的任何操作都只是客戶端的應用進行交互,頁面/組件由Web端渲染,路由也由瀏覽器控制,用戶只需要和當前瀏覽器內的應用打交道就可以了。

vueSSR原理圖

詳解Nuxt.js 實戰集錦

webpackSource 打包出兩個bundle文件:其中 Server Bundle用于服務端渲染,服務端通過渲染器 bundleRendererbundle 生成首屏html片段;而 Client Bundle 用于客戶端渲染,首屏外的交互和數據處理還是需要瀏覽器執行 Client Bundle 來完成

缺點:

  • 開發條件所限。瀏覽器特定的代碼,只能在某些生命周期鉤子函數(lifecycle hook)中使用;一些外部擴展庫(external library)可能需要特殊處理,才能在服務器渲染應用程序中運行。
  • 更多的服務器端負載。在 Node.js 中渲染完整的應用程序,顯然會比僅僅提供靜態文件的 server 更加大量占用 CPU 資源,因此如果你預料在高流量環境(high traffic)下使用,請準備相應的服務器負載,并明智地采用緩存策略。

二、nuxt.js介紹

1. nuxt.js是什么?

Nuxt.jsvue官方推薦的一個基于 Vue.js的做Vue SSR的通用應用框架(開箱即用),集成了Vue,Vue-Router,Vuex,Vue-Meta等組件/框架,內置了webpack用于自動化構建,使我們可以更快速地搭建一個具有服務端渲染能力的應用。

2. nuxt.js的優勢?

作為框架,Nuxt.js 為 客戶端/服務端 這種典型的應用架構模式提供了許多有用的特性,例如異步數據加載、中間件支持、布局支持等。Nuxt.js 有以下比較明顯的特性

  • 支持各種樣式預編譯器SASS,LESS等等
  • 本地開發支持熱加載
  • HTML頭部標簽管理(依賴vue-meta實現)
  • 自動代碼分層
  • 強大的路由功能,支持異步數據(路由無需額外配置)
  • 內置 webpack 配置,無需額外配置

3. nuxt.js的使用

npm create nuxt-app <project-name>

4. nuxt.js目錄結構

詳解Nuxt.js 實戰集錦

(layouts、pages、static、store、nuxt.config.js、package.json)是Nuxt保留的,不可以更改

5. nuxt.js渲染流程

詳解Nuxt.js 實戰集錦

  • Incoming Request指的是瀏覽器發出一個請求,服務端接收請求后
  • 要檢查當前有沒有nuxtServerInit這個配置項,如果有的話就先執行這個函數。具體的作用和使用可參考官方文檔nuxtserverinit-方法
  • middleware中間件,中間件允許您定義一個自定義函數運行在一個頁面或一組頁面渲染之前。也就是可以在 匹配布局(layout 組件)前執行某種操作,也可以在解析完 layout 之后,解析 page 組件前 執行某種操作。可以理解為是路由器的攔截器的作用
  • 驗證:validate(),可以配合高級動態路由去做驗證。如果校驗不通過,Nuxt.js 將自動加載顯示 404 錯誤頁面或 500 錯誤頁面,或者進行重定向。
  • 獲取數據,asyncData方法獲取數據并返回給當前組件,fetch方法修改vuexstore
  • render:最后進行渲染。將渲染后的頁面返回給瀏覽器,用戶在頁面進行操作,如果再次請求新的頁面,此時只會回到生命周期中的 middlerware 中,而非 nuxtServerInit。
  • nuxt-link,如果是發起一個新的路由,那么這個時候要從頭開始循環

詳解Nuxt.js 實戰集錦

我們把服務器端創建的 .vue 文件全部理解成組件,在服務器端環境(node)通過 beforeCreatecreated 這倆個生命周期節點后服務器端 vue 組件生命周期結束。返回頁面給瀏覽器,在客戶端環境(v8)中這個 vue 組件實例創建后會在客戶端再次擁有生命周期,此時生命周期中有 mounted 等鉤子函數。

需要特別注意的是 nuxt 中沒有 mounted 鉤子函數也沒有組件實例,只有 beforeCreate/created 鉤子與 context 對象。beforeCreated()created()這兩個生命周期函數是同時運行在服務端&&客戶端,vue的其他鉤子則運行在客戶端,所以beforeCreated()created()不存在window對象

三、nuxt.js渲染過程部分詳解

1、nuxtServerInit

舉例:打開網頁要立即顯示的內容

// SSR方式:
// 1、nuxtServerInit 方法

actions: {
  async nuxtServerInit({commit},{req,app}) {
    let {data: {province, city}} = await axios.get('/aa/bb')
    commit('home/setPosition',{province: '', city: ''})
  }
}

// 2、middleware 屬性

middleware: async (ctx) => {
  let {data: {province, city}} = await axios.get('/aa/bb')
}

// NO-SSR
vue 組件 mounted 函數發送請求

2、異步數據 asyncData

asyncData方法會在組件(限于頁面組件)每次加載渲染之前,即在服務端或路由更新之前被調用。在 asyncData() 中可以處理請求得來的數據,通過 return 將處理后的數據返回給當前 vue 組件的 data 。再次強調這里不能使用 this ,因為沒有組件實例,asyncData() 默認的參數是 ctxcontent 對象。

該方法用來獲取數據,在服務器端把異步獲取到的數據扔給瀏覽器,那是如何拋給瀏覽器的呢?

通過下發一個`script`標簽,然后在`window`上掛了一個對象這個對象,第一個是告訴你用的是哪個模板,第二個給你的是數據

詳解Nuxt.js 實戰集錦

3、布局

Nuxt.js布局方式如下圖所示:

詳解Nuxt.js 實戰集錦

nuxt.js實現了一個新的概念,layout布局,我們可以通過layout布 局方便的實現頁面的多個布局之間方便的切換。具體開發的頁面中,如果使用默認布局,則不需指定頁面的布局,nuxt框架會自動對沒有指定布局的頁面和default布局進行關聯。如果需要指定布局,則在layout字段中對布局進行指定。

<script>
export default {
 layout: 'plusBuy',
 ...
}
</script>

// 如果layout文件中建立了一個單獨的文件,則在使用中也要指定
<script>
export default {
 layout: 'plusBuy/plusBuy',
 ...
}
</script>

四、nuxt爬坑

1、localhost訪問可以,換成真實的ip地址后訪問不了

解決方案:

  1. 確認有沒有開代理
  2. package.json里做如下配置
"config": {
  "nuxt": {
    "host": "0.0.0.0",
    "port": 3000
  }
}

2、接口跨域問題

解決方案

  • 安裝@nuxtjs/axios@nuxtjs/proxy
  • nuxt.config.js做如下配置
modules: ['@nuxtjs/axios'], // 不需要加入@nuxtjs/proxy

axios: {
  proxy: true
},
proxy: {
  '/wlfrontend': { // 請求到 /wlfrontend 代理到請求 http://10.102.140.38:7001/wlfrontend
    target: 'http://10.102.140.38:7001',
    changeOrigin: true // 如果接口跨域,需要進行這個參數配置
  },
  '/scenery': { // 將'localhost:8080/scenery/xxx'代理到'https://m.ly.com/scenery/xxx'
    target: 'https://m.ly.com', // 代理地址
    changeOrigin: true, // 如果接口跨域,需要進行這個參數配置
    secure: false // 默認情況下,不接受運行在 HTTPS 上,且使用了無效證書的后端服務器。如果你想要接受,只要設置 secure: false
  }
}

3、asyncDate fetch created 因為服務端客戶端都會走,如果不想在客戶端執行?

async asyncData ({ query, store, req }) {
  if (!process.server) return
}

async fetch({ store, params }){
  if (!process.server) return
}

created(){
  if (!process.server) return
},

4、頁面做緩存,也就是返回上一級保持數據不重新請求

解決方案:
在布局頁面處理,layout/default.vue或者是自己建立的布局頁面

<template>
  <div class="plusBuy">
    <nuxt keep-alive />
  </div>
</template>

5、nuxt是把所有頁面的js都引入到主頁了?

在生產模式下,Nuxt.js 使用瀏覽器的預加載策略來預加載目標頁面的腳本資源。所以當用戶點擊某個鏈接時,會有一種秒開的感覺。預加載策略使得 Nuxt.js 既可以保持代碼分離又能保證頁面訪問體驗。
<nuxt-link>則是幫我們擴展了自動預獲取代碼分割頁面。可以使用 no-prefetch屬性 禁用
如果想要禁用,在nuxt.config.js做如下配置
router: {
  prefetchLinks: false, // 全局禁用所有鏈接上的預取
}
render: {
  resourceHints: false, // 添加prefetch和preload,以加快初始化頁面加載時間。如果有許多頁面和路由,可禁用此項
},

6、切換子路由的head中外部引入腳本載入有延遲,所以在調用時報錯

注意:
1、引入腳本不要加async:true,這樣的話腳本不會阻塞,在下面代碼有用到該腳本中的方式時,腳本可能還沒有加載完
2、需要每個小項目自己做個定制化頁面layout,layout/我的目錄/我的頁面.vue 然后在定制化頁面中使用head()加入腳本

export default {
  // 方式一:
  head: {
    script: [
      { type: 'text/javascript', src: 'https://js.40017.cn/cn/min/??/touch/hb/c/bridge.2.1.4.js?v=2016053', defer: true }
    ]
  }
  // 方式二:
  head () {
    return {
      script: [
        { type: 'text/javascript', src: 'https://js.40017.cn/cn/min/??/touch/hb/c/bridge.2.1.4.js?v=2016053', defer: true }
      ]
    }
  }
}

7、滾動事件

如果htmlbody設置了100%,那么子頁面足夠長時滾動的話,滾動事件要綁定在子頁面上,因為body的高度不是整個頁面的高度

// 1. 在子頁面父元素加
<template>
  <div class="plus" ref="mainPage"></div>
</template>

// 2. 樣式設置100%滾動
.plus {
  height: 100%;
  overflow-y: scroll;
  -webkit-overflow-scrolling : touch;
}

// 3. 再添加滾動事件
function scrollEvent() {
  var that = this;
  let dom = this.$refs.mainPage;

  dom.onscroll = function() {
    let wh = dom.scrollTop;
    // 頁面上滑,出現
    wh > 100 ? (that.showBackTop = true) : (that.showBackTop = false);
    // 未開通,頁面滑動至不出現頂部的立即開通按鈕時,底部的立即開通固定展示
    if(that.memberRightsInfo && !that.memberRightsInfo.IsPlusMember){
      if(document.querySelector('.tab') && document.querySelector('.tab').offsetTop){
        let distance = document.querySelector('.tab').offsetTop;
        wh > distance - 50 ? (that.isShowFixedBtn = true) : (that.isShowFixedBtn = false);
      }
    }
  };
}

8、文件下建立了其他文件,比如store/plusBuy/index.js,并沒有在store下直接建立index.js,如何使用?

原理:Nuxt把store中的index.js文件中所有的state、mutations、actions、getters都作為其公共屬性掛載到了store實例上,然而其他的文件則是使用的是命名空間,其對應的命名空間的名字就是其文件名。

computed: {
  ...mapState('plusBuy', {
    nickName: state => state.nickName
  })
}

...mapMutations('plusBuy', {
  setCityId: 'setCityId' // 將 `this.setCityId()` 映射為 `this.$store.commit('setCityId')`
})

...mapActions('plusBuy', {
  login: 'login' // 將 `this.login()` 映射為 `this.$store.dispatch('login')`
})

9、asyncData不可以調用this,如果有好多個異步或數據進行處理,如何優化asyncData()

// 可以使用類
class A {
  aatest(aa){
    console.log(aa)
  }
}

// 調用方法
async asyncData ({ query, store, req }) {
  var test = new A();
  test.aatest(123);
}

10、如何獲取cookie

// 服務端獲取cookie
b_getToken(req = {},c_name){
  if (req.headers && req.headers.cookie) {
    var req_Cookies = req.headers.cookie.split("; ")
    let tokens = ''
    req_Cookies.forEach(v => {
      if (v.indexOf(c_name + "=")>=0) {
        tokens = v
      }
    })
    return tokens.split('=')[1]
  } else {
    return ''
  }
}

// 客戶端獲取cookie
getCookie: function(c_name) {
  if (document.cookie.length > 0) {
    //先查詢cookie是否為空,為空就return ""
    let c_start = document.cookie.indexOf(c_name + "=") || ''; //通過String對象的indexOf()來檢查這個cookie是否存在,不存在就為 -1
    if (c_start != -1) {
      c_start = c_start + c_name.length + 1; //最后這個+1其實就是表示"="號啦,這樣就獲取到了cookie值的開始位置
      let c_end = document.cookie.indexOf(";", c_start); // 為了得到值的結束位置。因為需要考慮是否是最后一項,所以通過";"號是否存在來判斷
      if (c_end == -1) {
        c_end = document.cookie.length;
      }
      return unescape(document.cookie.substring(c_start, c_end)); 
    }
  }
  return "";
},

// 調用
let token = '';
if(process.server){
  token = serverUtilsFn.b_getToken(req,'17uCNRefId');
  console.log('server:' + token)
}else {
  token = utilsFn.getCookie('17uCNRefId');
  console.log('client:' + token)
}

11、axios數據處理問題,重復問題

import axios from 'axios';
import requestCheck from './requestCheck';

// 確保使用 axios.create創建實例后再使用。否則多次刷新頁面請求服務器,服務端渲染會重復添加攔截器,導致數據處理錯誤
const myaxios = axios.create()

// axios.defaults.baseURL = "http://localhost:3000/"

myaxios.interceptors.request.use(config => {
  let req = {...config };
  req.url = req.method.toLocaleLowerCase() == 'post' ? requestCheck(req.url, req.data) : requestCheck(req.url, req.params);
  return req;

}, error => {
  return Promise.reject(error)
})

myaxios.interceptors.response.use(response => {
  return response
}, error => {
  return Promise.reject(error)
})

export default myaxios;

12、跳轉路由傳遞參數并且取值

傳遞參數 -- this.$router.push({name: ' 路由的name ', params: {key: value}})
參數取值 -- this.$route.params.key
注: 使用這種方式,參數不會拼接在路由后面,地址欄上看不到參數
注意: 由于動態路由也是傳遞params的,所以在 this.$router.push() 方法中 path不能和params一起使用,否則params將無效。需要用name來指定頁面。

13、設置頁面動畫效果

/* 全局過渡動效設置 - 淡出 (fade) 效果*/

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

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

/* 局部過渡動效設置 - 淡出 (fade) 效果*/

.test-enter-active,
.test-leave-active {
  transition: opacity .5s;
}

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

// 在要使用的組件頁面中
export default {
  transition: 'test',
}

14、如何使用插件

// 1. 安裝插件
yarn add swiper -D

// 2. 引入
<script>
import Swiper from 'swiper'
</script>

// 3. 引入樣式
<style lang="less" scoped>
  @import "../../node_modules/swiper/css/swiper.css";
</style>

15、如何在組件中使用異步數據

如果組件不是和路由綁定的頁面組件,原則上是不可以使用異步數據的。因為 Nuxt.js 僅僅擴展增強了頁面組件的data方法,使得其可以支持異步數據處理。

對于非頁面組件,有兩種方式可以實現數據的異步獲取:

  1. 在組件的mounted方法里面實現異步獲取數據的邏輯,之后設置組件的數據,限制是:不支持服務端渲染。
  2. 在頁面組件的asyncDatafetch方法中進行API調用,并將數據作為props傳遞給子組件。服務器渲染工作正常。缺點:asyncData或頁面提取可能不太可讀,因為它正在加載其他組件的數據。

總之,使用哪種方法取決于你的應用是否需要支持子組件的服務端渲染。

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福建省| 罗山县| 正阳县| 遂宁市| 馆陶县| 腾冲县| 双城市| 德保县| 宁武县| 应城市| 四子王旗| 屏东县| 清流县| 聂荣县| 永清县| 海安县| 荣成市| 义马市| 诸城市| 富民县| 曲松县| 泸西县| 宁远县| 昌邑市| 临颍县| 西峡县| 东乌珠穆沁旗| 扬中市| 铁岭市| 伊宁市| 拉萨市| 柳江县| 辽宁省| 策勒县| 太湖县| 沙河市| 巩义市| 波密县| 沈阳市| 繁昌县| 普兰县|