亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Nuxt.js實戰(zhàn)和配置詳解

 更新時間:2019年08月05日 08:25:18   作者:fengxianqi  
這篇文章主要介紹了Nuxt.js實戰(zhàn)和配置,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前段時間剛好公司有項目使用了Nuxt.js來搭建,而剛好在公司內(nèi)部做了個分享,稍微再整理一下發(fā)出來。本文比較適合初用Nuxt.js的同學(xué),主要講下搭建過程中做的一些配置。建議初次使用Nuxt.js的同學(xué)先過一遍官方文檔,再回頭看下我這篇文章。

一、為什么要用Nuxt.js

原因其實不用多說,就是利用Nuxt.js的服務(wù)端渲染能力來解決Vue項目的SEO問題。

二、Nuxt.js和純Vue項目的簡單對比

 1. build后目標產(chǎn)物不同

vue: dist

nuxt: .nuxt

2. 網(wǎng)頁渲染流程

vue: 客戶端渲染,先下載js后,通過ajax來渲染頁面;

nuxt: 服務(wù)端渲染,可以做到服務(wù)端拼接好html后直接返回,首屏可以做到無需發(fā)起ajax請求;

3. 部署流程

vue: 只需部署dist目錄到服務(wù)器,沒有服務(wù)端,需要用nginx等做Web服務(wù)器;

nuxt: 需要部署幾乎所有文件到服務(wù)器(除node_modules,.git),自帶服務(wù)端,需要pm2管理(部署時需要reload pm2),若要求用域名,則需要nginx做代理。

4. 項目入口

vue: /src/main.js ,在main.js可以做一些全局注冊的初始化工作; nuxt: 沒有main.js入口文件,項目初始化的操作需要通過 nuxt.config.js 進行配置指定。

三、從零搭建一個Nuxt.js項目并配置 新建一個項目

直接使用腳手架進行安裝:

npx create-nuxt-app <項目名>

大概選上面這些選項。

值得一說的是,關(guān)于 Choose custom server framework (選擇服務(wù)端框架),可以根據(jù)你的業(yè)務(wù)情況選擇一個服務(wù)端框架,常見的就是Express、Koa,默認是None,即Nuxt默認服務(wù)器,我這里選了 Express 。

  • 選擇默認的Nuxt服務(wù)器,不會生成 server 文件夾,所有服務(wù)端渲染的操作都是Nuxt幫你完成,無需關(guān)心服務(wù)端的細節(jié),開發(fā)體驗更接近Vue項目,缺點是無法做一些服務(wù)端定制化的操作。
  • 選擇其他的服務(wù)端框架,比如 Express ,會生成 server 文件夾,幫你搭建一個基本的Node服務(wù)端環(huán)境,可以在里面做一些node端的操作。比如我公司業(yè)務(wù)需要(解析protobuf)使用了 Express ,對真正的服務(wù)端api做一層轉(zhuǎn)發(fā),在node端解析protobuf后,返回json數(shù)據(jù)給客戶端。

還有 Choose Nuxt.js modules (選擇nuxt.js的模塊),可以選 axiosPWA ,如果選了axios,則會幫你在nuxt實例下注冊 $axios ,讓你可以在.vue文件中直接 this.$axios 發(fā)起請求。

開啟eslint檢查

nuxt.config.js 的build屬性下添加:

 build: {
  extend (config, ctx) {
   // Run ESLint on save
   if (ctx.isDev && ctx.isClient) {
    config.module.rules.push({
     enforce: 'pre',
     test: /\.(js|vue)$/,
     loader: 'eslint-loader',
     exclude: /(node_modules)/
    })
   }
  }
 }

這樣開發(fā)時保存文件就可以檢查語法了。nuxt默認使用的規(guī)則是 @nuxtjs (底層來自eslint-config-standard ),規(guī)則配置在 /.eslintrc.js :

module.exports = {
 root: true,
 env: {
  browser: true,
  node: true
 },
 parserOptions: {
  parser: 'babel-eslint'
 },
 extends: [
  '@nuxtjs', // 該規(guī)則對應(yīng)這個依賴: @nuxtjs/eslint-config
  'plugin:nuxt/recommended'
 ],
 // add your custom rules here
 rules: {
  'nuxt/no-cjs-in-config': 'off'
 }
}

如果不習(xí)慣用 standard 規(guī)則的團隊可以將 @nuxtjs 改成其他的。

使用dotenv和@nuxtjs/dotenv統(tǒng)一管理環(huán)境變量

在node端,我們喜歡使用 dotenv 來管理項目中的環(huán)境變量,把所有環(huán)境變量都放在根目錄下的 .env 中。

安裝:

npm i dotenv

使用: 在根目錄下新建一個 .env 文件,并寫上需要管理的環(huán)境變量,比如服務(wù)端地址 APIHOST :

APIHOST=http://your_server.com/api

/server/index.js 中使用(該文件是選Express服務(wù)端框架自動生成的):

require('dotenv').config()

// 通過process.env即可使用
console.log(process.env.APIHOST) // http://your_server.com/api

此時我們只是讓服務(wù)端可以使用 .env 的文件而已,Nuxt客戶端并不能使用 .env ,按Nuxt.js文檔所說,可以將客戶端的環(huán)境變量放置在 nuxt.config.js 中:

module.exports = {
 env: {
  baseUrl: process.env.BASE_URL || 'http://localhost:3000'
 }
}

但如果node端和客戶端需要使用同一個環(huán)境變量時(后面講到API鑒權(quán)時會使用同一個SECRET變量),就需要同時在 nuxt.config.js.env 維護這個字段,比較麻煩,我們更希望環(huán)境變量只需要在一個地方維護,所以為了解決這個問題,我找到了 @nuxtjs/dotenv 這個依賴,它使得nuxt的客戶端也可以直接使用 .env ,達到了我們的預(yù)期。

安裝:

npm i @nuxtjs/dotenv

客戶端也是通過 process.env.XXX 來使用,不再舉例啦。

這樣,我們通過 dotenv@nuxtjs/dotenv 這兩個包,就可以統(tǒng)一管理開發(fā)環(huán)境中的變量啦。

另外, @nuxtjs/dotenv 允許打包時指定其他的env文件。比如,開發(fā)時我們使用的是 .env ,但我們打包的線上版本想用其他的環(huán)境變量,此時可以指定build時用另一份文件如 /.env.prod ,只需在 nuxt.config.js 指定:

module.exports = {
  modules: [
  ['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包時使用的dotenv
 ],
}

@nuxtjs/toast模塊

toast可以說是很常用的功能,一般的UI框架都會有這個功能。但如果你的站點沒有使用UI框架,而alert又太丑,不妨引入該模塊:

npm install @nuxtjs/toast

然后在 nuxt.config.js 中引入

module.exports = {
  modules: [
  '@nuxtjs/toast',
  ['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包時使用的dotenv
 ],
 toast: {// toast模塊的配置
  position: 'top-center', 
  duration: 2000
 }
}

這樣,nuxt就會在全局注冊 $toast 方法供你使用,非常方便:

this.$toast.error('服務(wù)器開小差啦~~')
this.$toast.error('請求成功~~')

API鑒權(quán)

對于某些敏感的服務(wù),我們可能需要對API進行鑒權(quán),防止被人輕易盜用我們node端的API,因此我們需要做一個API的鑒權(quán)機制。常見的方案有jwt,可以參考一下阮老師的介紹: 《JSON Web Token 入門教程》 。如果場景比較簡單,可以自行設(shè)計一下,這里提供一個思路:

  1. 客戶端和node端在環(huán)境變量中聲明一個秘鑰:SECRET=xxxx,注意這個是保密的;
  2. 客戶端發(fā)起請求時,將當(dāng)前時間戳(timestamp)和 SECRET 通過某種算法,生成一個 signature ,請求時帶上 timestampsignature ;
  3. node接收到請求,獲得 timestampsignature ,將 timestamp 和秘鑰用同樣的算法再生成一次簽名 _signature
  4. 對比客戶端請求的 signature 和node用同樣的算法生成的 _signature ,如果一致就表示通過,否則鑒權(quán)失敗。

具體的步驟:

客戶端對axios進行一層封裝:

import axios from 'axios'
import sha256 from 'crypto-js/sha256'
import Base64 from 'crypto-js/enc-base64'
// 加密算法,需安裝crypto-js
function crypto (str) {
 const _sign = sha256(str)
 return encodeURIComponent(Base64.stringify(_sign))
}

const SECRET = process.env.SECRET

const options = {
 headers: { 'X-Requested-With': 'XMLHttpRequest' },
 timeout: 30000,
 baseURL: '/api'
}

// The server-side needs a full url to works
if (process.server) {
 options.baseURL = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}/api`
 options.withCredentials = true
}

const instance = axios.create(options)
// 對axios的每一個請求都做一個處理,攜帶上簽名和timestamp
instance.interceptors.request.use(
 config => {
  const timestamp = new Date().getTime()
  const param = `timestamp=${timestamp}&secret=${SECRET}`
  const sign = crypto(param)
  config.params = Object.assign({}, config.params, { timestamp, sign })
  return config
 }
)

export default instance

接著,在server端寫一個鑒權(quán)的中間件, /server/middleware/verify.js

const sha256 = require('crypto-js/sha256')
const Base64 = require('crypto-js/enc-base64')

function crypto (str) {
 const _sign = sha256(str)
 return encodeURIComponent(Base64.stringify(_sign))
}
// 使用和客戶端相同的一個秘鑰
const SECRET = process.env.SECRET

function verifyMiddleware (req, res, next) {
 const { sign, timestamp } = req.query
 // 加密算法與請求時的一致
 const _sign = crypto(`timestamp=${timestamp}&secret=${SECRET}`)
 if (_sign === sign) {
  next()
 } else {
  res.status(401).send({
   message: 'invalid token'
  })
 }
}

module.exports = { verifyMiddleware }

最后,在需要鑒權(quán)的路由中引用這個中間件, /server/index.js

const { Router } = require('express')
const { verifyMiddleware } = require('../middleware/verify.js')
const router = Router()

// 在需要鑒權(quán)的路由加上
router.get('/test', verifyMiddleware, function (req, res, next) {
  res.json({name: 'test'})
})

靜態(tài)文件的處理

根目錄下有個 /static 文件夾,我們希望這里面的文件可以直接通過url訪問,需要在 /server/index.js 中加入一句:

const express = require('express')
const app = express()

app.use('/static', express.static('static'))

四、Nuxt開發(fā)相關(guān) 生命周期

Nuxt擴展了Vue的生命周期,大概如下:

export default {
 middleware () {}, //服務(wù)端
 validate () {}, // 服務(wù)端
 asyncData () {}, //服務(wù)端
 fetch () {}, // store數(shù)據(jù)加載
 beforeCreate () { // 服務(wù)端和客戶端都會執(zhí)行},
 created () { // 服務(wù)端和客戶端都會執(zhí)行 },
 beforeMount () {}, 
 mounted () {} // 客戶端
}

asyncData

該方法是Nuxt最大的一個賣點,服務(wù)端渲染的能力就在這里,首次渲染時務(wù)必使用該方法。 asyncData會傳進一個context參數(shù),通過該參數(shù)可以獲得一些信息,如:

export default {
 asyncData (ctx) {
  ctx.app // 根實例
  ctx.route // 路由實例
  ctx.params //路由參數(shù)
  ctx.query // 路由問號后面的參數(shù)
  ctx.error  // 錯誤處理方法
 }
}

渲染出錯和ajax請求出錯的處理

asyncData渲染出錯

使用 asyncData 鉤子時可能會由于服務(wù)器錯誤或api錯誤導(dǎo)致無法渲染,此時頁面還未渲染出來,需要針對這種情況做一些處理,當(dāng)遇到asyncData錯誤時,跳轉(zhuǎn)到錯誤頁面,nuxt提供了 context.error 方法用于錯誤處理,在asyncData中調(diào)用該方法即可跳轉(zhuǎn)到錯誤頁面。

export default {
  async asyncData (ctx) {
    // 盡量使用try catch的寫法,將所有異常都捕捉到
    try {
      throw new Error()
    } catch {
      ctx.error({statusCode: 500, message: '服務(wù)器開小差了~' })
    }
  }
}

這樣,當(dāng)出現(xiàn)異常時會跳轉(zhuǎn)到默認的錯誤頁,錯誤頁面可以通過 /layout/error.vue 自定義。

這里會遇到一個問題, context.error 的參數(shù)必須是類似 { statusCode: 500, message: '服務(wù)器開小差了~' }statusCode 必須是http狀態(tài)碼, 而我們服務(wù)端返回的錯誤往往有一些其他的自定義代碼,如 {resultCode: 10005, resultInfo: '服務(wù)器內(nèi)部錯誤' } ,此時需要對返回的api錯誤進行轉(zhuǎn)換一下。

為了方便,我引入了 /plugins/ctx-inject.js 為context注冊一個全局的錯誤處理方法: context.$errorHandler(err) 。注入方法可以參考: 注入 $root 和 context ctx-inject.js :

// 為context注冊全局的錯誤處理事件
export default (ctx, inject) => {
 ctx.$errorHandler = err => {
  try {
   const res = err.data
   if (res) {
    // 由于nuxt的錯誤頁面只能識別http的狀態(tài)碼,因此statusCode統(tǒng)一傳500,表示服務(wù)器異常。
    ctx.error({ statusCode: 500, message: res.resultInfo })
   } else {
    ctx.error({ statusCode: 500, message: '服務(wù)器開小差了~' })
   }
  } catch {
   ctx.error({ statusCode: 500, message: '服務(wù)器開小差了~' })
  }
 }
}

然后在 nuxt.config.js 使用該插件:

export default {
 plugins: [
  '~/plugins/ctx-inject.js'
 ]
}

注入完畢,我們就可以在 asyncData 介個樣子使用了:

export default {
  async asyncData (ctx) {
    // 盡量使用try catch的寫法,將所有異常都捕捉到
    try {
      throw new Error()
    } catch(err) {
      ctx.$errorHandler(err)
    }
  }
}

ajax請求出錯

對于ajax的異常,此時頁面已經(jīng)渲染,出現(xiàn)錯誤時不必跳轉(zhuǎn)到錯誤頁,可以通過 this.$toast.error(res.message) toast出來即可。

loading方法

nuxt內(nèi)置了頁面頂部loading進度條的樣式 推薦使用,提供頁面跳轉(zhuǎn)體驗。 打開: this.$nuxt.$loading.start() 完成: this.$nuxt.$loading.finish()

打包部署

一般來說,部署前可以先在本地打包,本地跑一下確認無誤后再上傳到服務(wù)器部署。命令:

// 打包
npm run build
// 本地跑
npm start

除node_modules,.git,.env,將其他的文件都上傳到服務(wù)器,然后通過 pm2 進行管理,可以在項目根目錄建一個 pm2.json 方便維護:

{
 "name": "nuxt-test",
 "script": "./server/index.js",
 "instances": 2,
 "cwd": "."
}

然后配置生產(chǎn)環(huán)境的環(huán)境變量,一般是直接用 .env.prod 的配置: cp ./.env.prod ./.env 。 首次部署或有新的依賴包,需要在服務(wù)器上 npm install 一次,然后就可以用 pm2 啟動進程啦:

// 項目根目錄下運行
pm2 start ./pm2.json

需要的話,可以設(shè)置開機自動啟動pm2: pm2 save && pm2 startup 。 需要注意的是,每次部署都得重啟一下進程: pm2 reload nuxt-test 。

五、最后

Nuxt.js引入了Node,同時nuxt.config.js替代了main.js的一些作用,目錄結(jié)構(gòu)和vue項目都稍有不同,增加了很多的約定,對于初次接觸的同學(xué)可能會覺得非常陌生,更多的內(nèi)容還是得看一遍官方的文檔。

demo源碼: fengxianqi/front_end-demos/src/nuxt-test。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實現(xiàn)的上拉加載更多數(shù)據(jù)/分頁功能示例

    vue實現(xiàn)的上拉加載更多數(shù)據(jù)/分頁功能示例

    這篇文章主要介紹了vue實現(xiàn)的上拉加載更多數(shù)據(jù)/分頁功能,涉及基于vue的事件響應(yīng)、數(shù)據(jù)交互等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • Vuex的各個模塊封裝的實現(xiàn)

    Vuex的各個模塊封裝的實現(xiàn)

    這篇文章主要介紹了Vuex的各個模塊封裝的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Vue實現(xiàn)登錄保存token并校驗實現(xiàn)保存登錄狀態(tài)的操作代碼

    Vue實現(xiàn)登錄保存token并校驗實現(xiàn)保存登錄狀態(tài)的操作代碼

    這篇文章主要介紹了Vue實現(xiàn)登錄保存token并校驗實現(xiàn)保存登錄狀態(tài),本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • vue如何調(diào)用攝像頭實現(xiàn)拍照上傳圖片、本地上傳圖片

    vue如何調(diào)用攝像頭實現(xiàn)拍照上傳圖片、本地上傳圖片

    這篇文章主要給大家介紹了關(guān)于vue如何調(diào)用攝像頭實現(xiàn)拍照上傳圖片、本地上傳圖片的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-07-07
  • Vue中保存數(shù)據(jù)到磁盤文件的方法

    Vue中保存數(shù)據(jù)到磁盤文件的方法

    今天小編就為大家分享一篇Vue中保存數(shù)據(jù)到磁盤文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 記錄一個Vue3簡易微信右滑刪除邏輯的思路實現(xiàn)

    記錄一個Vue3簡易微信右滑刪除邏輯的思路實現(xiàn)

    本文主要介紹了記錄一個Vue3簡易微信右滑邏輯的思路實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 解讀Vue實例的屬性及模板渲染

    解讀Vue實例的屬性及模板渲染

    這篇文章主要介紹了解讀Vue實例的屬性及模板渲染問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue-cli3.0配置及使用注意事項詳解

    vue-cli3.0配置及使用注意事項詳解

    這次給大家?guī)韛ue-cli3.0配置詳解,使用vue-cli3.0配置的注意事項有哪些?本文通過實戰(zhàn)案例給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-09-09
  • VUE中常用的4種高級方法

    VUE中常用的4種高級方法

    provide/inject 是 Vue.js 中用于跨組件傳遞數(shù)據(jù)的一種高級技術(shù),它可以將數(shù)據(jù)注入到一個組件中,然后讓它的所有子孫組件都可以訪問到這個數(shù)據(jù),這篇文章主要介紹了VUE中常用的4種高級方法,需要的朋友可以參考下
    2023-05-05
  • Django+Vue跨域環(huán)境配置詳解

    Django+Vue跨域環(huán)境配置詳解

    這篇文章主要介紹了Django+Vue跨域環(huán)境配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論