如何创建一个项目(学习笔记)

前言:

欢迎来到本次教程。这篇文章旨在深入解析在 B 站上的 Vue3 后台管理项目,同时也为您提供了创建此类项目的实践思路。我们将通过这个笔记系统地梳理一个项目的整体框架,涵盖了我们在 Vue 课程中学习的主要内容。

在此过程中,我尝试使用 Vant4 组件库替代了原先的 Element-Plus 组件,但请注意,由于 Vant4 和 Element-Plus 有所不同,有些 Element-Plus 组件可能无法找到完全相同的 Vant4 替代品。因此,本文中的 Vant4 代码仅供参考。

由于时间紧迫,尽管我已尽最大努力保证内容的准确性和完整性,但仍有可能存在一些疏漏或不够完善的地方。如果您在阅读过程中发现任何需要改进的地方,非常欢迎指出,您的建议将对我来说极为宝贵。

在此,小天同学再次向同学们表示感谢。我希望这篇文章能为你的学习提供有价值的参考,让我们一起探索 Vue3 的世界。

使用到的技术:
附本文使用技术的官网链接
vue3:https://cn.vuejs.org/
element-plus:http://element-plus.org/zh-CN/
vant4:https://vant-contrib.gitee.io/vant/#/zh-CN
pinia:https://pinia.web3doc.top/
vuex:https://vuex.vuejs.org/zh/
JSON-SERVER:https://github.com/typicode/json-server
axios:https://www.axios-http.cn/docs/intro
项目出处:[https://www.bilibili.com/video/BV1no4y1Y7gF?p=1&vd_source=6f495a4394638d66c7e55ede1b042f9e](https://www.bilibili.com/video/BV1no4y1Y7gF?


# 1.创建项目 ## 如何创建一个工程 ### 1.打开文件夹(找到对应的文件打开) ![image.png](https://img-blog.csdnimg.cn/img_convert/d5b48dfd3f755f9bd1e3a5549c42f2b9.png#averageHue=#3e85a5&clientId=u38756407-61d3-4&from=paste&height=503&id=ud56e188b&originHeight=1136&originWidth=694&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=448580&status=done&style=none&taskId=ud2e3313e-791a-4507-b1bb-69d0c28d649&title=&width=307)
![image.png](https://img-blog.csdnimg.cn/img_convert/82f93c7ad3b6eeaa605ffe9c35fb848a.png#averageHue=#fcfcfc&clientId=u0da46045-315b-4&from=paste&height=1009&id=u94d3a77e&originHeight=1513&originWidth=1798&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=84959&status=done&style=none&taskId=u23c4d2d2-9e8d-4e65-a0c2-dbf93bcab18&title=&width=1198.6666666666667)
我在这里创建了一个com.xiaotian的空文件夹 ### 2.集成终端打开 ![image.png](https://img-blog.csdnimg.cn/img_convert/46a3d7a4d236b4aad76c3fe80846af12.png#averageHue=#96a2a1&clientId=u38756407-61d3-4&from=paste&height=199&id=u599ca2a0&originHeight=445&originWidth=866&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=47090&status=done&style=none&taskId=ud4b4c022-d054-4e38-b0dc-b0bb5b03ffa&title=&width=387)

3.配置相关指令

如何创建一个项目(学习笔记)_第1张图片

npm init vue@latest

4.配置选择

按键盘的箭头按键选择yes或者no,回车就是下一步,以下是我的选择
如何创建一个项目(学习笔记)_第2张图片
只有vue Router和pinia我选择了yes,其他都是no

5.创建vite

从这一步开始,所有的“在终端中打开,全部指的是右键vue-project再点击在集成终端中打开!!
如何创建一个项目(学习笔记)_第3张图片
右键点击vue-project的位置,选择在集成终端中打开
输入以下指令
如何创建一个项目(学习笔记)_第4张图片

npm i vite

5.引入vant

我们输入以下代码:
如何创建一个项目(学习笔记)_第5张图片

npm i vant

至此,我们的项目基本内容已经创建完毕
(注:想要检查安装的文件版本,可以控package-lock.json中寻找)

最后一步,把没用的东西都删了,保留最基本的组件项目,
如何创建一个项目(学习笔记)_第6张图片
这些文件都可以把里面的内容删除成上图所示的样式。

2.相关配置

接下来我们当然是要改写我们的相关配置了
通常情况下我们要考虑main.js、路由、pinia的stores的配置,部分文件也需要修改vite.config.js的配置。

1.vant配置

(注意,以下采用了两种不同的引入方式:全局引入和部分引入,使用时可以二选一)

全局引入

在main.js中加入以下代码

import { createApp } from 'vue';
// 1. 引入你需要的组件
import { Button } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';

const app = createApp();

// 3. 注册你需要的组件
app.use(Button);

之后每使用一个组件,就在main.js中添加一个就可以了,比如我想添加一个轮播图的组件,就上官网查一下全局引入需要什么代码,复制进去就可以了
比如我想引入一个轮播图,就从vant找到轮播他,打开main.js,复制代码引入就可以。

如何创建一个项目(学习笔记)_第7张图片如何创建一个项目(学习笔记)_第8张图片

按需引入

如果是部分引入,就需要先安装一个插件,再分别引入,操作方法如下:
1.在终端中输入

# 通过 npm 安装
npm i unplugin-vue-components -D

# 通过 pnpm 安装
pnpm add unplugin-vue-components -D

2.打开vite.config.js
如何创建一个项目(学习笔记)_第9张图片
3.从vant4官网–快速上手–方法二–配置插件复制以下内容
如何创建一个项目(学习笔记)_第10张图片
将原本没有的部分,添加到我们刚刚打开的vite.config.js中。如何创建一个项目(学习笔记)_第11张图片

之后就非常简单,我们的组件需要哪一个就直接在script中引入就可以了。

比如我想引入一个轮播图,直接上vant4官网找相关的代码,
如何创建一个项目(学习笔记)_第12张图片
只需要这一行引入。

注意:如果使用的是以下写法,不需要引入这一行代码,可以直接使用

如何创建一个项目(学习笔记)_第13张图片
每个vue组件引入即可(就是复制过来)







2.路由配置

如果你从一开始就跟着我们的操作,左边的列表里是有router的字样的,里面有一个文件index.js,那就只需要如何创建一个项目(学习笔记)_第14张图片

如果你一开始没有自动安装路由,那可就遭老罪喽
你需要在终端中输入

npm install vue-router@4

然后需要做以下配置
如何创建一个项目(学习笔记)_第15张图片

3.pinia配置

1.pinia安装

如果您从一开始就是跟我们的步骤做,那您相对来说比较轻松,直接跳到第2部分。
如何创建一个项目(学习笔记)_第16张图片
但是如果不是,那就遭老罪喽。请执行以下步骤:
1.在终端中输入以下代码:

npm install pinia

2.将以下代码补充到main.js中

import { createPinia } from 'pinia'

app.use(createPinia())

3.在src文件夹下创建一个文件夹,名叫store,在此文件夹下创建一个文件名为:index.js
并添加以下代码

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
  // other options...
})

2.pinia的基本内容

我们把pinia配置好了以后,现在主要的内容给写进去

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'


export const useUsersStore = defineStore("main", {
    // 这个相当于是一个数据仓库,是处理数据用的。
    state: () => {
        return {
         // 比如我可以在这里定义年龄,姓名等等
            // name: "xiaotian",
            // age: 18,
            // id: 1
        };
    },
    // 这个相当于是一个计算属性,也是处理数据用的。比如说,我要把年龄加100岁,
    //那么我就可以在这里写一个方法,然后在页面上调用这个方法,就可以得到加了100岁的年龄了。
    getters: {
      // 比如我想给state的年龄+100
      return state.age + 100;
    },
    //这个相当于是一个method,写一些方法,比如处理数据的方法,比如点击事件的方法,比如axios请求的方法,比如定时器的方法...
    actions: {
    }
})

3.如何使用pinia配置好的数据

在你的组件中(就是写你页面内容的.vue结尾的文件中,引入以下代码)
我的建议是在store(如果你用的是Vuex生成的是store,如果你用的是pinia生成的是stores)文件夹下,创建一个state文件,并创建一个用户文件userInfo.JS和一个总页面index.js
如下图所示
如何创建一个项目(学习笔记)_第17张图片


// 注意,这里from后面是路径,别写错了,不行就先输入  ../  看看弹出来的是啥
import { useUsersStore } from '@/stores/counter.js'
// 这里是做响应式用的,在子页面修改的数据,通过这种方式可以完成同步,原因官网上面写的很清楚
import { storeToRefs } from 'pinia'
// 这里的useUsersStore(),和你store/index.js中配置的是一样的
const store = useUsersStore();

注意最后一行使用的useUsersStore();和你store/index.js中配置的是一样的。
如何创建一个项目(学习笔记)_第18张图片
当然,官网中明确写道这里不能使用解构赋值如何创建一个项目(学习笔记)_第19张图片
需要使用的话,加这个
如何创建一个项目(学习笔记)_第20张图片
也就是把原来的

//修改前
const {name,doubleCount} = store
//修改后
const {name,doubleCount} = storeToRefs(store)
// 加了一个storeToRefs()

至此,我们pinia的基本框架已经配置完成。

4.JSON-SERVER配置

参考文章地址:https://juejin.cn/post/7043424909472563208#heading-4
分为以下几个部分:

  1. node 环境安装
  2. 安装 json-server
  3. 创建数据库(其实就是一个 json 文件)
  4. 启动服务

1.node环境安装

这边建议直接官网下载:点击进入官网。
如何创建一个项目(学习笔记)_第21张图片
随便点一个,狂按下一步

2.安装json-server

官网地址:https://www.npmjs.com/package/json-server
安装指令(同样是终端中安装即可)

npm i json-server
// 想要全局安装选下面这个
npm install -g json-server

3.填写数据

在你本机创建一个文件夹,然后新建一个 json 文件,再填入数据即可。
步骤:

  1. 创建 json-server-demo 文件夹,
  2. 在 json-server-demo 里创建 db.json 文件(这些文件夹和文件名都可以自由命名)。
  3. db.json 文件录入以下数据(数据来自 json-server 官方文档)
{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}

4.启动服务

运行指令

json-server --watch db.json

如果是这个报错,
image.png
安装方式就选择

npm install -g json-server

如果是这个报错,这里就要修改配置
image.png
方法如下(参考文章:http://t.csdn.cn/JYIFA)

  1. 使用管理员方式打开Power Shell
  2. 输入Get-ExecutionPolicy,可以查看到当前的策略
  3. 输入Set-ExecutionPolicy RemoteSigned,设置当前的策略为RemoteSigned
  4. 输入Y

5.数据修改

这一步你可以在浏览器修改,也可以在postman修改,这里我使用的是postman
postman下载地址:点击下载
https://www.postman.com/downloads/?utm_source=postman-home

1.增

如何创建一个项目(学习笔记)_第22张图片
接下来可以增添数据
输入您的posts链接
如何创建一个项目(学习笔记)_第23张图片
如何创建一个项目(学习笔记)_第24张图片
这里就会输出相关代码

2.删

你想删除第二个,下图2中就写posts/2
如何创建一个项目(学习笔记)_第25张图片

3.改

我现在把相关的数据进行修改
就要确定他的id
公式:
http://localhost:3000/posts/{id}
比如我想把第一个修改为

{ "title": "php",
 "author": "xiaotiantian" }

如何创建一个项目(学习笔记)_第26张图片
如何创建一个项目(学习笔记)_第27张图片

4.查

你进入终端中,通过json-server --watch db.json运行以后,红框部分就是你查的数据的全部信息。
如何创建一个项目(学习笔记)_第28张图片
如果你想查询posts数据中,id为1的数据,就这么写

http://localhost:3000/posts/{id}

如果你想查询title为php的数据,你就这么写
http://localhost:3000/posts?title=php
如何创建一个项目(学习笔记)_第29张图片
如过你想查张三,男性,你就用到"&"

http://localhost:3000/posts?name=php&sex=man

5.更新

我想把数据中的xiaotiantian改成tian
步骤就是把操作改成patch,其他部分差不多
如何创建一个项目(学习笔记)_第30张图片
如何创建一个项目(学习笔记)_第31张图片
修改完成

6.修改端口

如果你想要修改我们的端口,不再使用3000,那可以使用以下指令修改

json-server -p 8888 db.json

这样打开以后端口就写改成了8888

7.修改主机端口

终端中输入以下代码修改主机号

json-server --host 0.0.0.0 db.json

如果你想了解更多内容,
请移步:https://www.breword.com/typicode-json-server
中文:

5.axios配置

官网地址:https://www.axios-http.cn/docs/intro

1. 下载Axios

首先,在Vue 3项目中下载Axios库,可以使用npm或yarn进行安装。在终端中进入项目目录,执行以下命令进行安装:

安装npm:

// 下面两个二选一
npm install axios

cnpm install axios -g

2. 配置Axios

我的习惯是,在src目录下建立一个util文件夹,这个文件夹下建立两个文件,
分别命名为:
requese.js
service.js
如下图所示:
如何创建一个项目(学习笔记)_第32张图片
在我们的service.js文件中,引入axios,以及状态管理库的内容

// axios引入
import axios from "axios"
//pinia引入
import store from "../store/index.js"
//创建一个axios实例
const Service = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

request.js我们等会再配置。

3.路由的详细配置

你写一个vue页面,就加一段路由配置,比如你写了login.vue页面。
// 登陆页面

const routes = [
{
  path: "/login",
  name: "login",
  component: () =>
      import ("../views/pages/login.vue") // 懒加载引入登录页面组件
}
]

如果你想写一个嵌套路由,比如这种类型
如何创建一个项目(学习笔记)_第33张图片
那你就需要写一个嵌套路由。
他的基本格式是:

const routes = [
    {
        path: "/",
        name: "layout",
        component: () =>
            import ("../views/Layout/LayOut.vue"),
        redirect: "/index",
        // 子路由/嵌套路由
        children: [{
                path: "/index",
                name: "index",
                component: () =>
                    import ("../views/pages/index.vue") // 懒加载引入首页组件
            },]

    }
]

也就是在配置中多加入一个children项目。

我的外边框(深色部分组件名称是layout),
嵌套部分组件名称是:index.vue,roles.vue,user.vue,goods.vue
那我一项一项写进去就可以了

{
        path: "/",
        name: "layout",
        component: () =>
            import ("../views/Layout/LayOut.vue"),
        redirect: "/index",
        // 子路由/嵌套路由
        children: [{
                path: "/index",
                name: "index",
                component: () =>
                    import ("../views/pages/index.vue") // 懒加载引入首页组件
            },
            {
                path: "/roles",
                name: "roles",
                component: () =>
                    import ("../views/pages/rolesList.vue") // 懒加载引入角色列表组件
            },
            {
                path: "/user",
                name: "user",
                component: () =>
                    import ("../views/pages/userList.vue") // 懒加载引入用户列表组件
            },
            {
                path: "/goods",
                name: "goods",
                component: () =>
                    import ("../views/pages/goodsList.vue") // 懒加载引入商品列表组件
            }
        ]


    }

完整配置:

import { createRouter, createWebHashHistory } from 'vue-router'
import store from "../store/index.js" // 引入Vuex的store实例

// 路由配置
const routes = [
    // 登陆页面
    {
        path: "/login",
        name: "login",
        component: () =>
            import ("../views/pages/login.vue") // 懒加载引入登录页面组件
    },
    {
        path: "/",
        name: "layout",
        component: () =>
            import ("../views/Layout/LayOut.vue"),
        redirect: "/index",
        // 子路由/嵌套路由
        children: [{
                path: "/index",
                name: "index",
                component: () =>
                    import ("../views/pages/index.vue") // 懒加载引入首页组件
            },
            {
                path: "/roles",
                name: "roles",
                component: () =>
                    import ("../views/pages/rolesList.vue") // 懒加载引入角色列表组件
            },
            {
                path: "/user",
                name: "user",
                component: () =>
                    import ("../views/pages/userList.vue") // 懒加载引入用户列表组件
            },
            {
                path: "/goods",
                name: "goods",
                component: () =>
                    import ("../views/pages/goodsList.vue") // 懒加载引入商品列表组件
            }
        ]


    }
]


// 生成hash路由对象
const router = createRouter({
    history: createWebHashHistory(),
    routes
})


// 路由守卫
router.beforeEach((to, from, next) => {
    /**
     * to:即将要进入的目标
     * from:正要离开的路由
     * next:只有执行next()页面才会进行跳转
     */
    // 判断用户是否登录
    console.log("store", store.state.uInfo)
    const uInfo = store.state.uInfo.userInfo
    if (!uInfo.username) {
        // 未登录,跳转到login
        if (to.path === "/login") {
            next()
            return
        }
        next("/login")


    } else {


        next()
    }
})


// 暴露路由对象
export default router

4.项目的详细配置

这一部分可以说是项目当中最难配置和理解的了。涉及到多种业务逻辑。如列表的登录,增删改查等等
这个部分的代码可以按照:
html+css->axios请求配置(配一次)->思考组件包含的功能->aixos基本的逻辑配置->vue组件逻辑->axios配置
这个顺序完成。

1.登录页面

1.html+css配置

我们先写登录页面怎么实现跳转
这个最基础的写法是…

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <button><a href="登录地址">a>button>
body>
html>

我不建议这么写,因为这么写没分。

html和css我们就不细说了,我这里直接给出





那在这个组件里的script怎么写呢
那首先我们是要访问我们库里面有没有相关的数据在,比如账号、密码、个人信息等等,
并且核实账号密码是否正确

2.axios请求配置

我们打开service.js写入以下部分**(看注释,只写新增部分!!最上边的代码之前我已经配置了,
不信点这里!!(点击这里)
)**

//这里是原本就有的,之前axios叫你们配置过的部分
import axios from "axios"
import store from "../store/index.js"
// 使用create创建axios实例
const Service = axios.create({
    timeout:8000,
  //这里写URL地址/接口地址等
    baseURL:"http://122.114.229.181:3000/api/private/v1/",
    headers:{
        "Content-type":"application/json;charset=utf-8",
        "Authorization":store.state.uInfo.userInfo.token
    }
})

// ******************************************
//下面是新增的部分
// post请求
export const post=config=>{
    return Service({
        ...config,
        method:"post",
        data:config.data
    })
}
// get请求
export const get=config=>{
    return Service({
        ...config,
        method:"get",
        params:config.data
    })
}
// put请求
export const put=config=>{
    return Service({
        ...config,
        method:"put",
        data:config.data
    })
}// delete请求
export const del=config=>{
    return Service({
        ...config,
        method:"delete"
    })
}

当然了,我们还需要状态管理器store/userInfo.js。

export default {
  state: {
    // 定义一个名为 userInfo 的变量,其值为一个对象。
    // 初始值为通过判断 localStorage 中是否存在名为 loginData 的数据,
    // 如果存在则将该数据解析为一个 JavaScript 对象,否则设置为空对象 {}。
    userInfo: (localStorage.getItem('loginData') && JSON.parse(localStorage.getItem('loginData'))) || {},
  },
  actions: {
    // 定义一个名为 setUserInfo 的 mutation 方法来修改 userInfo 变量的值。
    // 这个方法接收两个参数:state 和 uInfo,其中 state 是当前模块的状态对象,
    // 而 uInfo 是用于更新 userInfo 的新值。
    setUserInfo(state, uInfo) {
      state.userInfo = uInfo;
    },
  },
};

如果你的程序中要写很多个状态管理,我建议在stores文件夹下新建一个index.js文件

import { createStore } from 'vuex'
import uInfo from "./state/userinfo.state.js"
export default createStore({

    // 数据比较多,分模块
    modules: {
        uInfo
    }
})

以上内官网都有,
传送门:(点这里)
链接:https://www.axios-http.cn/docs/req_config

3.思考组件包含的功能

这里既然是登陆页面,就要考虑用户登录信息的核对和保存
既然如此,我们首先想到需要连接状态管理器路由以及响应式,于是我们导入以下代码

import { ref } from 'vue';
import { useStore } from 'vuex';
import { useRouter } from 'vue-router';

4.aixos基本的逻辑配置

既然我们我们需要发送api请求,我们就需要使用axios
这时候我们之前建立的util/request.js就排上了用场,我们把它当作一个中转站
我们打开util文件夹下的request.js文件,进行一个登录请求的配置
代码如下:

// 导入service中导出的HTTP方法
import { post, get, put, del } from "./service"

// 登录API
export const loginApi = data => {
    return post({
        url: "/login",
        data
    })
}

之后我们再导入登录请求的API


接下来的思路就是:
1.引入了以后,当然要调用store和router,所以我们要创建一个pinia实例一个路由实例,同时,创建一个响应式应用,储存登陆数据。还要用commit方法更新用户信息以及本地储存。
于是我写出以下代码,注意,代码是对上述login.vue代码的补充


登录页面可以添加一个路由守卫,当登录了以后会怎么样,如果没有登录会怎么样。
详细代码请看注释路由守卫部分
至此,router.js的配置完全结束,大家看一下这一段完整代码

import { createRouter, createWebHashHistory } from 'vue-router'
import store from "../store/index.js" // 引入Vuex的store实例

// 路由配置
const routes = [
    // 登陆页面
    {
        path: "/login",
        name: "login",
        component: () =>
            import ("../views/pages/login.vue") // 懒加载引入登录页面组件
    },
    {
        path: "/",
        name: "layout",
        component: () =>
            import ("../views/Layout/LayOut.vue"),
        redirect: "/index",
        // 子路由/嵌套路由
        children: [{
                path: "/index",
                name: "index",
                component: () =>
                    import ("../views/pages/index.vue") // 懒加载引入首页组件
            },
            {
                path: "/roles",
                name: "roles",
                component: () =>
                    import ("../views/pages/rolesList.vue") // 懒加载引入角色列表组件
            },
            {
                path: "/user",
                name: "user",
                component: () =>
                    import ("../views/pages/userList.vue") // 懒加载引入用户列表组件
            },
            {
                path: "/goods",
                name: "goods",
                component: () =>
                    import ("../views/pages/goodsList.vue") // 懒加载引入商品列表组件
            }
        ]

    }
]

// 生成hash路由对象
const router = createRouter({
    history: createWebHashHistory(),
    routes
})



//***************************************************
//*******************路由守卫在这里!!****************
//***************************************************
// 路由守卫
router.beforeEach((to, from, next) => {
    /**
     * to:从哪个页面
     * from:到哪个页面
     * next:只有执行next()页面才会进行跳转
     */
    // 判断用户是否登录
    console.log("store", store.state.uInfo)
    const uInfo = store.state.uInfo.userInfo
    if (!uInfo.username) {
        // 未登录,跳转到login
        if (to.path === "/login") {
            next()
            return
        }
        next("/login")

    } else {

        next()
    }
})

// 暴露路由对象
export default router

我们的登陆页面及其功能详解到此结束。

与此同时,我们还需要写入登录
我们要做的是请求数据
在element-plus里面使用的是这个按钮,绑定了一个时间,再vant的按钮中可以随便找一个,button,绑定一个事件就好。
image.png

const handleLogin = async () => {   //
  const res = await loginApi(loginData.value); // 
  if (res.data) {   //
  store.commit('setUserInfo', res.data);  //
  localStorage.setItem('loginData', JSON.stringify(res.data));  //
  router.push({ path: '/' }); // 
}
};

现在考虑,如果登录正在加载,或服务器出错应该弹出提示,这个提示的信息也要在axios文件中配置

import { Toast } from 'vant';

// 请求拦截器
axios.interceptors.request.use(config => {
  // 显示 loading
  Toast.loading({
    message: 'Loading...',
    forbidClick: true, // 禁止点击背景
    loadingType: 'spinner', // loading 样式
  });
  return config; // 返回请求配置
});

// 响应拦截器
axios.interceptors.response.use(response => {
  // 隐藏 loading
  Toast.clear();
  const data = response.data; // 获取响应数据
  if (data.code !== 200) {
    // 处理错误
    Toast.fail(data.msg || '服务器出错'); // 显示错误提示
    return Promise.reject(data); // 返回 rejected 状态的 Promise
  }
  return data; // 返回响应数据
}, error => {
  // 隐藏 loading
  Toast.clear();
  Toast.fail('服务器错误'); // 显示错误提示
  return Promise.reject(error); // 返回 rejected 状态的 Promise
});

至此,我们的service.js已经基本配置完毕。
现提供完整代码

import axios from "axios"
import store from "../store/index.js"
import { Toast } from 'vant';

// 创建一个axios实例,并设置请求超时时间、基础URL和请求头
const Service = axios.create({
    timeout: 8000,
    baseURL: "http://122.114.229.181:3000/api/private/v1/",
    headers: {
        "Content-type": "application/json;charset=utf-8",
        "Authorization": store.state.uInfo.userInfo.token
    }
})

// 请求拦截器
axios.interceptors.request.use(config => {
  // 显示 loading
  Toast.loading({
    message: 'Loading...',
    forbidClick: true, // 禁止点击背景
    loadingType: 'spinner', // loading 样式
  });
  return config; // 返回请求配置
});

// 响应拦截器
axios.interceptors.response.use(response => {
  // 隐藏 loading
  Toast.clear();
  const data = response.data; // 获取响应数据
  if (data.code !== 200) {
    // 处理错误
    Toast.fail(data.msg || '服务器出错'); // 显示错误提示
    return Promise.reject(data); // 返回 rejected 状态的 Promise
  }
  return data; // 返回响应数据
}, error => {
  // 隐藏 loading
  Toast.clear();
  Toast.fail('服务器错误'); // 显示错误提示
  return Promise.reject(error); // 返回 rejected 状态的 Promise
});

// post请求
export const post = config => {
    // 使用Service实例发送post请求,并传入请求配置
    return Service({
        ...config,
        method: "post",
        data: config.data
    })
}


// get请求
export const get = config => {
    // 使用Service实例发送get请求,并传入请求配置
    return Service({
        ...config,
        method: "get",
        params: config.data
    })
}


// put请求
export const put = config => {
    // 使用Service实例发送put请求,并传入请求配置
    return Service({
        ...config,
        method: "put",
        data: config.data
    })
}


// delete请求
export const del = config => {
    // 使用Service实例发送delete请求,并传入请求配置
    return Service({
        ...config,
        method: "delete"
    })
}

现在将login.vue的代码完整版整理出来







2.角色页面

在这个页面里我要实现用户的增删改查功能,也就是要获取数据并且完成修改

1.html+css配置

老规矩,html直接给出,因为都是element的配置。vant只要找到相同的功能直接写就可以



在上述代码中,我想要实现数据的实时响应,这里做了个单/双向绑定(注意这并不一定是我写的,有些事element-plus自带的,不需要去看)
:data=“rolesList”
v-model=“formData.roleName”
v-model=“formData.roleDesc”

以及按钮触发的方法
这里可以理解为一个点击事件,做了一个绑定,点击以后自动触发函数。
@close=“clearForm”//‘编辑角色’:‘新建角色’(这个是关闭事件)
@click=“goToHome”
@click=“dialogFormVisible=true”//新建角色
@click="editRow(item)//编辑
@click=“deleteRow(item)”//删除
@click="submitForm(userForm)//确定按钮

我们既然想要获取用户信息,肯定要通过axios发送请求,增删改查等等,也就是post get delect等等
那首先我们就要考虑axios配置
无非就是获取相关的api
打开util/request文件,把这些代码加进去

// 以上是之前写过的部分
// 导入service中导出的HTTP方法
import { post, get, put, del } from "./service"

// 登录API
export const loginApi = data => {
    return post({
        url: "/login",
        data
    })
}

// *******************************
// ******以下是新增部分************
// *******************************
// 获取角色API
export const getRolesApi = data => {
    return get({
        url: "roles",
        data
    })
}


// 新建角色API
export const addRolesApi = data => {
    return post({
        url: "roles",
        data
    })
}


// 编辑角色API
export const editRolesApi = data => {
    return put({
        url: `roles/${data.id}`,
        data
    })
}


// 删除角色API
export const rolesDeleteApi = data => {
    return del({
        url: `roles/${data.id}`
    })
}

(其实内部结构差不多,文件名也写的很清楚。如果你喜欢,export const dog=data都可以。)

接下来我们应该处理script里面的内容,步骤如下:
1.数据和表单的响应式(数据可以用ref,表单可以用composables中的useForm)
2.调用接口
3.点击事件的逻辑
打开roleList.vue文件

import { ref } from 'vue';
import {  useForm } from '@/composables';
import { getRolesApi, addRolesApi, editRolesApi, rolesDeleteApi } from '@/util/request.js';

同时创建
响应式接收数据

const rolesList = ref([]);
const dialogFormVisible = ref(false);
const formData = ref({ roleName: '', roleDesc: '' });
const userForm = ref();

在表单中,创建一个规则,标记某个项目必须填写

const rules = {
  roleName: {
    required: true,
    message: '此项必填',
    trigger: 'blur',
  },
};

我们还需要验证表单数据是否符合规则

const { validate } = useForm(userForm, formData, rules);
  • userForm:一个响应式的对象,用于存储表单数据。
  • formData:一个普通的对象,包含了表单数据的初始值。
  • rules:一个普通的对象,包含了表单验证的规则。

在上面的代码中,当表单提交时,我们调用validate 方法进行验证。如果验证通过,就执行表单提交操作。如果验证失败,validate 方法会返回 false,我们可以在组件中根据这个返回值来进行错误提示等操作。

我们表单已经制作完成,下面就要执行以下步骤:

  1. 获取用户数据
  2. 编辑/添加
  3. 删除
  4. 新建

我们的思路是,通过API实现各种功能。通过异步处理就可以了

// 定义获取角色列表的函数
const getList = async () => {
  const res = await getRolesApi();
  rolesList.value = res.data;
};


// 定义提交表单的函数
const submitForm = async () => {
  const res = await validate();
  if (!res) {
    return;
  }
  if (formData.value.id) {
    await editRolesApi(formData.value);
  } else {
    await addRolesApi(formData.value);
  }
  dialogFormVisible.value = false;
  getList();
};


// 定义编辑角色的函数
const editRow = (row) => {
  dialogFormVisible.value = true;
  const { roleName, roleDesc, id } = row;
  formData.value = { id, roleName, roleDesc };
};


// 定义删除角色的函数
const deleteRow = async (row) => {
  await rolesDeleteApi(row);
  getList();
};


// 定义清空表单的函数
const clearForm = () => {
  formData.value = { roleName: '', roleDesc: '' };
};


// 初始化时获取角色列表
getList();

如果提交表单函数看不懂,我这里写了详细注释

// 定义提交表单的函数
const submitForm = async () => {
  // 首先调用了validate()方法来验证表单数据
  // validate()方法是由上文引入的useForm自定义Hook返回的方法之一,用于验证表单数据是否符合预设的规则
  // validate()方法返回一个Promise,我们使用await语句等待这个Promise解析
  const res = await validate();

  // 如果验证失败(validate()方法返回的Promise解析为false),
  // 那么我们立即返回,停止函数的执行,避免提交无效的表单数据
  if (!res) {
    return;
  }

  // 如果表单数据(formData.value)中包含id字段,那么我们认为用户正在编辑一个已存在的角色
  // 在这种情况下,我们调用editRolesApi()方法来更新这个角色的信息
  // editRolesApi()方法接受一个包含角色数据的对象作为参数,并返回一个Promise,我们使用await语句等待这个Promise解析
  if (formData.value.id) {
    await editRolesApi(formData.value);
  } else {
    // 如果表单数据(formData.value)中不包含id字段,那么我们认为用户正在创建一个新的角色
    // 在这种情况下,我们调用addRolesApi()方法来创建新的角色
    // addRolesApi()方法接受一个包含角色数据的对象作为参数,并返回一个Promise,我们使用await语句等待这个Promise解析
    await addRolesApi(formData.value);
  }

  // 不论是创建新的角色还是编辑已存在的角色,我们都会在表单提交成功后隐藏表单对话框
  // 我们通过将dialogFormVisible.value设为false来隐藏对话框
  dialogFormVisible.value = false;

  // 表单提交成功后,我们需要获取最新的角色列表以便在页面上显示
  // 我们通过调用getList()方法来获取最新的角色列表
  getList();
};

好了,下面是roleList.vue完整代码