十八、element-plus 用户页面展示

一、api

UserModel.ts

/**

* 用户信息

*/

export interface UserInfo{

avatar:string;

id:string;

introduction:string;

name:string;

roles:Array<string>

}

/**

* 用户列表查询参数

*/

export interface UserListParm{

deptId:string | number;

loginName:string;

currentPage:number;

pageSize:number;

total:number;

}

user.ts

import http from "@/http/http"

import { UserInfo, UserListParm } from "./UserModel"

enum Api {

    getInfo = '/api/sysUser/getInfo',

    getLeftTree = '/api/dept/list',

    getUserList = '/api/user/list'

}

export const getInfoApi = async () => {

    return await http.get<UserInfo>(Api.getInfo)

}

//获取用户部门树

export const getLeftTreeApi = async () => {

    return await http.get(Api.getLeftTree)

}

//获取用户列表

export const getUserListApi = async (parm: UserListParm) => {

    return await http.get(Api.getUserList, parm)

}

二、composables

useLeftTree.ts

  

import { DeptModel, SelectNode } from "@/api/dept/DeptModel";

import { getLeftTreeApi } from "@/api/user/user";

import { nextTick, onMounted, reactive, ref } from "vue";

export default function useLeftTree(emit){

     //树的ref属性

     const parentTree = ref<InstanceType<typeof ElTree>>();

    const treeData=reactive({

        data:[]

    })

 //选中的数据

 const selectNode = reactive<SelectNode>({

    id: '',

    name: ''

})

//树的属性

    const defaultProps=reactive({

        children:'children',

        label:'name'

    })

     //树的点击事件

     const handleNodeClick = (data: DeptModel) => {

        console.log('点击了')

        selectNode.id = data.id;

        selectNode.name = data.name

        console.log(selectNode)

        emit('treeClick',data.id)

    }

    const getTreeData=async()=>{

        let res=await getLeftTreeApi()

        if(res&&res.code==200){

            treeData.data=res.data

            nextTick(()=>{

                //处理默认选中第一个节点

                const nodes=document.querySelector('.el-tree-node') as any

                console.log("nodes:%s",nodes.textContent);

                if(nodes){

                    nodes.click()

                }

            })

        }

    }

   onMounted(()=>{

       getTreeData()

   })

    //加号和减号的点击事件

    const openBtn = (data: DeptModel) => {

        console.log(data)

        //设置展开或者关闭

        data.open = !data.open;

        if (parentTree.value) {

            parentTree.value.store.nodesMap[data.id].expanded = !data.open;

        }

    }

    return{

        defaultProps,

        handleNodeClick,

        treeData,

        getTreeData,

        parentTree,

        openBtn

    }

}

useUserTable.ts

import { getUserListApi } from "@/api/user/user";

import { UserListParm } from "@/api/user/UserModel";

import { reactive } from "vue";

export default function useUserTable(){

    const tableData=reactive({

        list:[]

    })

      //表格查询的参数

      const listParm = reactive<UserListParm>({

        deptId:'',

        pageSize:10,

        currentPage:1,

        total:0,

        loginName:''

    })

     //查询表格

     const getUserList = async() =>{

        let res = await getUserListApi(listParm)

        console.log('表格加载完成')

        console.log(res)

        if(res && res.code == 200){

            //把返回的数据设置到表格绑定的数据里面

            tableData.list = res.data.records

            //设置分页总条数

            listParm.total = res.data.total;

        }

    }

     //树组件调用,查询用户列表

     const treeClick = async(deptId:number) =>{

        //设置部门Id

        listParm.deptId = deptId

        //加载表格

        getUserList();

    }

     //页容量改变时触发

     const sizeChange = (size:number) =>{

        listParm.pageSize = size;

        //重新加载表格

        getUserList();

    }

    //页数改变时触发

    const currentChange = (page:number) =>{

        listParm.currentPage = page;

        //重新加载表格

        getUserList();

    }

    return {

        tableData,

        listParm,

        getUserList,

        treeClick,

        sizeChange,

        currentChange

    }

}

三、views

LeftTree.vue

  

<template>

  <el-tree

    ref="parentTree"

    :data="treeData.data"

    node-key="id"

    :props="defaultProps"

    default-expand-all

    :highlight-current="true"

    :expand-on-click-node="false"

    @node-click="handleNodeClick"

  >

    <template #default="{ node, data }">

      <div class="custom-tree-container">

        <!-- 长度为0说明没有下级 -->

        <span v-if="data.children.length == 0">

          <DocumentRemove style="width: 1.3em; height: 1.3em; margin-right: 5px;color: #8c8c8c;"></DocumentRemove>

        </span>

        <!-- 点击展开和关闭 -->

        <span v-else @click.stop="openBtn(data)">

          <component

            style="width: 1.1em; height: 1.1em; margin-right: 5px;color: #8c8c8c;"

            :is="data.open ? Plus : Minus"

          />

        </span>

        <span>{{ node.label }}</span>

      </div>

    </template>

  </el-tree>

</template>

<script setup lang='ts'>

import { DocumentRemove, Plus, Minus } from '@element-plus/icons'

import useLeftTree from '@/composables/user/useLeftTree';

//注册事件

const emit = defineEmits(['treeClick'])

//树相关数据

const { treeData, defaultProps,handleNodeClick,openBtn,parentTree } = useLeftTree(emit);

</script>

<style lang="scss">

.el-tree {

  font-size: 14px;

  margin-top: 15px;

  .el-tree-node {

    position: relative;

    padding-left: 10px;

  }

  // 子集像右偏移 给数线留出距离

  .el-tree-node__children {

    padding-left: 20px;

  }

  //这是竖线

  .el-tree-node :last-child:before {

    height: 40px;

  }

  .el-tree > .el-tree-node:before {

    border-left: none;

  }

  .el-tree > .el-tree-node:after {

    border-top: none;

  }

  //这自定义的线 的公共部分

  .el-tree-node:before,

  .el-tree-node:after {

    content: "";

    left: -4px;

    position: absolute;

    right: auto;

    border-width: 1px;

  }

  .tree :first-child .el-tree-node:before {

    border-left: none;

  }

  // 竖线

  .el-tree-node:before {

    border-left: 1px solid #d9d9d9;

    bottom: 0px;

    height: 100%;

    top: -25px;

    width: 1px;

  }

  //横线

  .el-tree-node:after {

    border-top: 1px solid #d9d9d9;

    height: 20px;

    top: 14px;

    width: 12px;

  }

  .el-tree-node__expand-icon.is-leaf {

    width: 8px;

  }

  //去掉elementui自带的展开按钮  一个向下的按钮,打开时向右

  .el-tree-node__content > .el-tree-node__expand-icon {

    display: none;

  }

  //每一行的高度

  .el-tree-node__content {

    line-height: 30px;

    height: 30px;

    padding-left: 10px !important;

  }

}

//去掉最上级的before  after 即是去电最上层的连接线

.el-tree > div {

  &::before {

    display: none;

  }

  &::after {

    display: none;

  }

}

</style>

Index.vue

<template>

  <div class="common-layout">

    <el-container>

      <el-aside width="200px">

        <LeftTree @treeClick="treeClick"></LeftTree>

      </el-aside>

      <el-main>

          <!-- 搜索栏-->

            <el-form :model="listParm" label-width="80px" :inline="true" size="mini">

                <el-form-item>

                    <el-input placeholder="请输入用户姓名" v-model="listParm.loginName"></el-input>

                </el-form-item>

                <el-form-item>

                    <el-button >搜索</el-button>

                    <el-button  style="color: #FF7670;">重置</el-button>

                    <el-button   type="primary">新增</el-button>

                </el-form-item>

            </el-form>

         <el-table :height="tableHeigth" :data="tableData.list" border stripe>

                <el-table-column prop="loginName" label="姓名" />

                <el-table-column prop="deptName" label="所属部门" />

                <el-table-column prop="mobile" label="电话" />

                <el-table-column prop="email" label="邮箱" />

                <el-table-column label="操作" width="310" align="center">

                    <template #default="scope">

                        <el-button size="mini" type="primary" >编辑</el-button>

                        <el-button size="mini" type="primary"  >分配角色</el-button>

                        <el-button size="mini" type="danger" >删除</el-button>

                    </template>

                </el-table-column>

            </el-table>

              <!-- 分页

           

            size-change:

            -->

            <el-pagination

                @size-change="sizeChange"

                @current-change="currentChange"

                :current-page.sync="listParm.currentPage"

                :page-sizes="[10, 20, 40, 80, 100]"

                :page-size="listParm.pageSize"

                :total="listParm.total"

                layout="total, sizes, prev, pager, next, jumper"

                background

            ></el-pagination>

      </el-main>

    </el-container>

  </div>

</template>

<script setup lang="ts">

import useUserTable from '@/composables/user/useUserTable';

import LeftTree from '@/views/system/user/LeftTree.vue'

import { nextTick, onMounted, ref } from 'vue';

//容器的高度

const containerHeight = ref(0);

//表格的高度

const tableHeigth = ref(0);

//表格列表

const { listParm, getUserList, tableData,treeClick,sizeChange,currentChange } = useUserTable();

onMounted(() => {

    //注意:需要放到nextTick

    nextTick(() => {

        containerHeight.value = window.innerHeight - 100

        tableHeigth.value = window.innerHeight - 220

    })

})

</script>

四、mock 数据

import Mock from 'mockjs'

Mock.mock(new RegExp('/api/sysUser/getInfo'+'.*'),'get',{

    "msg":"获取成功",

    "code":200,

    "data":{

        "id":9,

        "name":"超级管理员",

        "avatar":null,

        "introduction":null,

        "roles":[

            "sys:user:edit",

            "sys:role:delete",

            "sys:menu:add",

            "sys:user:delete",

            "sys:role:add",

            "sys:menu:edit",

            "sys:user:add",

            "sys:role:edit",

            "sys:menu:delete",

            "sys:systemCode",

            "sys:phoneRoot",

            "sys:addGoodsCategory",

            "sys:code:add",

            "sys:addDepartment",

            "sys:role:assign",

            "sys:cs2",

            "sys:document",

            "sys:user:assign",

            "sys:cs1",

            "sys:test",

            "sys:phone:index",

            "sys:editGoodsCategory",

            "sys:manage",

            "sys:code:edit",

            "sys:editDept",

            "sys:goodsCategory",

            "sys:1",

            "sys:dept",

            "sys:goods",

            "sys:1-1",

            "sys:deleteDept",

            "sys:user",

            "sys:systenConfig",

            "sys:role",

            "sys:menu"

        ]

    }

})

Mock.mock(new RegExp('/api/user/list'+'.*'),'get',{

    "msg":"成功",

    "code":200,

    "data":{

        "records":[

            {

                "id":9,

                "username":"admin",

                "loginName":"超级管理员",

                "password":"$2a$10$rDkPvvAFV8kqwvKJzwlRv.i.q.wz1w1pz0SFsHn/55jNeZFQv/eCm",

                "authorities":null,

                "nickName":"超级管理员",

                "mobile":"110",

                "email":"admin@163.com",

                "deptId":1,

                "deptName":"高原机械制造有限公司",

                "createTime":"2023-08-08T03:11:11.000+00:00",

                "updateTime":"2019-12-16T02:25:53.000+00:00",

                "isAdmin":"1",

                "sex":"0",

                "postId":null,

                "postName":null,

                "permissionList":null,

                "accountNonExpired":true,

                "accountNonLocked":true,

                "credentialsNonExpired":true,

                "enabled":true

            },

            {

                "id":70,

                "username":"zsf",

                "loginName":"张三丰",

                "password":"1234",

                "authorities":null,

                "nickName":"菜鸟一只",

                "mobile":"18687116223",

                "email":"3501754007@qq.com",

                "deptId":1,

                "deptName":"云南南天信息",

                "createTime":"2021-01-31T08:06:21.000+00:00",

                "updateTime":"2021-01-31T08:06:21.000+00:00",

                "isAdmin":"0",

                "sex":"1",

                "postId":null,

                "postName":null,

                "permissionList":null,

                "accountNonExpired":true,

                "accountNonLocked":true,

                "credentialsNonExpired":true,

                "enabled":true

            },

            {

                "id":71,

                "username":"zwj",

                "loginName":"张无忌33",

                "password":"1234",

                "authorities":null,

                "nickName":"黑白双侠33",

                "mobile":"18787171933",

                "email":"3501754007@qq.com",

                "deptId":1,

                "deptName":"云南南天信息",

                "createTime":"2021-01-31T08:10:14.000+00:00",

                "updateTime":"2021-01-31T08:10:14.000+00:00",

                "isAdmin":"0",

                "sex":"0",

                "postId":null,

                "postName":null,

                "permissionList":null,

                "accountNonExpired":true,

                "accountNonLocked":true,

                "credentialsNonExpired":true,

                "enabled":true

            },

            {

                "id":76,

                "username":"lcy",

                "loginName":"lcy",

                "password":"$2a$10$wW1o9nFm9nqdXoLZPoJOUOTRfGgESANiMf2kuD1n/yuLncbc7n1SO",

                "authorities":null,

                "nickName":"",

                "mobile":"18314358245",

                "email":"",

                "deptId":1,

                "deptName":"高原西北风科技有限公司",

                "createTime":"2021-04-09T00:34:53.000+00:00",

                "updateTime":"2021-04-09T00:34:53.000+00:00",

                "isAdmin":"0",

                "sex":"1",

                "postId":null,

                "postName":null,

                "permissionList":null,

                "accountNonExpired":true,

                "accountNonLocked":true,

                "credentialsNonExpired":true,

                "enabled":true

            }

        ],

        "total":4,

        "size":10,

        "current":1,

        "orders":[

        ],

        "optimizeCountSql":true,

        "hitCount":false,

        "countId":null,

        "maxLimit":null,

        "searchCount":true,

        "pages":1

    }

})

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值