Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

so丶簡單發表於2018-11-08

前言

以nuxt作為vue的服務端渲染,適合剛接觸或者準備上vue ssr的同學參考和學習, 此專案涉及註冊、登入、商品展示、地址管理等等,從前端到後端到最後到服務端部署,讓你體驗到全棧開發到樂趣。

專案地址如遇網路不佳,請移步國內映象加速節點

效果演示

檢視demo請戳這裡(請用chrome手機模式預覽)

移動端掃描下方二維碼

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

API介面文件

介面文件地址(基於apidoc)

技術棧

vue2 + vuex + vue-router + mint-ui + nuxt

專案執行


git clone git@github.com:EasyTuan/nuxt-elm.git

# 國內映象加速節點:git@gitee.com:easytuan/node-elm-api.git

cd nuxt-elm

npm install

npm run dev

#模版快速生成
npm run tep `檔名`

# pm2部署
npm run start

複製程式碼

補充

此專案有配套的後臺系統,如果想體驗前後臺同時開發,可以下載對應的後臺系統:後臺專案傳送地址

如果只做前端開發,請忽略這句話。

目標功能

  • [x] 商家列表 -- 完成
  • [x] 購物車功能 -- 完成
  • [x] 餐館食品列表頁 -- 完成
  • [x] 店鋪評價頁面 -- 完成
  • [x] 商家詳情頁 -- 完成
  • [x] 登入、註冊 -- 完成
  • [x] 修改密碼 -- 完成
  • [x] 個人中心 -- 完成
  • [x] 紅包 -- 完成
  • [x] 收貨地址 -- 完成

業務介紹

目錄結構

├── assets               // 靜態資源
│   ├── images                // 圖片資源
│   ├── services              // api請求
│   ├── styles                // 樣式檔案
│   └── utils                 // 常用工具類
├── components           // 元件
├── config
│   └── index.js              // 配置檔案
├── layouts              // 佈局
├── middleware           // 中介軟體
├── pages                // 頁面
├── plugins              // 外掛
├── static               // 靜態資源
└── store                //vuex狀態樹
複製程式碼

部分截圖展示

首頁展示

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐 Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

個人資料

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐 Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

我的

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐 Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

訂餐

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐 Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

商家評價

Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐 Vue 服務端渲染(SSR)、Nuxt2 - 從入門到實踐

說明

如果對您有幫助,您可以點選專案 "Star" 支援一下 謝謝! ^_^

或者您可以 "follow" 一下,我會不斷開源更多的有趣的專案

如有問題請直接在 Issues 中提,或者您發現問題並有非常好的解決方案,歡迎 PR ?

開發日常記錄

nuxt模版搭建

這裡關於專案初始化,我是直接使用的 Nuxt 官網提供的 starter 模板


# 安裝 vue-cli
npm install -g vue-cli

# 初始化專案
vue init nuxt-community/starter-template nuxt-ssr-demo

# 安裝依賴
cd nuxt-ssr-demo
npm install

# 啟動本地服務
npm run dev

複製程式碼

訪問 http://localhost:3000 ,現在我們來看下初始化好的專案目錄


├── assets                      // 靜態資源
├── components                  // 全域性元件
├── layouts                     // 頁面佈局
├── middleware                  // 中介軟體
├── pages                       // 路由頁面
├── static                      // 靜態資源,打包檔名不會被hash
├── store                       // vuex
├── nuxt.config.js              // nuxt配置檔案
├── package.json
├── README.md

複製程式碼

注意:nuxt預設會讀取pages裡面的vue檔案,自動生成路由,如需要自定義路由,可在nuxt.config.js中配置對應引數。

request請求封裝

資料和展示層的剝離是有必要的,這也是為什麼前端都提倡MV*的設計模式,而對request請求封裝是我們第一步要完成的。這裡我選了axios作為HTTP請求客戶端,axios相容瀏覽器端和node端,同時提供了請求攔截、響應攔截等讓我們開發更加愉快的功能。

config/index.js 中寫入:


const json = require('../package.json');
const port = json.config.nuxt.port;

module.exports = {
  IS_RELEASE: true, // true線上,false測試

  BASE_URL: `http://localhost:${port}/api`, // 測試

  // BASE_URL: `https://elm.caibowen.net/api`, // 生產

  // IMG_URL: 'http://localhost:9000/', // 測試

  IMG_URL: 'https://easytuan.gitee.io/node-elm-api/public/', // 生產(使用碼雲Gitee Pages 服務)

  HEADERS: {
    'Content-Type': 'application/json;charset=UTF-8'
  },

  TIMEOUT: 12000, // api超時時間

};

複製程式碼

assets/utils/request.js 中寫入:


import axios from 'axios';
import config from '~/config';
import { Toast } from 'mint-ui';

axios.defaults.baseURL = config.BASE_URL;
axios.defaults.timeout = config.TIMEOUT;
axios.defaults.headers = config.HEADERS;

// 請求攔截器
axios.interceptors.request.use( request => {
  if (!config.IS_RELEASE) {
    console.log(
      `${new Date().toLocaleString()}【 M=${request.url} 】P=`,
      request.params || request.data,
    );
  }
  return request;
}, error => {
  return Promise.reject(error);
});

export default async (options = { method: 'GET' }) => {
  let isdata = true;
  if (
    options.method.toUpperCase() !== 'POST'
    && options.method.toUpperCase() !== 'PUT'
    && options.method.toUpperCase() !== 'PATCH'
  ) {
    isdata = false;
  }
  const res = await axios({
    method: options.method,
    url: options.url,
    data: isdata ? options.data : null,
    params: !isdata ? options.data : null,
  });
  if (res.status >= 200 && res.status < 300) {
    if (!config.IS_RELEASE) {
      console.log(
        `${new Date().toLocaleString()}【介面響應:】`,
        res.data,
      );
    }
    // 瀏覽器環境彈出報錯資訊
    if(typeof window !== "undefined" && res.data.code !== 0) {
      Toast(res.data.msg);
    }
    return res.data;
  }else {
    if(typeof window !== "undefined" && res.data.code !== 0) {
      Toast('請求錯誤');
    }
  }

};

複製程式碼

最後所有api請求都寫進server.js檔案,方便統一管理。

跨域處理

使用過 vue 的同學,肯定知道對於專案中的跨域,vue-cliwebpack 中的 proxy 選項進行了一層封裝。它暴露出來的是一個叫 proxyTable 的選項,是對 webpack 中的 proxy 和其三方外掛 http-proxy-middleware 的一個整合。

不幸的 Nuxt 中沒有 proxyTable 這麼一個配置項來進行跨域的配置。當然幸運的是,在 Nuxt 中你可以直接通過配置 http-proxy-middleware 來處理跨域。更幸運的是 Nuxt 官方提供了兩個包來處理 axios 跨域問題。

首先,進行安裝

npm i @nuxtjs/axios @nuxtjs/proxy -D
複製程式碼

然後在 nuxt.config.js 檔案裡進行配置

  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  proxy: [
    [
      '/api',{
        // target: 'http://localhost:9000',
        target: 'https://elm-api.caibowen.net',
        changeOrigin: true,
        pathRewrite: { '^/api' : '/' }
      }
    ]
  ],
複製程式碼

然後你就可以安心使用你的 axios 進行跨域請求了

專案部署

到這一步的同學,你得先確保你擁有一個自己的伺服器。如果沒有的話,趕緊去買一個(我不會和你說AWS和google雲有提供免費一年的雲伺服器試用)

OK,文章繼續。在進行部署講解前,我們先看一下 Nuxt 提供的幾個命令

命令 描述
nuxt 啟動一個熱載入的 Web 伺服器(開發模式) localhost:3000
nuxt build 利用 webpack 編譯應用,壓縮 JS 和 CSS 資源(釋出用)
nuxt start 以生成模式啟動一個 Web 伺服器 (nuxt build 會先被執行)
nuxt generate 編譯應用,並依據路由配置生成對應的 HTML 檔案 (用於靜態站點的部署)

開始部署

上傳程式碼到伺服器,然後執行命令nuxt build && nuxt start 監聽3000埠。 接下來,開始配置你的 nginx (用於埠轉發)

 server {
  # 埠,http為 80,如果部署了https請監聽 443
  listen 80;
  # 域名
  server_name elm.caibowen.net;
  # 反向代理
  location / {
    proxy_pass http://localhost:3000;
  }
}
複製程式碼

然後重啟 nginx

nginx -s restart
複製程式碼

然後你就能在 elm.caibowen.net 訪問到你的網站啦

最後

對於 Nuxt,在使用層面,是比較簡單、好上手的。相對 vue-ssr 來說,它大大的簡化了開發的配置,讓開發人員可以只需思考業務的開發,而不用太去擔心檔案的配置。其中 Nuxt 通過監聽 pages 目錄檔案變更並自動生成路由更是直接省去了我們平常對於路由的配置。

但是,目前 Nuxt 整體還是有待提高的,目前社群相關的三方外掛比較有限,市面上相關的參考資料也相對比較少。

不管如何,希望 Nuxt 社群可以越來越好吧 ~

相關文章