(一)基于 vue-element-admin 前端與后端框架搭建

前端搭建

項目初始化
git clone https://gitee.com/panjiachen/vue-element-admin.git
cd vue-element-admin
npm i
npm run dev
成功訪問
image.png

image.png

項目精簡

  • 刪除 src/views 下的源碼,保留:
    dashboard: 首頁
    error-page: 異常頁面
    login: 登錄
    redirect: 重定向
  • 對 src/router/index 進行相應修改
  • 刪除 src/router/modules 文件夾
  • 刪除 src/vendor 文件夾

如果是線上項目,建議將 components 的內(nèi)容也清理,以免影響訪問速度,或者直接使用 vue-admin-template 構(gòu)建項目
src/router/index 精簡完后

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

/* Layout */
import Layout from '@/layout'

export const constantRoutes = [
  {
    path: '/redirect',
    component: Layout,
    hidden: true,
    children: [
      {
        path: '/redirect/:path(.*)',
        component: () => import('@/views/redirect/index')
      }
    ]
  },
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    path: '/auth-redirect',
    component: () => import('@/views/login/auth-redirect'),
    hidden: true
  },
  {
    path: '/404',
    component: () => import('@/views/error-page/404'),
    hidden: true
  },
  {
    path: '/401',
    component: () => import('@/views/error-page/401'),
    hidden: true
  },
  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [
      {
        path: 'dashboard',
        component: () => import('@/views/dashboard/index'),
        name: 'Dashboard',
        meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
      }
    ]
  }
]

/**
 * asyncRoutes
 * the routes that need to be dynamically loaded based on user roles
 */
export const asyncRoutes = [
  // 404 page must be placed at the end !!!
  { path: '*', redirect: '/404', hidden: true }
]

const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})

const router = createRouter()

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router
重新啟動 npm run dev
image.png

項目配置

通過 src/settings.js 進行全局配置:

  • title: 站點標題,進入某個頁面后,格式為:頁面標題-站點標題
 title: '三味書屋',
image.png
  • showSettings: 是否顯示右側(cè)懸浮配置按鈕
  • tagsView: 是否顯示頁面標簽功能條
  • fixedHeader: 是否將頭部布局固定
  • sidebarLogo: 菜單欄中是否顯示 LOGO
  • errorLog: 默認顯示錯誤日志的環(huán)境
    通過全局搜索可以看到 src/utils/get-page-title.js 中引用了 全局的 title
import defaultSettings from '@/settings'

const title = defaultSettings.title || '三味書屋'

export default function getPageTitle(pageTitle) {
  if (pageTitle) {
    return `${pageTitle} - ${title}`
  }
  return `${title}`
}

get-page-title.js 在 src/permission.js 中被引用

Node 簡介

Node 是基于 V8 引擎的 Javascript 運行環(huán)境,它使得 Javascript 可以在服務端直接與操作系統(tǒng)進行交互,與文件控制,網(wǎng)絡交互,進行控制等。
Chrome 瀏覽器同樣是集成了 V8 引擎的 Javascript 運行環(huán)境,與 Node 不同的是它們向 Javascript 注入的內(nèi)容不同 Chrome 向 Javascript 注入了 window 對象,Node 注入的是 global ,這使得兩者應用場景完全不同,Chrome 的 Javascript 所有的指令都需要通過 Chrome 瀏覽器作為中介實現(xiàn)

Express |簡介

express 是一個輕量級的 Node Web 服務端框架,同樣是一個人氣超高的項目,它可以幫助我們快速的搭建,基于 Node 的 Web 應用

項目初始化

創(chuàng)建項目目錄 admin-demo-node,進入目錄執(zhí)行命令初始化項目
npm init -y 
安裝依賴
npm i -S express
創(chuàng)建 app.js
// 引用 express
const express = require('express')

// 創(chuàng)建 express 應用
const app = express()

// 監(jiān)聽 / 路徑 get 請求
app.get('/',function(req,res){
    // 通過 get 請求的時候會返回個客戶端
    res.send('hello node')
})

// 使 express 監(jiān)聽 5000 端口號發(fā)起的 http 請求
const server = app.listen(5000,function(){
    const {address,port} = server.address()
    console.log('http Server is running on http://%s:%s',address,port)
})
啟動項目

修改 package.json


image.png

執(zhí)行命令啟動

node app.js

image.png

瀏覽器輸入 http://localhost:5000
image.png

Express 三大基礎概念

中間件

中間件是一個函數(shù),請求和響應周期中被順序調(diào)用
寫一個中間函數(shù)
調(diào)用中間件注意事項:

  • next() 必須調(diào)用,否則不會向下執(zhí)行,也就是說 執(zhí)行完上上面的代碼后,next() 下面的代碼不會再執(zhí)行了,會一直等待
  • 一定要在發(fā)起請求之前調(diào)用,否則請求已經(jīng)執(zhí)行完畢,也不會去調(diào)用中間件
 /**
  * 寫一個中間函數(shù)
  *     調(diào)用中間件注意事項:
  *         1. next() 必須調(diào)用,否則不會向下執(zhí)行,也就是說 執(zhí)行完上上面的代碼后,
  *            next() 下面的代碼不會再執(zhí)行了,會一直等待
  *         2. 一定要在發(fā)起請求之前調(diào)用,否則請求已經(jīng)執(zhí)行完畢,也不會去調(diào)用中間件
  */ 
const myLogger = function(req,res,next){
    console.log('myLogger')
    next()
}

// 通過 app.use() 使用中間件,和 vue 加載插件非常相似
app.use(myLogger)
路由

應用如何響應請求的一種規(guī)則

響應 / 路徑的 get 請求

// 監(jiān)聽 / 路徑 get 請求
app.get('/',function(req,res){
    // 通過 get 請求的時候會返回個客戶端
    res.send('hello node')
})

響應 / 路徑的 post 請求

// 監(jiān)聽 / 路徑 post 請求
app.post('/',function(req,res){
    res.send('post 請求')
})

規(guī)則主要分兩部分

  • 請求方法: get ,post ......
  • 請求的路徑:/ , /user, /*user$/......
異常處理

通過自定義異常處理中間件處理請求中產(chǎn)生的異常

// 異常處理中間件,它也是一個 function
app.get('/user',function(req,res){
    throw new Error('這是故意拋出的異常')
})

// 注意參數(shù)一個都不能少否則,視為普通中間件
// 異常處理要放到請求之后調(diào)用
const errorHandler = function(err,req,res,next){
    console.log('errorHandler......')
    res.status(500).json({
        error: -1,
        msg: err.toString()
    })
    res.send('down......')
}

// 使用中間件
app.use(errorHandler)

使用時需要注意兩點:

    1. 參數(shù)一個都不能少,否則會視為普通中間件
    1. 中間件需要在請求之后引用

瀏覽器輸入 http://localhost:5000/user

image.png

后端框架搭建

路由

安裝 boom 依賴,最大的好處是可以快速的幫我們生成一些異常信息

npm i -S boom

app.js

// 引用 express
const express = require('express')

// 應用我們自定義的中間件
const router = require('./router')

// 創(chuàng)建 express 應用
const app = express()

// 將我們自定義的全局路由,托管到自定義的 router 下進行處理
app.use('/',router)


// 使 express 監(jiān)聽 5000 端口號發(fā)起的 http 請求
const server = app.listen(5000,function(){
    const {address,port} = server.address()
    console.log('http Server is running on http://%s:%s',address,port)
})

創(chuàng)建 router 文件夾,創(chuàng)建 router/index.js

// 引入 express
const express = require('express')
// 引入 boom
const boom = require('boom')
// 引入自定義的 router
const userRouter = require('./user') 

const {
    CODE_ERROR
} = require('../utils/constant')

// 注冊路由  通過 Router() 的實例化,完成一個 router 的注冊
const router = express.Router()

// 監(jiān)聽根路徑的處理
router.get('/',function(req,res){
    res.send('歡迎學習三味書屋管理后臺')
})


// 導出 router 主要作用幫我們來進行路由的監(jiān)聽
module.exports = router

創(chuàng)建 router/user.js

// 引入 express
const express = require('express')

const router = express.Router()

router.get('/info',function(req,res,next){
    res.json('user info ...')
})

module.exports = router

創(chuàng)建 router 文件夾,創(chuàng)建 router/constant.js

// 導出一個錯誤狀態(tài)碼
module.exports = {
    CODE_ERROR: -1
}

啟動,訪問根路徑 http://localhost:5000

image.png

app.js 引入 userRouter

// 通過 userRouter 來處理 /user 路由,對路由進行解耦
// 這里我們指定了路由的前綴 /user 
router.use('/user',userRouter)

這里指定的路由的前綴 /user 所有訪問路徑前要加 /user
訪問 http://localhost:5000/user/info

image.png

添加 404 異常處理
/**
 * 集中處理 404 請求的中間件
 *  注意:該中間件必須放在正常處理流程之后,否則會攔截正常請求
 */
router.use((req,res,next) => {
    // 使用 next 其實是繼續(xù)的將異常向下傳遞,應為后續(xù)可能還要加一些異常處理
    next(boom.notFound('接口不存在'))
});

訪問一個不存在的路徑


image.png
添加我們自定義的異常中間件

自定義路由異常處理中間件
注意兩點:

  • 方法的參數(shù)不能少
  • 方法必須放在路由最后
/**
 * 自定義路由異常處理中間件
 *  注意兩點:
 *      1. 方法的參數(shù)不能少
 *      2. 方法必須放在路由最后
 */
router.use((err,req,res,next) => {
    console.log(err)
    /**
     * 1. 首先獲取 message ,message 就是我們上面自定義的 message,如果不存在返回一個“系統(tǒng)錯誤”
     * 2. 去拿 statusCode ,statusCode 是從 output 里面拿,如果沒有拿到默認返回的就是 500
     * 3. 獲取 errroMessage,仍然是從 output 中獲取,playload 就是我們的參數(shù),如果沒有就返回 err.message
     * 4. 最后通過 res.status 將錯誤碼返回,返回錯誤碼之后再返回一個 json ,json 中封裝了我們的異常信息
     */
    const msg = (err && err.message) || '系統(tǒng)錯誤'
    const statusCode = (err.output && err.output.statusCode) || 500
    const errorMsg = (err.output && err.output.payload && err.output.payload.error) || err.message
    res.status(statusCode).json({
        code: CODE_ERROR,
        msg,
        error: statusCode,
        errorMsg
    })
})

訪問一個不存在的路徑時,會返回一個 json 的結(jié)果,方便前端做出處理


image.png
我們看一下 err 對象
  data: null,
  isBoom: true,
  isServer: false,
  output: {
    statusCode: 404,
    payload: { statusCode: 404, error: 'Not Found', message: '接口不存在' },
    headers: {}
  },
  reformat: [Function],
  typeof: [Function: notFound]
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容