1. 程式人生 > 實用技巧 >nuxt:從零開始一個移動端專案

nuxt:從零開始一個移動端專案

有關ssr的概念和優點的相關理論可以參考我的另外一篇部落格

這篇主要記錄一下如何從零建立一個nuxt專案

參考:nuxt.js官網

P1.專案建立

nuxt.js官網有推薦使用create-nuxt-app命令一步建立一個nuxt專案,windows的話這裡推薦使用cmd,不要使用git bash(因為使用git bash時一些需要方向鍵進行選擇的時候根本看不到你現在選擇的是哪項,比較難受)

我選的配置如下:

如果npx不可用,可能時npm版本過低,可以使用npm init nuxt-app <你的專案名>

等安裝完成依賴,初始化的專案結構如下:

執行npm run dev就可以執行起來,如果初始化的專案都跑不起來,建議檢查一下自己的node或者npm版本是不是太低

P2. 路由

nuxt.js內建vue-router,不需要修改router.js檔案,只需要在pages目錄下建立對應資料夾,nuxt.js會自動生成路由配置。

pages/test/index.vue 對應的路由為 /test

pages/test/_testName.vue 是動態路由,nuxt.js裡_開頭的為動態路由,可以由params中接收傳參,對應路由為 /test/xx ,其中xx為傳遞的資料

跳轉至動態路由的程式碼如下

    testRoute() {
      this.$router.push({
        name: 'test-testName',  // 動態拼接name
        params: {
          testName: Math.ceil(Math.random() * 10)   // 引數key與路由名對應
        }
      })
    }

P3.資料請求

nuxt.js內建axios外掛,在nuxt.js中配置使用 。對請求的配置可以參考官網文件

  modules: [
    '@nuxtjs/axios'
  ]

可以在nuxt例項中訪問到它,即window.$nuxt.$axios

但注意window物件在服務端渲染期間是無法訪問到的,如果想在服務端渲染期間進行請求,axios物件還會在asyncData與fetch中的引數上下文物件context中訪問到,如

asyncData({ $axios }) {
    // ...
}

fetch({ $axios, store }) {
   // ...  
}

P4.fetch與asyncData

均在服務端渲染期間呼叫,支援請求完成後再展示首屏頁面

不同:

fetch用於更新vuex的state資料,asyncData可以更新元件內部資料。

相同:

1.都只在頁面元件(pages目錄下)下才會被呼叫,子元件的這兩個方法是沒用的。

2.都無法訪問到this,window,document

3.第一個引數都是上下文物件context,context 變數的可用屬性一覽:

屬性欄位型別可用描述
app Vue 根例項 客戶端 & 服務端 包含所有外掛的 Vue 根例項。例如:在使用axios的時候,你想獲取$axios可以直接通過context.app.$axios來獲取
isClient Boolean 客戶端 & 服務端 是否來自客戶端渲染(廢棄。請使用process.client
isServer Boolean 客戶端 & 服務端 是否來自服務端渲染(廢棄。請使用process.server
isStatic Boolean 客戶端 & 服務端 是否來自nuxt generate靜態化(預渲染)(廢棄。請使用process.static
isDev Boolean 客戶端 & 服務端 是否是開發 dev 模式,在生產環境的資料快取中用到
isHMR Boolean 客戶端 & 服務端 是否是通過模組熱替換webpack hot module replacement(僅在客戶端以 dev 模式)
route Vue Router 路由 客戶端 & 服務端 Vue Router 路由例項
store Vuex 資料 客戶端 & 服務端 Vuex.Store例項。只有vuex 資料流存在相關配置時可用
env Object 客戶端 & 服務端 nuxt.config.js中配置的環境變數,見環境變數 api
params Object 客戶端 & 服務端 route.params的別名
query Object 客戶端 & 服務端 route.query的別名
req http.Request 服務端 Node.js API 的 Request 物件。如果 Nuxt 以中介軟體形式使用的話,這個物件就根據你所使用的框架而定。nuxt generate不可用
res http.Response 服務端 Node.js API 的 Response 物件。如果 Nuxt 以中介軟體形式使用的話,這個物件就根據你所使用的框架而定。nuxt generate不可用
redirect Function 客戶端 & 服務端 用這個方法重定向使用者請求到另一個路由。狀態碼在服務端被使用,預設 302redirect([status,] path [, query])
error Function 客戶端 & 服務端 用這個方法展示錯誤頁:error(params)params引數應該包含statusCodemessage欄位
nuxtState Object 客戶端 Nuxt 狀態,在使用beforeNuxtRender之前,用於客戶端獲取 Nuxt 狀態,僅在universal模式下可用
beforeNuxtRender(fn) Function 服務端 使用此方法更新__NUXT__在客戶端呈現的變數,fn呼叫 (可以是非同步){ Components, nuxtState },參考示例

兩個方法都必須做好錯誤捕獲,如果在執行過程中出現了錯誤,頁面會直接渲染失敗

P5.Plugins

plugins是在app例項化之前載入完成的外掛庫,包括第三方外掛或者自制外掛,在nuxt.config.js中配置,通過ssr屬性設定是在服務端時載入還是在客戶端時載入(服務端載入時無window和document)。

配置參考如下:

 plugins: [{
    src: './node_modules/lib-flexible/flexible.js', // 移動端適配
    ssr: false
  }, {
    src: '@/plugins/mint-ui.js',
    ssr: false
  }, {
    src: '@/plugins/lazyload.js',
    ssr: false
  }, {
    src: '@/plugins/vconsole.js',
    ssr: false
  }],

需要在plugins目錄下建立對應的檔案,注意配置ssr為true時是無window物件的,因此如果需要window物件,需要將ssr設定為false

以引入vconsole為例

1.安裝vconsole依賴項

2.在plugins下建立vconsole.js,內容如下

import VConsole from 'vconsole'

const vc = process.env.NODE_ENV === 'development' ? new VConsole() : ''

export default vc

3.在nuxt.config.js中plugins下配置如上,注意配置ssr為false,因為vconsole需要檢查和建立dom

P6.全域性css與sass的全域性樣式變數如何引入

nuxt.config.js中css屬性可以引入全域性樣式檔案、模組、第三方庫,如下

  css: [{
    src: 'mint-ui/lib/style.css',
    lang: 'css'
  }, {
    src: '~/assets/css/global.css',
    lang: 'css'
  }],

如果想引入sass的全域性變數,需要啟用和配置styleResource:

    /**
   * 全域性引入的其他樣式檔案
   * 路徑不能使用~和@
   * See https://zh.nuxtjs.org/api/configuration-build/#styleresources
   */
  styleResources: {
    scss: './assets/css/index.scss',
    // less: ...
    // sass: ...
  },
  modules:[ '@nuxtjs/style-resources'//支援引入全域性scss  ],

P7.移動端適配

簡單粗暴的話,可以考慮引入lib-flexible和postcss-px2rem外掛

lib-flexible或者amfe-flexible可以考慮npm安裝,也可以直接將它們的構建結果的js直接引入到專案中,然後在plugins中引入,ssr設為false,可以參考上面plugins配置

postcss-px2rem或者pxcss-pxtorem安裝之後,在nuxt.config.js中設定如下

 build: {
    postcss: [
      require('postcss-px2rem')({
        remUnit: 75,    // 以設計稿750為參考
        propList: ['*']
      }),
    ],
  }

如果考慮自己實現,還需要處理nuxt的error頁面,不然報錯的時候emmmm

P8.部署

// ...