vue-cli實現非同步請求返回mock模擬資料

wojiaoao發表於2022-03-18

  在前後端分離開發的過程中,前端開發過程中,頁面的資料顯示一般都是寫死的靜態資料,也就是沒有經過介面,直接寫死在程式碼中的,在後端給出介面後,再替換為介面資料,為了減少對接成本,mock就出現了。通過預先跟伺服器端約定好的介面,模擬請求資料甚至邏輯,能夠讓前端開發更加獨立自主,不會被服務端的開發所阻塞。

  網上有不少使用mockjs模擬資料的文章,但基本都是本地攔截請求返回資料,在network 中沒有發出任何的請求,本地除錯起來很不好,只能通過console.log來除錯。為了實現真正的非同步請求,那麼就需要真正的伺服器介面,而在開發vue-cli專案時,本地開發執行啟動命令後,實際就是啟動了一個本地伺服器,那麼只要把介面地址都在本地伺服器中配置並使用mock返回資料就可以實現真正的非同步請求了,這樣除錯就和真正的請求一模一樣了。

  開始實現

  因為是vue-cli專案,請先安裝node和npm。

  1、首先,需要全域性安裝vue-cli:

> npm install -g @vue-cli

  2、建立vue-cli專案:

> vue create vue-mock

  建立成功後進入專案根目錄,執行npm run serve啟動,應該可以成功訪問vue示例頁面  

  本示例使用的版本是vue-cli 4.5.13、vue3、webpack4,如果發現某個配置不生效,請留意是否已經被廢棄。

  3、安裝axios

> npm install axios -S

  4、main.js新增aixos,修改如下

// main.js
import { createApp } from 'vue' import App from './App.vue' import axios from 'axios' const vueApp = createApp(App) vueApp.config.globalProperties.$axios = axios // vue3與vue2的區別,不再是通過prototype vueApp.mount('#app')

  5、安裝mockjs

> npm install mockjs -D

  6、在根目錄新建mock資料夾,在mock資料夾下新建index.js檔案,並在main.js中引入index.js,程式碼如下:

// mock/index.js
import Mock from 'mockjs' Mock.mock('/url', 'get', (req, res) => { return Mock.mock({ status: 200, req, res, data: '請求成功' }) })
// main.js
import { createApp } from 'vue' import App from './App.vue' import axios from 'axios' import '../mock/index' // 引入mock路由攔截 const vueApp = createApp(App) vueApp.config.globalProperties.$axios = axios vueApp.mount('#app')

 

  7、修改helloWorld.vue檔案如下:

// helloWorld.vue
<template> <div> <button @click="getMockData">獲取mock資料</button> </div> </template> <script> export default { name: 'HelloWorld', methods: { getMockData() { this.$axios.get('/url').then(res => { console.log(res) }) } } } </script> <style scoped> </style>

這時候頁面效果如下:

   到了這一步可以說是成功實現mock資料返回了,細心的朋友可能已經發現,network裡面並沒有出現請求,我們只能通過console檢視返回結果,當請求數量多時就不太好除錯了,那有沒有什麼辦法可以讓請求出現在network中呢?

  前面已經說到執行專案時,就是啟動了一個本地伺服器,只要想辦法把介面路由配置進去就可以了,接著往下看

  9、修改vue.config.js中的devServer的配置,如果沒有該檔案則新建

// vue.config.js
const Mock = require('mockjs')
module.exports = {
  //...
  devServer: {
    port: 8082,
    before: function(app, server) { // webpack4使用before,webpack使用setupMiddlewares
      app.get('/url', function(req, res) {
        res.json(Mock.mock({
          status: 200,
          data: '請求成功啦~'
        }));
      });
    }
  }
};

   註釋main.js中引入的mock配置

import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'
// import '../mock/index' // 引入mock路由攔截
const vueApp = createApp(App)
vueApp.config.globalProperties.$axios = axios
vueApp.mount('#app')

  重啟服務,重新點選按鈕,成功請求,並且在network也出現了該請求,如下圖

 

 

  這樣似乎已經實現了我們的目的了,既使用了mock模擬資料,也方便了除錯,但是,在我們修改了返回的資料內容時,請求介面,發現還是原來的資料,因為是修改配置檔案,所以每次修改都需要重啟服務,這也太麻煩了吧,我們想每次修改before裡的內容時,伺服器都能夠自動熱更新,就像修改其他檔案一樣,瀏覽器自動更新,繼續往下走。

  10、安裝chokidar外掛,監聽mock資料夾,實現介面路由熱更新,想了解更多chokidar的內容請自行搜尋

> npm install chokidar -D

  11、在mock資料夾下新建mock-server.js,借鑑於vue-element-admin中的mock新方案實現,內容如下,就不具體細說了,大家可以自行除錯

// mock/mock-server.js
const chokidar = require('chokidar') const path = require('path') const mockDir = path.join(process.cwd(), 'mock') // 刪除對應的介面路由快取 function removeRegisterRoutes() { Object.keys(require.cache).forEach(i => { if (i.includes(mockDir)) { console.log(i) delete require.cache[require.resolve(i)] } }) } // 註冊介面路由,每增加一個路由,app._router.stack就增加一個堆疊 function registerRoutes(app){ const mocks = require('./index') // 這裡必須在函式內引用,否則無法實現熱更新 let count = 0 for (const mock of mocks) { app[mock.method](mock.url, mock.response); count++ } return { start: app._router.stack.length - count, count } } module.exports = (app) => { let { start, count } = registerRoutes(app) chokidar.watch(mockDir, {}).on('all', (event, path) => { if (event === 'change' || event === 'add') { app._router.stack.splice(start, count) // 先刪除舊的api路由,再重新註冊新的路由 removeRegisterRoutes() const stack = registerRoutes(app) start = stack.start count = stack.count } }) }

  注意,修改mock-server.js檔案內容不會觸發自動更新,具體原因這裡就不說了,可以自己想一想哦~

  12、修改mock中的index.js檔案

// mock/index.js
const Mock = require('mockjs') const routers = [ { url: '/url', method: 'get', response: (req, res) => { res.json(Mock.mock({ status: 200, data: '請求成功~' })) } }, { url: '/url/path', method: 'get', response: (req, res) => { res.json(Mock.mock({ status: 200, data: '請求介面/url/path' })) } } ] module.exports = routers

  13、修改vue.config.js的beforte

// vue.config.js
//
const Mock = require('mockjs') module.exports = { //... devServer: { port: 8082, before: require('./mock/mock-server') } };

  重新啟動,點選按鈕,請求成功,修改mock中的index裡面的返回資料,回到頁面點選按鈕,發現返回資料已改變,到此,已實現介面請求返回mock資料。

  示例程式碼請點選獲取

  如有不對或者建議,請提出,謝謝。

相關文章