手把手教你实现一个vue3+ts+nodeJS后台管理系统(一)

2,593 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

前言

本系列将通过前端vue + ts加后端nodeJS的技术框架从零实现一个后台管理系统,作者主业是web前端开发小白,刚刚学完vue3与nodeJS技术不久,因此本系统算是一个练手项目,参考了一些项目的写法,可能有一些做的不够好的地方,欢迎讨论!

技术栈

前端

  • 语言:typeScript
  • 前端框架:vue 3
  • 脚手架:vite
  • 路由:vue-router 4
  • 状态管理:vuex 4
  • CSS 预编译处理:sass
  • 网络请求工具:axios
  • 前端 UI 框架:element-plus 2

后端

  • 语言:javaScript
  • 运行环境:node.js 14
  • 后端开发框架:express 4
  • 数据库:mysql
  • 缓存数据库:redis
  • 数据库映射模块(ORM):sequelize 5

前端项目构建

先附上本人的node及npm版本

image.png

前端项目

安装,选择vue、typeScript

npm create vite@latest
cd vue_ts-app
npm install
npm run dev

image.png

运行项目

npm run dev

image.png

输入网址出现这个页面说明创建成功

image.png

vscode打开查看目录结构

image.png

项目就创建完成了,在vscode打开并在终端运行命令npm run dev

此时不会自动在浏览器打开,若需要得在package.json文件script字段的dev属性值后添加--open

安装系统所需依赖

1.将@作为src文件夹的别名

安装所需ts类型

npm install @types/node --save-dev

vite.config.ts下添加如下配置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src') // 路径别名
    },
    extensions: ['.js', '.json', '.ts', '.vue'] // 使用路径别名时想要省略的后缀名,可以自己 增减
  }
});

tsconfig.jsoncompilerOptions配置项下添加如下配置属性

"baseUrl": ".",
// 用于设置解析非相对模块名称的基本目录,相对模块不会受到baseUrl的影响
"paths": {
  // 用于设置模块名到基于baseUrl的路径映射
  "@/*": ["src/*"]
}

2.安装所需依赖

  • 一. vuex

  • 1.安装

    npm install vuex@4.0.2
    

    2.创建store文件夹及配置文件index.ts,并导入以下配置

    import { createStore } from 'vuex';
    export default createStore({
      state: {
        count: 0
      },
      mutations: {
        SET_COUNT: (state, count) => {
          count += 1;
          state.count = count;
        }
      },
      actions: {},
      getters: {}
    });
    

    3.在main.ts中引入

    import { createApp } from 'vue';
    import './style.css';
    import store from '@/store/index';
    import App from '@/App.vue';
    ​
    const app = createApp(App);
    app.use(store).mount('#app');
    

    4.创建测试页面并测试(test.vue)

    <template>
      <div>
        count:{{ count }}
        <button @click="addCount">count++</button>
      </div>
    </template><script setup lang="ts">
    import { ref } from 'vue';
    import { useStore } from 'vuex';
    // 导入store
    const store = useStore()
    // 将count赋值
    const count = ref(store.state.count)
    // count增加方法
    function addCount() {
      count.value++
      store.commit('SET_COUNT', count.value)
    }
    </script><style scoped></style>
    

    App.vue

    <template>
      <Test />
    </template>
    <script setup lang="ts">
    import Test from './components/test.vue';
    ​
    </script><style scoped></style>
    

    可以看到功能没问题

image.png

  • 二. vue-router

  • 1.安装

    npm install vue-router@4
    

    2.创建router文件夹添加配置文件

    import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
    ​
    const routes: RouteRecordRaw[] = [
      {
        path: '/',
        name: 'Test',
        component: () => import('@/components/test.vue') // 注意这里要带上 文件后缀.vue
      }
    ];
    ​
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    });
    ​
    export default router;
    

    3.在main.ts文件中导入

    import router from '@/router/index'
    // 在app后添加
    app.use(router)
    

    4.将App.vue修改为路由视图

    <template>
      <router-view></router-view>
    </template>
    <script setup lang="ts"></script><style scoped></style>

    5.测试发现url改变

image.png

  • 三. element-plus

  • 1.安装

    npm install element-plus@2 --save
    npm install -D unplugin-vue-components unplugin-auto-import
    

    2.在vite.config.ts添加如下配置

    // vite.config.ts
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue';
    import { resolve } from 'path';
    import AutoImport from 'unplugin-auto-import/vite'
    import Components from 'unplugin-vue-components/vite'
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({
      // ...
      plugins: [
        // ...
        AutoImport({
          resolvers: [ElementPlusResolver()],
        }),
        Components({
          resolvers: [ElementPlusResolver()],
        }),
      ],
      // ...
    })
    

    3.volor支持

    如果你使用volar,可在tsconfig.json 中通过 compilerOptions.type 指定全局组件类型

    // tsconfig.json
    {
      "compilerOptions": {
        // ...
        "types": ["element-plus/global"]
      }
    }
    

    4.测试

    将test.vue的button修改

    <ElButton @click="addCount">count++</ElButton>
    

image.png

  • 四.axios封装

  • 1.安装

    npm install axios
    

    2.添加utils文件夹并添加http.ts配置文件

    import Axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
    ​
    const BASE_URL = ''; //请求接口url 如果不配置 则默认访问链接地址
    const TIME_OUT = 20000; // 接口超时时间const instance = Axios.create({
      baseURL: BASE_URL,
      timeout: TIME_OUT
    });
    ​
    // 添加请求拦截器
    instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    ​
    // 添加响应拦截器
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        console.log(response);
        return response.data;
      },
      (error: AxiosError) => {
        return Promise.reject(error);
      }
    );
    ​
    export default instance;
    

    3.在utils文件夹下创建api文件夹备用

前端项目的初始化到这里就结束了

后端项目

初始化

1.创建一个新文件夹vue_ts-server

2.用vscode打开并执行命令初始化文件

npm init -y
安装express
npm i express@4.17.1
1.1在根目录创建项目入口文件app.js
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
​
// write your code here...// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(9999, function () {
  console.log('api server running at http://127.0.0.1:9999')
})
1.2 配置 cors 跨域
  1. 运行如下的命令,安装 cors 中间件:
npm i cors@2.8.5
  1. app.js 中导入并配置 cors 中间件(app.listen()之前):
// 导入 cors 中间件
const cors = require('cors')
// 将 cors 注册为全局中间件
app.use(cors())
1.3 配置解析表单数据的中间件
  1. 安装body-parser
npm install body-parser@1.20.1
  1. 在app.js中添加配置
const bodyParser = require('body-parser');
app.use(
  bodyParser.urlencoded({
    extended: true
  })
);
​
app.use(bodyParser.json());
1.4 初始化路由相关的文件夹
  1. 在项目根目录中,新建router文件夹,用来存放所有的路由模块

    路由模块中,只存放客户端的请求与处理函数之间的映射关系

  2. 在项目根目录中,新建router_handler文件夹,用来存放所有的路由处理函数模块

    路由处理函数模块中,专门负责存放每个路由对应的处理函数

1.5 初始化用户路由模块
  1. router 文件夹中,新建 user.js 文件,作为用户的路由模块,并初始化代码如下:

    const express = require('express')
    // 创建路由对象
    const router = express.Router()
    ​
    // 登录
    router.post('/login', (req, res) => {
      res.send('login OK')
    })
    ​
    // 将路由对象共享出去
    module.exports = router
    
  2. app.js 中,导入并使用 用户路由模块

    // 导入并注册用户路由模块
    const userRouter = require('./router/user')
    app.use('/user', userRouter)
    
1.6 抽离用户路由模块中的处理函数

目的:为了保证 路由模块 的纯粹性,所有的 路由处理函数,必须抽离到对应的 路由处理函数模块

  1. /router_handler/user.js 中,使用 exports 对象,分别向外共享如下两个 路由处理函数

    /**
     * 在这里定义和用户相关的路由处理函数,供 /router/user.js 模块进行调用
     */// 登录的处理函数
    exports.login = (req, res) => {
      res.send('login OK')
    }
    
  2. /router/user.js 中的代码修改为如下结构:

    const express = require('express')
    const router = express.Router()
    ​
    // 导入用户路由处理函数模块
    const userHandler = require('../router_handler/user')
    ​
    // 登录
    router.post('/login', userHandler.login)
    ​
    module.exports = router
    
1.6 在postman中测试

1.首先在终端中输入运行命令

node app.js

2.在postman中测试成功

image.png

参考

一个基于vite构建的vue3+pinia+ts+elementUI plus的初始化开箱即用的项目模版