Nuxt開發經驗分享,讓你踩少點坑!

wangsys發表於2021-09-09

說明

本文章基於starter-template模板進行講解,面向有vue-cli開發經驗的寶寶

vue init nuxt-community/starter-template

圖片描述

Nuxt

簡單來說,Nuxt就是基於Vue的一個應用框架,採用服務端渲染,讓你的SPA應用(Vue)也可以擁有SEO

生命週期

眾所周知,Vue的生命週期全都跑在客戶端(瀏覽器),而Nuxt的生命週期有些在服務端(Node),客戶端,甚至兩邊都在:


圖片描述


生命週期流程圖,紅框內的是Nuxt的生命週期(執行在服務端),黃框內同時執行在服務端&&客戶端上,綠框內則執行在客戶端



實戰經驗

1. 紅框、黃框內的週期都不存在Window物件

export default {   asyncData() {    console.log(window) // 服務端報錯   },   fetch() {    console.log(window) // 服務端報錯   },   created () {    console.log(window) // undefined   },   mounted () {    console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}   } }

2. 配置錯誤頁面

你可以透過編輯 layouts/error.vue 檔案來定製化錯誤頁面.

export default {  props: ['error'],  layout: 'blog' // 你可以為錯誤頁面指定自定義的佈局}

3. 自定義Loading頁面

nuxt.config.js

module.exports = {
  loading: '~components/loading.vue'}

loading.vue

export default {  data: () => ({    loading: false   }),  methods: {     start () {      this.loading = true     },     finish () {      this.loading = false     }   } }

4. 校驗引數

如果校驗失敗,則自動跳轉到錯誤頁面

export default {   validate({ params, query }) {    return /^d+$/.test(params.id) // must be number   } }

5. Header、Footer等公共元件放哪?

大家都知道,vue-cli入口檔案是app.vue,在nuxt開發當中則是./layout/default.vue

6. 沒有keep-alive

由於是服務端渲染,所以不支援元件的keep-alive,那自然activated、deactivated這兩個生命週期也沒了

7. 配置外掛

所有外掛都寫在/plugins目錄下,這裡以vue-lazyload為例

plugins/lazy-load.js

import Vue from 'vue'import VueLazyLoad from 'vue-lazyload'Vue.use(VueLazyLoad, {  loading: require('~/assets/images/loading.jpg'),  error: require('~/assets/images/error.jpg')
})

nuxt.config.js

module.expors = {
  plugins = [
    {
      src: "~/plugins/lazy-load",
      ssr: false
    }
  ]
}

8. 使用Axios,並配置全域性攔截器,處理跨域

starter-template模板,推薦使用@nuxtjs/axios、@nuxtjs/proxy,不需要在plugins配置

安裝依賴

npm install @nuxtjs/axios @nuxtjs/proxy --save

使用、處理跨域

// nuxt.config.jsmodule.exports = {
  modules: [ '@nuxtjs/axios' ], // 不需要加入@nuxtjs/proxy
  axios: {
    proxy: true,
    prefix: '/api', // baseURL
    credentials: true,
  },
  proxy: {    '/api/': {
      target: '', // 代理地址
      changeOrigin: true,
      pathRewrite: {        '^/api': ''
      },
    },
  }
}

元件中使用

export default {   fetch ({ app }) {    console.log(app.$axios)   },   asyncData ({ app }) {    console.log(app.$axios)   },   created () {    console.log(this.$axios)   } }

到此為止,我們並不需要在plugins配置axios,但是如果要設定全域性攔截器,那麼就要新建一個/plugins/axios.js

export default function (app) {  let axios = app.$axios; 
 // 基本配置
  axios.defaults.timeout = 10000
  axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

  // 請求回撥
  axios.onRequest(config => {})  // 返回回撥
  axios.onResponse(res => {})  // 錯誤回撥
  axios.onError(error => {})
}

然後在plugins配置它

module.exports = {
  plugins = [
    {
      src: "~/plugins/axios",
      ssr: false
    },
  ]
}

9. 預設Meta標籤

nuxt.config.js

module.exports = {
  head: {
    title: 'your project title',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' }
    ],
    link: [
      { rel: 'stylesheet', href: '' }
    ]
  }
}

10. 頁面元件特有的Meta標籤

export default {   head () {    return {      meta:        [         {          name: 'keywords',          content: '最強王者,今晚吃雞'         },       ]     }   } }

11. 動態路由的Meta標籤填充

遊戲詳情頁面舉例子,由於資料是非同步獲取的,我們需要把資料獲取寫在asyncData鉤子,待資料獲取成功才會渲染該頁面元件


12. 使用Vuex

nuxt自己整合了vuex,所以不需要安裝在/store目錄下新建index.js即可使用

import Vuex from 'vuex'let store = () => new Vuex.Store({  state: {    token: ''
  },  mutations: {
    setToken (state, token) {
       state.token = token
    }
  }
})export default store

13. 登入狀態?

vue-cli專案中,我們可以用,它可以使vuex的狀態持久化,頁面重新整理都不會丟失,原理當然是localStorage啦!當然我更喜歡用進行儲存token,問題來了,nuxt專案怎麼儲存登入狀態呢?當然上面這兩種方法我們都可以使用,但是有個問題,由於在created鉤子中不存在window物件(獲取cookie、localStorage都需要window物件),當你需要判斷是否存在token的時候,你必須要在mounted進行操作,這說明頁面進來的一瞬間你無法得知是否已經登入了,這會導致顯示使用者名稱、元件顯示於隱藏都慢半拍


nuxt非常友好,它提供了fetch鉤子,還有nuxtServerInit,這兩個鉤子都執行在服務端並且我們能很快速地操作store

14. fetch的使用

如果頁面元件設定了fetch方法,它會在元件每次載入前被呼叫(在服務端或切換至目標路由之前),此方法需要跟服務端的人員配合


15. nuxtServerInit

終極無敵方法

import Vuex from 'vuex'let store = () => new Vuex.Store({  state: {    token: ''
  },  mutations: {
    setToken (state, token) {
       state.token = token
    }
  },  actions: {
    nuxtServerInit({ commit }, { req }) {      let cookie = req.headers.cookie;      // 將cookie轉成json物件(自己實現該方法)
      let token = cookieparse(cookie).token;
      commit('setToken', token);
    },
  }
})export default store

16. 封裝屬於自己的全域性方法

 let xielikang = function () {  /**
   * @method 列印資訊方法
   * @param {String} msg 資訊
   */
  let message = function (msg) {
    msg && console.log(msg)
  }  let otherfn = function (msg) {}  return {
    message,
    otherfn
  }

}

Vue.prototype.$kang= xielikang

元件呼叫

export default {   created() {    this.$kang.message('小老弟,你怎麼回事')   } }

對了,別忘了在plugins中配置,可以回到第7小節檢視配置

17. 全域性樣式

nuxt.config.js

module.exports = {
  css: ['~/assets/stylesheets/main.min.css']
}

18. 使用Element-UI

還是plugins資料夾新建element-ui.js

// 全域性引入import Vue from 'vue'import ElementUI from 'element-ui'Vue.use(ElementUI)// 按需引入import { Button, Loading, MessageBox } from 'element-ui'Vue.use(Button)
Vue.prototype.$loading = Loading.service
Vue.prototype.$msgbox = MessageBox

nuxt.config.js

module.exports = {
  css: ['element-ui/lib/theme-chalk/index.css'],
  plugins: [
    {
      src: "~/plugins/element",
      ssr: true
    }
  ]
}

18. 如何使用sass前處理器

安裝依賴

npm install node-sass sass-loader --save

元件中使用(不需要其他的配置了)

19. fetch、asyncData、validate使用範圍

只能在頁面元件使用,也就是pages目錄下的元件,而不是components目錄下的元件,要有所區分

20. 傳統部署

npm run build && npm run start

21. pm2部署

它允許您永久保持應用程式活躍,無需停機即可重新載入它們,並不需要傳統部署的.nuxt資料夾,該部署方法也跟生產環境一樣含熱更新

npm install pm2 -g
npm run build
pm2 start ./node_modules/nuxt/bin/nuxt-start



作者:daydreammoon
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2814866/,如需轉載,請註明出處,否則將追究法律責任。

相關文章