电商后台管理系统-3.用户管理模块

189 阅读5分钟

一、用户列表

1.首先创建并引入Users.vue组件,然后作为Home组件的子组件

用户列表组件创建.gif

2.用户列表在sessionStorage中保存左侧菜单的激活状态(default.active)

image.png

(1)激活状态实现之前

侧边栏激活状态实现之前.gif

(2)通过el-menu标签中添加:default-active="activePath"则可以实现,实现过程如图所示:

侧边栏激活状态实现代码.gif

(3)激活状态实现之后

侧边栏激活状态实现之后.gif

3.绘制用户列表组件的基本布局结构(el-breadcrumb、el-card、el-row)

el-breadcrumb separator-class="el-icon-arrow-right">
  <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
  <el-breadcrumb-item>用户管理</el-breadcrumb-item>
  <el-breadcrumb-item>用户列表</el-breadcrumb-item>
  
</el-breadcrumb>
<!-- 卡片视图区域 -->
<el-card class="box-card">
  <!-- 搜索与添加区域 -->
  
<el-row :gutter="20">
    <el-col :span="8">
        <el-input placeholder="请输入内容" class="input-with-select">
    <el-button slot="append" icon="el-icon-search"></el-button>
  </el-input>
    </el-col>
    <el-col :span="4">
        <el-button type="primary">添加用户</el-button>
    </el-col>

</el-row>
</el-card>

效果如图所示:

image.png

4.获取用户列表数据

api接口文档:

image.png

(1)通过axios获取用户数据

  data(){
        return {
            // 获取用户列表的参数对象
            queryInfo:{
            // 查询参数
            query:'',
            // 当前页码
            pagenum:1,
            // 每页显示条数
            pagesize:2,
            },
            userList:[],
            total:0

        }
    },
    methods:{
        async getUserList(){
           const {data:res}=await this.$http.get('users',{
                params:this.queryInfo
            })
            console.log(res);
            if(res.meta.status !== 200){
                return this.$message.error('获取用户列表失败')
            }
            this.userList =res.data.users
            this.total =res.data.total
        }
    },
    created(){
        this.getUserList()

    }

(2)通过这个可以发现与之前post请求有些不一样,多了一个params,之前login信息请求是这样的

data(){
        return {
            //这是登录表单的数据表单对象
            loginForm:{
                username:'',
                password:''
            },
            // 这是表单验证规则的对象
            loginFormRules:{
                // 验证用户名是否合法
                username:[
                    { required: true, message: '请输入用户名', trigger: 'blur' },
                    { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
                ],
                // 验证密码是否合法
                password:[
                    { required: true, message: '请输入用户名', trigger: 'blur' },
                    { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
                ]
            }
        }
    },
    methods:{
        resetLoginForm(){
            // console.log(this);
            // 这是在上面对组件实例进行了定义,名为loginFormRef,然后调用resetFields(),所以就实现了重置
            this.$refs.loginFormRef.resetFields();
        },
        login(){
            this.$refs.loginFormRef.validate(async(valid)=>{
                // console.log(valid);
               if(!valid) {
                   return;
                   }
               else{
                //login是请求路径,this.loginForm是请求对象
               const { data:res } = await this.$http.post('login',**this.loginForm**)
            //    console.log(res);
                if(res.meta.status !== 200) {
                   return this.$message.error('登录失败')
                   }else{
                       this.$message.success('登录成功');
                    //    将登录成功后的token,保存到客户端的sessionStorage中,因为需要登录成功后才能访问其它API
                       window.sessionStorage.setItem('token',res.data.token);
                    //    将导航栏路径改为/home
                       this.$router.push('/home')

                   }
               }
               
            });

5.使用el-table组件渲染基本的用户列表

<el-table
      :data="userList"
      style="width: 100%"
      border
      stripe>
      <el-table-column
        prop="username"
        label="姓名"
        >
      </el-table-column>
       <el-table-column
        prop="email"
        label="邮箱"
        >
        </el-table-column>
        <el-table-column
        prop="mobile"
        label="电话"
        >
      </el-table-column>
      <el-table-column
        prop="role_name"
        label="角色"
        >
        </el-table-column>
      <el-table-column
        prop="mg_state"
        label="状态"
        >
        </el-table-column>
        <el-table-column
        prop=""
        label="操作"
        >
        </el-table-column>
    </el-table>
     <el-table
      :data="userList"
      style="width: 100%"
      border
      stripe>
      <el-table-column
        prop="username"
        label="姓名"
        >
      </el-table-column>
       <el-table-column
        prop="email"
        label="邮箱"
        >
        </el-table-column>
        <el-table-column
        prop="mobile"
        label="电话"
        >
      </el-table-column>
      <el-table-column
        prop="role_name"
        label="角色"
        >
        </el-table-column>
      <el-table-column
        prop="mg_state"
        label="状态"
        >
        </el-table-column>
        <el-table-column
        prop=""
        label="操作"
        >
        </el-table-column>
    </el-table>
</el-card>
    </div>
</template>
<script>
export default {
    data(){
        return {
            // 获取用户列表的参数对象
            queryInfo:{
            // 查询参数
            query:'',
            // 当前页码
            pagenum:1,
            // 每页显示条数
            pagesize:2,
            },
            userList:[],
            total:0,
            

        }

效果图:

image.png

当el-table元素中注入data对象数组后,在el-table-column中用prop属性来对应对象中的键名即可填入数据,用label属性来定义表格的列名。可以使用width属性来定义列宽。

1.为表格添加索引列,这个跟简单,只需要加上以下代码就可以了

image.png 效果图:

image.png

6.自定义状态列的显示效果,利用插槽作用域

image.png 就可以实现状态栏的显示效果:

状态栏吗显示效果.gif

7.渲染操作列,也是利用作用域插槽

  <template slot-scope="scope">
            <!-- {{scope.row}} -->
 <!-- 修改按钮 -->
 <el-tooltip class="item" effect="dark" content="编辑" placement="top" :enterable="false">
       <el-button type="primary" icon="el-icon-edit" size="mini"></el-button>
    </el-tooltip>

 <!-- 删除按钮 -->
 <el-tooltip class="item" effect="dark" content="删除" placement="top" :enterable="false">
     <el-button type="danger" icon="el-icon-delete" size="mini"></el-button>
    </el-tooltip>
 
 <!-- 分配角色按钮 -->
 <el-tooltip class="item" effect="dark" content="分配角色" placement="top" :enterable="false">
       <el-button type="warning" icon="el-icon-setting" size="mini"></el-button>
    </el-tooltip>

        </template>

效果图:

image.png

8.实现分页效果(重点)

(1) 利用elment-ui的el-pagination来实现。

    <!-- 分页区域 -->
<el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page.sync="queryInfo.pagenum"
      :page-sizes="[2, 5, 10, 20]"
      :page-size="queryInfo.pagesize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total">
    </el-pagination>
</el-card>
    </div>
</template>
<script>
export default {
    data(){
        return {
            // 获取用户列表的参数对象
            queryInfo:{
            // 查询参数
            query:'',
            // 当前页码
            pagenum:1,
            // 当前每页显示条数
            pagesize:2,
            },
            userList:[],
            total:0,
        }
    },
    methods:{
        async getUserList(){
           const {data:res}=await this.$http.get('users',{
                params:this.queryInfo
            })
            // console.log(res);
            if(res.meta.status !== 200){
                return this.$message.error('获取用户列表失败')
            }
            this.userList =res.data.users
            this.total =res.data.total
            // console.log(this.userList);
        },
        // 监听pagesize改变的事件
    handleSizeChange(newSize){
        this.queryInfo.pagesize = newSize
        // 重新获取用户数据
        this.getUserList()
        console.log(newSize);

    },
    handleCurrentChange(newPage){
        console.log(newPage);
        this.queryInfo.pagenum =newPage
        // 重新获取用户数据
        this.getUserList()

    }

代码分析

此例是一个完整的用例,使用了size-changecurrent-change事件来处理页码大小和当前页变动时候触发的事件。page-sizes接受一个整型数组,数组元素为展示的选择每页显示个数的选项,[100, 200, 300, 400]表示四个选项,每页显示 2 个,5 个,10 个或者 20 个。size-change是当改变一页显示数目时触发会触发handleSizeChange方法,handleSizeChange会有一个参数,其值为当前页面显示数据最大数current-change是表示页码数,切换页码时会触发handleCurrentChange方法,也有一个参数,为页码值current-page.sync代表当前页码,page-sizes代表页面最多显示条数,page-size,当前页面显示条数。total代表数据总条数,实现效果如图所示:

分页的实现.gif

9.修改用户状态 put请求

image.png (1)开关变化监听事件

image.png (2)put请求更改状态,数据库里的状态同时更改

async userStateChange(userInfo){
        // console.log(userInfo);
        const {data:res} = await this.$http.put(`users/${userInfo.id}/state/${userInfo.mg_state}`)
        console.log(res);
        if(res.meta.status !== 200){
            userInfo.mg_state =!userInfo.mg_state
            return this.$message.error('更新状态失败')
        }else{
            this.$message.success('更新状态成功')

        }
    }

效果图:(如图不是修改了数据库数据的话,刷新后状态会恢复为原来的状态)

用户状态更改.gif

10.实现用户搜索功能(离谱,没懂其原理)

代码如下:

image.png

其中clearble是当搜索框有内容时,可以点击×清空内容,clear时间是当点击清空时触发的时间,这里是重新获取数据

注意: 这里没弄懂其搜索原理,很迷

11.添加用户功能

1.渲染添加用户对话框,利用的是el-dialog组件,

dialog代码如下:

    <!-- 添加用户对话框 -->
    <el-dialog
  title="提示"
  :visible.sync="addDialogVisible"
  width="50%">
  <!-- 内容主题区域 -->
  <span>这是一段信息</span>
  <!-- 对话框底部区域 -->
  <span slot="footer" class="dialog-footer">
    <el-button @click="addDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="addDialogVisible = false">确 定</el-button>
  </span>
</el-dialog>

其中visible.sync代表对话框的默认状态。其它就没什么好说的。需要的是点击了添加用户按钮时,把addDialogVisible改为true,如图所示:

添加用户对话框.gif

效果图:

添加用户对话框效果图.gif

2.添加用户表单的渲染

<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px" class="demo-ruleForm">
  <el-form-item label="用户名" prop="username">
    <el-input v-model="addForm.username"></el-input>
  </el-form-item>
  <el-form-item label="密码" prop="password">
    <el-input v-model="addForm.password"></el-input>
  </el-form-item>
  <el-form-item label="邮箱" prop="email">
    <el-input v-model="addForm.email"></el-input>
  </el-form-item>
   <el-form-item label="手机号" prop="mobile">
    <el-input v-model="addForm.mobile"></el-input>
  </el-form-item>
  </el-form>

添加表单数据和校验规则:

image.png 效果图:

image.png

自定义验证规则: 使用方法可见下面这个网址: element.eleme.cn/#/zh-CN/com…

image.png

实现添加表单的重置操作

没重置前(输入过后关闭对话框,数据不会清空):

添加用户表单重置前.gif

重置后(再次点击,数据清空):

添加用户表单重置后.gif

(1) 利用dialog的close监听事件,获取表单的ref(),调用resetFields()

addDialogClosed(){
        this.$refs.addFormRef.resetFields()

    }

image.png

3.添加表单的预校验

 addUser(){
        this.$refs.addFormRef.validate(valid =>{
            // 校验成功则为true,校验石失败则为false
            console.log(valid);
        })
    }

4.预校验通过,发起添加用户的网络请求(调用API完成用户添加)

添加用户API接口:

image.png

addUser(){
        this.$refs.addFormRef.validate(async valid =>{
            // 校验成功则为true,校验石失败则为false
            // console.log(valid);
            // 如果校验失败,则直接return,就不走添加的逻辑
            if(!valid){
                return
            }else{
                // 如果校验成功则执行添加逻辑,发起网络请求,完成添加用户
                const {data : res}=await this.$http.post('users',this.addForm)
                if(res.meta.status !== 201){
                    if(res.meta.status == 400){
                        this.$message.warning('用户已存在')
                        }else{
                            this.$message.error('添加用户失败')
                        }
                    
                } else{
                    this.$message.success('用户添加成功')
                    // 关闭添加用户对话框
                    this.addDialogVisible = false
                    // 刷新列表,调用获得用户列表即可
                    this.getUserList()
                }

            }

12.修改用户

1.展示用户对话框

这个与显示添加用户对话框一样

2.根据用户id查询用户信息

image.png

3.渲染修改用户的表单

与上面添加用户一样,修改部分数据就行

实现修改表单的重置操作

与上面添加用户一样,修改部分数据就行

修改用户数据

image.png

editUser(){
        // 对话框预校验
        this.$refs.editFormRef.validate( async valid => {
            // console.log(valid);
            // 预校验不通过
            if(!valid){
                return
            }else{
                const {data :res}=await this.$http.put(`users/${this.scope_id}`,
                {email:this.editForm.email,mobile:this.editForm.mobile})
                // console.log(res);
                if(res.meta.status !== 200){
                    return this.$message.error('修改用户信息失败')
                }else{
                    this.EditDialogVisible =false
                    this.getUserList();
                    this.$message.success('修改用户信息成功')
                }
            }
        })
    },

14.删除用户

1.弹窗询问用户是否进行删除,(element-ui的messageBox弹窗)

 async removeUserById(id){
        // console.log(id);
        // 先弹窗询问用户是否删除
         const confirmResult=await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)
        // 如果用户点击确认删除按钮,则返回值为字符串 confirm
        // 如果用户点击取消删除按钮,则返回值为字符串 cancel

        // console.log(typeof(confirmResult));
        if(confirmResult !=='confirm'){
            return this.$message.info('已经取消删除')
        }else{
            console.log(66);
        }
    }

注意:点击确认返回confirm,点击取消返回cancel

3.调用API实现删除用户

image.png

// 根据id删除对应的用户信息
    async removeUserById(id){
        // console.log(id);
        // 先弹窗询问用户是否删除
         const confirmResult=await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)
        // 如果用户点击确认删除按钮,则返回值为字符串 confirm
        // 如果用户点击取消删除按钮,则返回值为字符串 cancel

        // console.log(typeof(confirmResult));
        if(confirmResult !=='confirm'){
            return this.$message.info('已经取消删除')
        }else{
            const {data:res}=await this.$http.delete(`users/${id}`)
            if(res.meta.status !==200){
                return this.$message.error('删除用户失败')
            }else{
                this.$message.success('删除用户成功')
                this.getUserList()
            }
        }
    }