Vue3后台通用管理系统(二):header面包屑的实现、tags标签的实现、用户管理页的实现

目录

(一)header组件面包屑的实现

1.通过store存储面包屑数据和操作

2.点击aside组件菜单二级面包屑展示

3.展示面包屑

4.刷新组件时的问题

(二)tags标签页

1.静态组件编写

2.点击菜单选项新增tag和点击tag跳转路由

3.删除tag的路由跳转解决

4.刷新后tagslist数据丢失问题解决

(三)user用户管理页的完成

1.通过mock模拟数据数组

2.使用element-plus搭建结构

3.实现分页展示功能

4.实现搜索框搜索功能

5.新增用户+模态框表单

(1)通过el-dialog和el-form搭建框架

(2)表单功能完善+表单格式验证

(3)发送新增用户请求

6.修改用户数据

7.删除用户数据


(一)header组件面包屑的实现

header组件显示面包屑路径

思路:将当前路径信息存储在currentItem中,根据点击aside菜单跳转到对应路由并更改currentitem信息

1.通过store存储面包屑数据和操作

将aside组件的菜单列表存储到store中

tabList用于存储所有currentItem的数据

在menu.ts中:

// 存储菜单列表
  const menuListData = reactive([
    {
      path: "/",
      name: "home",
      label: "首页",
      icon: "house",
      url: "Home/Home",
    },
    {
      path: "/mall",
      name: "mall",
      label: "商品管理",
      icon: "video-play",
      url: "MallManage/MallManage",
    },
    {
      path: "/user",
      name: "user",
      label: "用户管理",
      icon: "user",
      url: "UserManage/UserManage",
    },
    {
      label: "其他",
      icon: "location",
      children: [
        {
          path: "/page1",
          name: "page1",
          label: "Page1",
          icon: "setting",
          url: "Other/PageOne",
        },
        {
          path: "/page2",
          name: "page2",
          label: "Page2",
          icon: "setting",
          url: "Other/PageTwo",
        },
      ],
    },
  ])

  // tabslist 用于确定当前路径
  const tabsList = [
    {
      path: "/",
      name: "home",
      label: "首页",
      icon: "house",
      url: "Home/Home",
    },
    {
      path: "/mall",
      name: "mall",
      label: "商品管理",
      icon: "video-play",
      url: "MallManage/MallManage",
    },
    {
      path: "/user",
      name: "user",
      label: "用户管理",
      icon: "user",
      url: "UserManage/UserManage",
    },
    {
      path: "/page1",
      name: "page1",
      label: "Page1",
      icon: "setting",
      url: "Other/PageOne",
    },
    {
      path: "/page2",
      name: "page2",
      label: "Page2",
      icon: "setting",
      url: "Other/PageTwo",
    },
  ]
  // 存储当前路径信息
  let currentItem = ref({
    path: "/",
    name: "home",
    label: "首页",
    icon: "house",
    url: "Home/Home",
  })

  // 更改当前路径信息
  function changeCurrent(item: any) {
    currentItem.value.label = item.label
    currentItem.value.path = item.path
  }
  // 每次页面刷新时将面包屑当前路径保存上
  function findCurrentItem() {
    // as any是因为find()一定能找到对应的item
    currentItem.value = breadList.find((item) => {
      return item.path == useRoute().path
    }) as any
  }

2.点击aside组件菜单二级面包屑展示

在component/commonAside中:
// 跳转到对应的路由
function goRouter(item: any) {
    menustore.changeCurrent(item)
    router.push({
        name: item.name,
    })
}

3.展示面包屑

<!-- 面包屑 -->
<el-breadcrumb separator="/" class="bread-crumb">
    <el-breadcrumb-item :to="{ path: '/' }"
        @click="menuStore.changeCurrent({ path: '/', name: 'home', label: '首页', icon: 'house', url: 'Home/Home' })">首页</el-breadcrumb-item>    
    <el-breadcrumb-item v-if="menuStore.currentItem.path != '/'" 
        :to="menuStore.currentItem.path">
        {{ menuStore.currentItem.label }}</el-breadcrumb-item>
</el-breadcrumb>

因为一级面包屑一定是首页,所以点击一级面包屑将‘/’路径的数据传给currentItem

4.刷新组件时的问题

当刷新网页后,路由还是保持不变,但currentItem中存储的当前路径会清空变为默认数据,因此需要在每次项目刷新后,判断当前路径,将tabList中符合当前路径的item对象传给currentItem

在stores/menu.ts中:
// 每次页面刷新时将面包屑当前路径保存上
  function findCurrentItem() {
    // as any是因为find()一定能找到对应的item
    currentItem.value = breadList.find((item) => {
      return item.path == useRoute().path
    }) as any
  }

在component/commonAside中:
// 每次页面刷新时将面包屑当前路径保存上,防止刷新后currentItem数据丢失
//  这个函数放哪里运行都行
menustore.findCurrentItem()

感觉这个解决方法不太简洁,专门新增了一个面包屑标签数组breadList,后面不同用户登录会导致菜单列表不同,到那时再看看面包屑这样处理会不会出问题

(二)tags标签页

实现效果如下: 

二级面包屑和tag要实时对应,在写代码实现的时候要特别注意

1.静态组件编写

tags标签页单独用一个非路由组件编写

在stores/menu中:
// tagsList 标签列表 (默认首页标签一直存在)
  let tagsList = reactive([
    {
      path: "/",
      name: "home",
      label: "首页",
      icon: "house",
      url: "Home/Home",
    },
  ])

在component/commonTag中:
<script setup lang="ts">
import { useMenuStore } from '@/stores/Menu';
import { reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router'

const router = useRouter()
const route = useRoute()
const menuStore = useMenuStore()
let tags = menuStore.tagsList
</script>

<template>
    <div class="tags">
        <el-tag v-for="(tag, index) in tags" :key="tag.name" 
            :closable="tag.name != 'home'" :disable-transitions="false"
            :effect="route.name == tag.name ? 'dark' : 'plain'" >
            {{ tag.label }}</el-tag>
    </div>
</template>

2.点击菜单选项新增tag和点击tag跳转路由

点击aside组件的菜单选项实现新增tag

在stores/menu中:
  // 点击菜单选项增加taglist 并更新当前currentItem
  function addTag(item: any) {
    // 当点击路径不是首页时更新currentItem
    if (item.name == 'home') {
      currentItem.value = {
        path: "/",
        name: "home",
        label: "首页",
        icon: "house",
        url: "Home/Home",
      }
    } else {
      currentItem.value = item
    }

    // 查找item是否在tagslist中存在
    let index = tagsList.findIndex((tag) => {
      return tag.name == item.name
    })
    // 如果item不在tagslist中就加进去,在的话就不做操作
    index == -1 ? tagsList.push(item) : ''
  }

点击tag跳转到对应路由

要注意跳转路由时也需要更改面包屑的当前路径数据currentItem 

在component/commonTag中:

// 点击标签跳转到对应路径 并改变当前tag的数据
function changeCurrentTag(tag: any) {
    // 跳转到对应路径
    router.push(tag.path)
    // 更改currentItem
    menuStore.addTag(tag)
}

<el-tag v-for="(tag, index) in tags" :key="tag.name" 
    :closable="tag.name != 'home'" :disable-transitions="false"
    :effect="route.name == tag.name ? 'dark' : 'plain'" 
    @click="changeCurrentTag(tag)">
        {{ tag.label }}
</el-tag>

3.删除tag的路由跳转解决

删除tab操作 element-plus自带属性

在stores/menu中:
// 删除tagslist中的tag
  function deleteTag(item: any) {
    // 寻找要删除的item的索引
    let index = tagsList.findIndex((tag) => {
      return tag.name == item.name
    })
    // 删除
    tagsList.splice(index, 1)
  }

要注意:在删除tag是要判断删除的是否是当前路由的tag,如果是,就将路由跳转到前一个tag,同时要更改面包屑的当前路径数据

在component/commonTag中:
// 删除tag
function handleClose(tag: any, index: number) {
    // 删除对应tag
    menuStore.deleteTag(tag)
    // 如果删除的是所在的路由 就将路由跳转到前一个tag索引
    if (tag.name == route.name) {
        router.push(tags[index - 1].path)
        // 更改currentItem
        menuStore.addTag(tags[index - 1])
    }
}

<el-tag v-for="(tag, index) in tags" :key="tag.name" 
    :closable="tag.name != 'home'" :disable-transitions="false"
    :effect="route.name == tag.name ? 'dark' : 'plain'" 
    @click="changeCurrentTag(tag)"
    @close="handleClose(tag, index)">
        {{ tag.label }}
</el-tag>

4.刷新后tagslist数据丢失问题解决

点击刷新后tagslist里只会有最开始首页的标签,如果处于其他的路由,就需要重新获取当前路径并将数据加入到tagsList中。

在stores/menu中:
// 每次页面刷新时将面包屑当前路径保存上
  // 将当前路由对应的tag加到taglist中
  function findCurrentItem() {
    // as any是因为find()一定能找到对应的item
    currentItem.value = tabsList.find((item) => {
      return item.path == route.path
    }) as any
    // 将当前路由的tag重新保存在taglist中
    if (currentItem.value.name != 'home') {
      tagsList.push(currentItem.value)
    }
  }

(三)user用户管理页的完成

1.通过mock模拟数据数组

随机生成100个数据,发送查询请求携带参数关键字(搜索功能)、页数、每页限制数量(分页器功能)

get请求采用params传递参数,在config中通过url获取,需要对其进行处理才能使用数据

url为:/mock/user/getuserlist?keyword=&page=1&limit=13,无法与/mock/user/getuserlist匹配,因此要用到正则

在mock/userMockServer中:

// 引入mock.js
import Mock from "mockjs";

// 随机生成100条user数据
let userList = []
for (let i = 0; i < 100; i++) {
    // 用于计算年龄
    let d1 = new Date().getFullYear()
    let d2 = Mock.Random.date()
    let d3 = parseInt(d2.split('-')[0])

    userList.push(Mock.mock({
        id: Mock.Random.guid(),
        name: Mock.Random.cname(),
        addr: Mock.mock('@county(true)'),
        // 'age|18-60': 1,
        age: d1 - d3 + 1,
        birth: d2,
        sex: Mock.Random.integer(0, 1)
    }))
}

// 将传入的params参数转换为对象形式
function paramToObj(url: string) {
    // params通过路径../..?xx=xx&xx=xx的形式传入
    let params = url.split("?")[1]
    // 判断有没有params参数
    if (!params) return {}

    // 对传入的params的格式进行转换
    // 对params解码 将url中的中文等解码出来
    let res = '{"' +
        decodeURIComponent(params)
            .replace(/"/g, '\\"')
            .replace(/&/g, '","')
            .replace(/=/g, '":"') +
        '"}'
    return JSON.parse(res)
}

// 获取列表数据
// get请求使用params参数传递参数 在config.url中获取
Mock.mock(/mock\/user\/getuserlist/, 'get', (config) => {
    // 解构赋值 关键字可为空、页数、每页数量限制
    let { keyword, page = 1, limit = 13 } = paramToObj(config.url)
    return {
        code: 200,
        data: {
            userList
        }
    }
})
在src/api中:
// 获取用户列表数据 传入关键字(可选)、页数page、每页限制limit
// 通常使用params传递参数 参数会展示在url上
export const getUserList = (params: any) => mockRequests({
    url: 'user/getuserlist',
    method: 'get',
    params
})

在view/user中:
import { onMounted } from 'vue'
import { getUserList } from '@/api';

onMounted(async () => {
    let result = await getUserList({ keyword: 'csq', page: 1, limit: 20 })
    // 性别是以0和1存储的,展示时是男女
    userList.value.forEach((item: any) => {
    item.sex = item.sex === 1 ? '女' : '男'

})

2.使用element-plus搭建结构

<div class="user">
        <el-container>
            <el-header>
                <el-button class="add" type="primary" size="" @click="">增加+</el-button>
                <div class="search">
                    <input type="text" placeholder="请输入关键字" v-model="keyword">
                    <el-button type="primary" icon="Search" @click="searchUser">搜索</el-button>
                </div>
            </el-header>
            <el-main>
                <el-table :data="userList" style="width: 100%;height: 622px;" stripe>
                    <el-table-column :prop="item.prop" :label="item.label" :width="item.width" v-for="item in tableLabel"
                        :key="item.prop" />
                    <el-table-column fixed="right" label="操作" width="200">
                        <template #default="scope">
                            <el-button size="small" @click="">修改</el-button>
                            <el-button size="small" type="danger" @click="">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-main>
        </el-container>
        <el-footer>
            <el-pagination background layout="prev, pager, next" :page-size="config.limit" :total="total"
                v-model:current-page="currentPage" />
        </el-footer>
    </div>

3.实现分页展示功能

使用watch检测currentPage的改变(更清晰有效)

官方建议不使用change-current事件(如下)

// 查询用户数组的参数项
let config = reactive({
    keyword: '',
    page: 1,
    limit: 14,
})
// 总条数
let total = ref(0)
// 当前页数
let currentPage = ref(1)
// 双向绑定实时监听分页器的当前页数
// 因为官方不建议使用函数current-change 可能随时会取消该函数
watch(currentPage, (newValue, oldValue) => {
    config.page = newValue
    // 重新展示数据
    getUserData()
})

<el-pagination background layout="prev, pager, next" 
    :page-size="config.limit" :total="total"
    v-model:current-page="currentPage" />

将新的页数数据传给config后,/getuserlist要接收并根据page重新发送数据

// 解构赋值 关键字可为空、页数、每页数量限制
let { keyword, page = 1, limit = 14 } = paramToObj(config.url)

// 分页展示
let list = userList.filter((item, index) => {
    return (index >= (page - 1) * limit && index < page * limit)
})

return {
        code: 200,
        data: {
            userList: list,
            total: count
        }
    }

4.实现搜索框搜索功能

在输入框中输入关键字(允许搜索姓名、地址),点击搜索将keyword传给/getuserlist并重新发送数据

// 存储输入框的关键字
let keyword = ref('')
// 根据关键字搜索
function searchUser() {
    config.keyword = keyword.value
    getUserData()
    config.keyword = ''
}

<div class="search">
    <input type="text" placeholder="请输入关键字" v-model="keyword">
    <el-button type="primary" icon="Search" @click="searchUser">搜索</el-button>
</div>

先进行搜索关键字,再对获得的数组进行页码操作

// 获取列表数据
// get请求使用params参数传递参数 在config.url中获取
Mock.mock(/mock\/user\/getuserlist/, 'get', (config) => {
    // 解构赋值 关键字可为空、页数、每页数量限制
    let { keyword, page = 1, limit = 14 } = paramToObj(config.url)

    // 判断有无关键字并返回对应有关键字的数组
    let pageList = userList.filter((item) => {
        if (keyword && item.name.indexOf(keyword) === -1 && item.addr.indexOf(keyword) === -1) return false
        return true
    })

    // 分页展示
    let list = pageList.filter((item, index) => {
        return index >= (page - 1) * limit && index < page * limit
    })

    return {
        code: 200,
        data: {
            userList: list,
            total: pageList.length
        }
    }
})

5.新增用户+模态框表单

点击增加按钮弹出对话框,输入新增用户信息,点击确定提交增加用户请求,再展示到列表中

(1)通过el-dialog和el-form搭建框架

// 新增用户的对话框 默认不显示
let centerDialogVisible = ref(false)
// 提交格式 用于提交新增用户或修改用户的信息
let ruleForm: any = reactive({
    name: '',
    age: '',
    sex: '',
    birth: '',
    addr: ''
})

<el-dialog v-model="centerDialogVisible" title="新增用户" width="30%" align-center :close-on-click-modal="false"
        :close-on-press-escape="false">
        <span>
            <el-form :model="ruleForm" label-width="120px" ref="ruleFormRef">
                <el-form-item label="姓名" prop="name" :rules="[{ required: true, message: '性别是必填项' }]">
                    <el-input v-model="ruleForm.name" placeholder="请输入姓名" />
                </el-form-item>
                <el-form-item label="年龄" prop="age" :rules="[{ required: true, message: '年龄是必填项' },
                { type: 'number', message: '请输入数字' }]">
                    <el-input v-model.number="ruleForm.age" placeholder="请输入年龄" />
                </el-form-item>
                <el-form-item label="性别" prop="sex" :rules="[{ required: true, message: '性别是必填项' }]">
                    <el-select v-model="ruleForm.sex" placeholder="请输入性别">
                        <el-option label="男" value="男" />
                        <el-option label="女" value="女" />
                    </el-select>
                </el-form-item>
                <el-form-item label="出生日期" prop="birth" :rules="[{ required: true, message: '出生日期是必填项' }]">
                    <el-date-picker v-model="ruleForm.birth" type="date" placeholder="请输入出生日期" value-format="YYYY-MM-DD" />
                </el-form-item>
                <el-form-item label="地址" prop="addr" :rules="[{ required: true, message: '地址是必填项' }]">
                    <el-cascader v-model="ruleForm.addr" :options="pcaTextArr" />
                </el-form-item>
            </el-form>
        </span>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="cancelRuleForm">取消</el-button>
                <el-button type="primary" @click="submitRuleForm">确定</el-button>
            </span>
        </template>
    </el-dialog>

地址(省市区) 的选择采用一个中国地区选择的插件element-china-area-data

element-china-area-data - npm

安装:

npm install element-china-area-data -S

使用省市区三级联动(纯文字)

// 引入省市区地区选择插件
import { pcaTextArr } from "element-china-area-data";

let ruleForm: any = reactive({
    name: '',
    age: '',
    sex: '',
    birth: '',
    addr: ''
})

<el-form-item label="地址" prop="addr" :rules="[{ required: true, message: '地址是必填项' }]">
    <el-cascader v-model="ruleForm.addr" :options="pcaTextArr" />
</el-form-item>

 会以数组的形式存储在addr中

后续提交表单的时候再更改格式

(2)表单功能完善+表单格式验证

在对话框中点击取消或确定后,存储的表单数据和验证提示信息不会消失,需要通过el-form提供的方法resetField对该表单项进行重置,将其值重置为初始值并移除校验结果 

// 将el-form绑定到ruleFormRef
const ruleFormRef = ref<FormInstance>()
// 清空表单输入框内数据
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.resetFields()
}
// 提交新增用户数据 发送请求
function submitRuleForm() {
    ...
    // 隐藏模态框
    centerDialogVisible.value = false
    // 清空表单
    resetForm(ruleFormRef.value)
}
// 取消提交用户表单操作
function cancelRuleForm() {
    // 隐藏模态框
    centerDialogVisible.value = false
    // 清空表单
    resetForm(ruleFormRef.value)
}

<el-form :model="ruleForm" label-width="120px" ref="ruleFormRef">
    <el-form-item label="姓名" prop="name" 
        :rules="[{ required: true, message: '性别是必填项' }]">
        <el-input v-model="ruleForm.name" placeholder="请输入姓名" />
    </el-form-item>
    <el-form-item label="年龄" prop="age" 
        :rules="[{ required: true, message: '年龄是必填项' },
                { type: 'number', message: '请输入数字' }]">
        <el-input v-model.number="ruleForm.age" placeholder="请输入年龄" />
    </el-form-item>
    ...
</el-form>
...
<template #footer>
    <span class="dialog-footer">
        <el-button @click="cancelRuleForm">取消</el-button>
        <el-button type="primary" @click="submitRuleForm">确定</el-button>
    </span>
</template>

表单格式的基本验证

通过el-form-item的rules属性设置,必须搭配prop对应名称才能生效

上面代码出现过了

(3)发送新增用户请求

配置对应的mock请求

在mock/userMockServer中:
// 请求添加数据
Mock.mock('/mock/user/adduserlist', 'post', config => {
    let { name, age, sex, birth, addr } = JSON.parse(config.body)
    userList.unshift({
        id: Mock.Random.guid(),
        name, age, sex, birth, addr
    })

    return {
        code: 200,
        data: {
            message: 'ok了'
        }
    }

})

在api/index中:
// 请求添加用户数据
// 通常会使用data传递参数 参数存储在请求的body里
export const adduserlist = (data: any) => mockRequests({
    url: '/user/adduserlist',
    method: 'post',
    data
})

点击确定按钮发送请求

validate函数:对整个表单的内容进行验证。 接收一个回调函数,或返回 Promise 

如果添加新用户成功,就重新请求渲染数据 

// 提交新增用户数据 发送请求
function submitRuleForm() {
    if (!ruleFormRef.value) return
    // 判断表单验证是否通过
    ruleFormRef.value.validate(async (valid) => {
        if (valid) {
            // 转换格式
            ruleForm.sex = ruleForm.sex == '女' ? 1 : 0
            ruleForm.addr = ruleForm.addr.join(' ')
            // 请求添加数据
            let res = await adduserlist(ruleForm) as any
            if (res.code == 200) { // 使用断言 否则报错没有code属性
                // 刷新数据
                getUserData()
            }

            // 隐藏模态框
            centerDialogVisible.value = false
            // 清空表单
            resetForm(ruleFormRef.value)
        } else {
            ElMessage({
                showClose: true,
                message: '请输入正确的数据',
                type: 'error',
            })
        }
    })
}

6.修改用户数据

因为修改用户数据也需要用到ruleForm数据和表单对话框,因此可以和新增用户的功能公用,只需要加个标志区分即可

添加标志handleFlag实现新增和修改功能的区分

// 标志 是edit还是add
let handleFlag = ref('add')
// 点击增加按钮
function handleAdd() {
    centerDialogVisible.value = true
    handleFlag.value = 'add'
}
// 点击编辑按钮
function handleEdit(row: any) {
    centerDialogVisible.value = true
    handleFlag.value = 'edit'
    console.log(row);
}

<el-dialog :title="handleFlag == 'add' ? '新增用户' : '编辑用户'">

点击编辑后需要获取对应行的数据,并将其展示在表单输入框中

获取行数据#default="scope"

使用template中的作用域插槽,它的作用是在外部获取组件内的数据 ,这里是为了获取这一行的数据,我们让slot-scope值为scope,那么由scope.row就可以得到数据

// 点击编辑按钮
function handleEdit(row: any) {
    centerDialogVisible.value = true
    handleFlag.value = 'edit'

    nextTick(() => {
        // 将row的属性和值赋给ruleForm 浅拷贝
        Object.assign(ruleForm, row)
        // 将空号分割的字符串重新变为数组
        ruleForm.addr = ruleForm.addr.split(' ')
        console.log(ruleForm);
    })
}

<template #default="scope">
    <el-button size="small" @click="handleEdit(scope.row)">修改</el-button>
    <el-button size="small" type="danger" @click="">删除</el-button>
</template>

发送修改用户数据的请求

配置对应的mock请求

在mock/userMockServer中:
// 请求修改数据
Mock.mock('/mock/user/updateuserlist', 'post', config => {
    let { id, name, age, sex, birth, addr } = JSON.parse(config.body)
    // 寻找到对应的用户数据
    userList.forEach(item => {
        if (item.id === id) {
            item.name = name
            item.age = parseInt(age)
            item.sex = sex
            item.birth = birth
            item.addr = addr
        }
    })
    return {
        code: 200,
        data: {
            message: 'ok了'
        }
    }
})

在api/index中:
// 请求修改用户数据
export const updateUserList = (data: any) => mockRequests({
    url: '/user/updateuserlist',
    method: 'post',
    data
})
在view/user中:
// 提交用户数据 发送请求
function submitRuleForm() {
    if (!ruleFormRef.value) return
    // 判断表单验证是否通过
    ruleFormRef.value.validate(async (valid) => {
        if (valid) {
            if (handleFlag.value == 'add') { // 新增
                // 转换格式
                ruleForm.sex = ruleForm.sex == '女' ? 1 : 0
                ruleForm.addr = ruleForm.addr.join(' ')
                // 请求添加数据
                let res = await adduserlist(ruleForm) as any
                if (res.code == 200) { // 使用断言 否则报错没有code属性
                    // 隐藏模态框
                    centerDialogVisible.value = false
                    // 清空表单
                    resetForm(ruleFormRef.value)
                    // 刷新数据
                    getUserData()
                }
            } else { // 编辑
                // 转换格式
                ruleForm.sex = ruleForm.sex == '女' ? 1 : 0
                ruleForm.addr = ruleForm.addr.join(' ')

                // 请求更新数据
                let res = await updateUserList(ruleForm) as any
                if (res.code == 200) {
                    // 隐藏模态框
                    centerDialogVisible.value = false
                    // 清空表单
                    resetForm(ruleFormRef.value)
                    // 刷新数据
                    getUserData()
                }
            }
        } else {
            ElMessage({
                showClose: true,
                message: '请输入正确的数据',
                type: 'error',
            })
        }
    })
}

7.删除用户数据

在mock/userMockServer中:
// 请求删除数据
Mock.mock('/mock/user/deleteuserlist', 'delete', config => {
    // 要删除的用户的id
    let deleteId = config.body

    userList = userList.filter((item: any) => {
        return item.id != deleteId
    })
    return {
        code: 200,
        data: {
            message: '删了'
        },
    }

})

在api/index中:
// 请求删除用户数据 根据id删除
export const deleteUserList = (data: any) => mockRequests({
    url: '/user/deleteuserlist',
    method: 'delete',
    data
})
import { getUserList, adduserlist, updateUserList, deleteUserList } from '@/api';
// 删除用户
function deleteUser(row: any) {
    ElMessageBox.confirm('确定删除该用户吗?',)
        .then(async () => {
            await deleteUserList(row.id).then(res => {
                // console.log(res);
                getUserData()
            })
            ElMessage({
                showClose: true,
                type: 'success',
                message: '删除成功',
            })
        })
        .catch(() => {
            ElMessage({
                type: 'info',
                message: 'Delete canceled',
            })
        })
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值