拉钩教育管理系统项目实战(三)- 权限管理、资源管理

437 阅读4分钟

笔记来源:拉勾教育 - 大前端就业集训营

文章内容:学习过程中的笔记、感悟、和经验

权限管理

限制不同用户登录系统后可以看到并使用的功能,因为角色功能依赖菜单列表和资源列表,所以我们需要先制作资源和菜单列表两个组件

菜单列表

整体布局

  • 使用element-ui的卡片组件作为大结构
  • 创建一个新的路由页面(路由创建就不在这展示了),用来添加菜单
// src - views - menu - addMenu.vue文件,现在知只是写了结构,还没有对齐数据

<template>
  <el-card class="box-card">
    <div slot="header" class="clearfix">
      <span>添加菜单</span>
    </div>
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="菜单名称">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="菜单路径">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="上级菜单">
        <el-select v-model="form.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="描述">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="前端图标">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="form.resource">
          <el-radio label="是">是</el-radio>
          <el-radio label="否">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="num" @change="handleChange"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
        <el-button>重置</el-button>
      </el-form-item>
    </el-form>
</el-card>

</template>

<script>
export default {
  name: 'addMenu',
  data () {
    return {
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      }
    }
  },
  methods: {
    onSubmit () {
      console.log('submit!')
    }
  }
}
</script>

<style>

</style>

// 添加路由
{
    path: '/addMenu',
    name: 'addMenu',
    component: () => import(/* webpackChunkName:'addMenu' */ '@/views/menu/addMenu')
  }

添加菜单布局与数据绑定

使用element中的from表单,使用后台接口,使用piostman调试

本项目后台接口操作成功后都会返回一个code=000000,可以使用这个参数进行判断是否成功

// src - views - menu - addMenu.vue文件,还没有修改上级菜单,其他数据已经对齐

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 组件标题 -->
    <div slot="header" class="clearfix">
      <span>添加菜单</span>
    </div>
    <!-- 表单,绑定form数据 -->
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="菜单名称">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="菜单路径">
        <el-input v-model="form.href"></el-input>
      </el-form-item>
      <el-form-item label="上级菜单">
        <el-select v-model="form.parentId" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="描述">
        <el-input v-model="form.description"></el-input>
      </el-form-item>
      <el-form-item label="前端图标">
        <el-input v-model="form.icon"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="form.shown">
          <el-radio :label="true">是</el-radio>
          <el-radio :label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="form.orderNum" @change="handleChange"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
        <el-button>重置</el-button>
      </el-form-item>
    </el-form>
</el-card>

</template>

<script>
export default {
  name: 'addMenu',
  // 数据
  data () {
    return {
      // 表单数据
      form: {
        name: '',
        href: '',
        parentId: '',
        description: '',
        icon: '',
        shown: '',
        orderNum: ''
      }
    }
  },
  methods: {
    // 点击提交方法
    onSubmit () {
      console.log('submit!')
    },
    // 计数器方法
    handleChange (value) {
      console.log(value)
    }
  }
}
</script>

<style>

</style>

上级菜单处理

  • 使用获取编辑菜单页面信息接口,传入参数-1即可,返回的数据虽然找不到-1,但还是会返回所有一级菜单
  • 重新创建一个专门用于菜单处理的js文件,可以使用模版字符串或者params的方式传递参数
  • 在组件中获取全部顶层菜单,并把所有顶层菜单绑定到上级菜单组件
// src - services - menu.js文件

// 引入接口模块
import request from '@/utils/request'

// 获取编辑菜单信息接口
export const getEditMenuInfo = (id = -1) => {
  return request({
    method: 'get',
    url: '/boss/menu/getEditMenuInfo',
    // 这里使用params传值,也可以直接在url后面传值
    params: {
      id
    }
  })
}
// src - views - menu - addMenu.vue,已经将全部表单数据绑定完毕

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 组件标题 -->
    <div slot="header" class="clearfix">
      <span>添加菜单</span>
    </div>
    <!-- 表单,绑定form数据 -->
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="菜单名称">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="菜单路径">
        <el-input v-model="form.href"></el-input>
      </el-form-item>
      <!-- 修改上级菜单 -->
      <el-form-item label="上级菜单">
        <!-- 下拉菜单 -->
        <el-select v-model="form.parentId" placeholder="请选择上级菜单">
          <!-- 用于添加顶层菜单 -->
          <el-option label="无上级菜单" :value="-1"></el-option>
          <!-- 遍历所有顶层菜单,绑定名称和id -->
          <el-option v-for="item in parentMenuList" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="描述">
        <el-input v-model="form.description"></el-input>
      </el-form-item>
      <el-form-item label="前端图标">
        <el-input v-model="form.icon"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="form.shown">
          <el-radio :label="true">是</el-radio>
          <el-radio :label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="form.orderNum"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
        <el-button>重置</el-button>
      </el-form-item>
    </el-form>
</el-card>

</template>

<script>
// 引入请求接口方法
import { getEditMenuInfo } from '@/services/menu'
export default {
  name: 'addMenu',
  // 数据
  data () {
    return {
      // 表单数据
      form: {
        name: '',
        href: '',
        parentId: '',
        description: '',
        icon: '',
        shown: '',
        orderNum: ''
      },
      // 全部顶层菜单
      parentMenuList: []
    }
  },
  // 生命周期钩子函数
  created () {
    // 调用函数获取菜单数据
    this.getInfo()
  },
  methods: {
    // 点击提交方法
    onSubmit () {
      console.log('submit!')
    },
    // 用于获取全部顶层菜单
    async getInfo () {
      // 调用接口方法获取数据
      const { data } = await getEditMenuInfo()
      // 判断请求结果是否正确
      if (data.code === '000000') {
        // 将获取到的全部顶层菜单赋值data
        this.parentMenuList = data.data.parentMenuList
      }
    }
  }
}
</script>

添加菜单提交

  • 在菜单管理中添加按钮可以跳转添加菜单路由
  • 点击提交按钮提交的时候进行表单校验是否为空,提交给服务端接口,数据直接使用form
// src - services - menu.js文件

// 引入接口模块
import request from '@/utils/request'

// 获取编辑菜单信息接口
export const getEditMenuInfo = (id = -1) => {
  return request({
    method: 'get',
    url: '/boss/menu/getEditMenuInfo',
    // 这里使用params传值,也可以直接在url后面传值
    params: {
      id
    }
  })
}

// 保存、新增菜单
export const saveOrUpdate = (data) => {
  return request({
    method: 'post',
    url: '/boss/menu/saveOrUpdate',
    data
  })
}

// src - views - menu - index.vue,已经将全部表单数据绑定完毕

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 卡片顶部 -->
    <div slot="header" class="clearfix">
      <!-- 添加点击事件 -->
      <el-button @click="addMenu">添加菜单</el-button>
    </div>
  </el-card>
</template>

<script>
export default {
  name: 'mymenu',
  methods: {
    // 用于跳转到菜单添加路由
    addMenu () {
      this.$router.push({
        name: 'addMenu'
      })
    }
  }
}
</script>

// src - services - addMenu.js文件

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 组件标题 -->
    <div slot="header" class="clearfix">
      <span>添加菜单</span>
    </div>
    <!-- 表单,绑定form数据 -->
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="菜单名称">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="菜单路径">
        <el-input v-model="form.href"></el-input>
      </el-form-item>
      <!-- 修改上级菜单 -->
      <el-form-item label="上级菜单">
        <!-- 下拉菜单 -->
        <el-select v-model="form.parentId" placeholder="请选择上级菜单">
          <!-- 用于添加顶层菜单 -->
          <el-option label="无上级菜单" :value="-1"></el-option>
          <!-- 遍历所有顶层菜单,绑定名称和id -->
          <el-option v-for="item in parentMenuList" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="描述">
        <el-input v-model="form.description"></el-input>
      </el-form-item>
      <el-form-item label="前端图标">
        <el-input v-model="form.icon"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="form.shown">
          <el-radio :label="true">是</el-radio>
          <el-radio :label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="form.orderNum"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
        <el-button>重置</el-button>
      </el-form-item>
    </el-form>
</el-card>

</template>

<script>
// 引入请求接口方法
import { getEditMenuInfo, saveOrUpdate } from '@/services/menu'
export default {
  name: 'addMenu',
  // 数据
  data () {
    return {
      // 表单数据
      form: {
        name: '',
        href: '',
        parentId: '',
        description: '',
        icon: '',
        shown: '',
        orderNum: ''
      },
      // 全部顶层菜单
      parentMenuList: []
    }
  },
  // 生命周期钩子函数
  created () {
    // 调用函数获取菜单数据
    this.getInfo()
  },
  methods: {
    // 点击提交后用于新增菜单
    async onSubmit () {
      // 获取数据
      const form = this.form
      // 校验数据,根据校验数据结果执行操作
      if (form.name !== '' && form.href !== '' && form.parentId !== '') {
        //  - 校验通过调用接口添加菜单
        const { data } = await saveOrUpdate(this.form)
        //  - - 判断是否添加成功,添加成功弹出提示并跳回菜单管管理
        if (data.code === '000000') {
          this.$message.success('菜单添加成功')
          this.$router.push('/menu')
        } else {
          // - - 添加失败弹出提示
          this.$message.error('添加失败')
        }
      } else {
        // - 校验失败弹出提示
        this.$message.error('您填写的信息有误,请重新输入')
      }
    },
    // 用于获取全部顶层菜单
    async getInfo () {
      // 调用接口方法获取数据
      const { data } = await getEditMenuInfo()
      // 判断请求结果是否正确
      if (data.code === '000000') {
        // 将获取到的全部顶层菜单赋值data
        this.parentMenuList = data.data.parentMenuList
      }
    }
  }
}
</script>

菜单列表展示

  • menu.js中创建获取全部菜单接口方法
  • 使用element表格组件
  • menu组件引入接口并使用获取所有菜单数据使用
  • 使用自定义列模版进行操作列的设置
// src - services - menu.js文件

// 获取所有菜单
export const getAll = () => {
  return request({
    method: 'get',
    url: '/boss/menu/getAll'
  })
}
// src - services - menu.js文件

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 卡片顶部 -->
    <div slot="header" class="clearfix">
      <!-- 添加点击事件 -->
      <el-button @click="addMenu">添加菜单</el-button>
    </div>
    <!-- 表格组件,绑定数据 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        prop="date"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="菜单名称">
      </el-table-column>
      <el-table-column
        prop="level"
        label="菜单级数">
      </el-table-column>
      <el-table-column
        prop="icon"
        label="前端图标">
      </el-table-column>
      <el-table-column
        prop="orderNum"
        label="排序">
      </el-table-column>
      <el-table-column
        prop="date"
        label="操作"
        width="180">
        <!-- 使用自定义列模版设置两个操作按钮,内部可以使用scope访问到相关数据 -->
        <template slot-scope="scope">
          <el-button
            size="mini"
            @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script>
// 引入接口文件
import { getAll } from '@/services/menu'
export default {
  name: 'mymenu',
  data () {
    return {
      // 列表数据
      tableData: []
    }
  },
  // 钩子函数
  created () {
    // 在实例创建完后获取全部菜单数据
    this.getAllMenu()
  },
  methods: {
    // 用于跳转到菜单添加路由
    addMenu () {
      this.$router.push({
        name: 'addMenu'
      })
    },
    // 用于获取全部菜单数据
    async getAllMenu () {
      // 获取数据
      const { data } = await getAll()
      // 判断是否获取成功
      if (data.code === '000000') {
        // - 将获取的数据传递给列表
        this.tableData = data.data
      } else {
        // - 数据获取失败主动弹出提示
        this.$message.error('菜单数据获取失败')
      }
    },
    // 编辑按钮点击事件函数
    handleEdit () {
      console.log('编辑')
    },
    // 删除按钮点击事件函数
    handleDelete () {
      console.log('删除')
    }
  }
}
</script>

菜单删除

  • menu.js中创建删除菜单接口方法
  • menu组件引入方法并在点击删除后触发方法(注意最好在删除之前进行二次确认)删除菜单
  • 注意async和await
  • 删除后要提示并且重新更新组件数据
// src - services - menu.js文件

........
// 删除菜单
export const deleteMenu = (id) => {
  return request({
    method: 'delete',
    url: `/boss/menu/${id}`
  })
}
// src - services - menu.js文件

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 卡片顶部 -->
    <div slot="header" class="clearfix">
      <!-- 添加点击事件 -->
      <el-button @click="addMenu">添加菜单</el-button>
    </div>
    <!-- 表格组件,绑定数据 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        prop="date"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="菜单名称">
      </el-table-column>
      <el-table-column
        prop="level"
        label="菜单级数">
      </el-table-column>
      <el-table-column
        prop="icon"
        label="前端图标">
      </el-table-column>
      <el-table-column
        prop="orderNum"
        label="排序">
      </el-table-column>
      <el-table-column
        prop="date"
        label="操作"
        width="180">
        <!-- 使用自定义列模版设置两个操作按钮,内部可以使用scope访问到相关数据 -->
        <template slot-scope="scope">
          <!-- 使用scope.row.id获取这一行的id数据 -->
          <el-button
            size="mini"
            @click="handleEdit(scope.$index, scope.row.id)">编辑</el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script>
// 引入接口文件
import { getAll, deleteMenu } from '@/services/menu'
export default {
  name: 'mymenu',
  data () {
    return {
      // 列表数据
      tableData: []
    }
  },
  // 钩子函数
  created () {
    // 在实例创建完后获取全部菜单数据
    this.getAllMenu()
  },
  methods: {
    // 用于跳转到菜单添加路由
    addMenu () {
      this.$router.push({
        name: 'addMenu'
      })
    },
    // 用于获取全部菜单数据
    async getAllMenu () {
      // 获取数据
      const { data } = await getAll()
      // 判断是否获取成功
      if (data.code === '000000') {
        // - 将获取的数据传递给列表
        this.tableData = data.data
      } else {
        // - 数据获取失败主动弹出提示
        this.$message.error('菜单数据获取失败')
      }
    },
    // 编辑按钮点击事件函数
    handleEdit () {
      console.log('编辑')
    },
    // 删除按钮点击事件函数
    handleDelete (id) {
      // 设置弹框,用于二次确认
      this.$confirm('此操作将永久删除该条菜单数据, 是否继续?', '删除菜单', {
        // 使用async
      }).then(async () => {
        // 调用接口删除菜单
        const { data } = await deleteMenu(id)
        // 判断是否删除成功
        if (data.code === '000000') {
          // - 删除成功更新数据
          this.getAllMenu()
          // - 弹出提示
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
        } else {
          // 删除失败弹出提示
          this.$message({
            type: 'info',
            message: '删除失败'
          })
        }
      }).catch(() => {
        // 取消删除弹出提示
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    }
  }
}
</script>

编辑菜单布局处理

新建编辑路由组件,使用动态路由

由于添加和编辑内容相似,可以把两个组件相同部分进行封装

这里要使用父子组件传值,实现添加和编辑组件标题的动态变化以及重置按钮的显示和隐藏

index。vue组件点击编辑实现带着id跳转,并且在编辑组件上可以访问到id

// src - views - menu - index.vue文件

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 卡片顶部 -->
    <div slot="header" class="clearfix">
      <!-- 添加点击事件 -->
      <el-button @click="addMenu">添加菜单</el-button>
    </div>
    <!-- 表格组件,绑定数据 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        prop="date"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="菜单名称">
      </el-table-column>
      <el-table-column
        prop="level"
        label="菜单级数">
      </el-table-column>
      <el-table-column
        prop="icon"
        label="前端图标">
      </el-table-column>
      <el-table-column
        prop="orderNum"
        label="排序">
      </el-table-column>
      <el-table-column
        prop="date"
        label="操作"
        width="180">
        <!-- 使用自定义列模版设置两个操作按钮,内部可以使用scope访问到相关数据 -->
        <template slot-scope="scope">
          <!-- 使用scope.row.id获取这一行的id数据 -->
          <el-button
            size="mini"
            @click="handleEdit(scope.row.id)">编辑</el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script>
// 引入接口文件
import { getAll, deleteMenu } from '@/services/menu'
export default {
  name: 'mymenu',
  data () {
    return {
      // 列表数据
      tableData: []
    }
  },
  // 钩子函数
  created () {
    // 在实例创建完后获取全部菜单数据
    this.getAllMenu()
  },
  methods: {
    // 用于跳转到菜单添加路由
    addMenu () {
      this.$router.push({
        name: 'addMenu'
      })
    },
    // 用于获取全部菜单数据
    async getAllMenu () {
      // 获取数据
      const { data } = await getAll()
      // 判断是否获取成功
      if (data.code === '000000') {
        // - 将获取的数据传递给列表
        this.tableData = data.data
      } else {
        // - 数据获取失败主动弹出提示
        this.$message.error('菜单数据获取失败')
      }
    },
    // 编辑按钮点击事件函数!!!!!!!!!!!!!!!!!!!!
    handleEdit (id) {
      // 跳转,并且带着id
      this.$router.push(`/editMenu/${id}`)
    },
    // 删除按钮点击事件函数
    handleDelete (id) {
      // 设置弹框,用于二次确认
      this.$confirm('此操作将永久删除该条菜单数据, 是否继续?', '删除菜单', {
        // 使用async
      }).then(async () => {
        // 调用接口删除菜单
        const { data } = await deleteMenu(id)
        // 判断是否删除成功
        if (data.code === '000000') {
          // - 删除成功更新数据
          this.getAllMenu()
          // - 弹出提示
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
        } else {
          // 删除失败弹出提示
          this.$message({
            type: 'info',
            message: '删除失败'
          })
        }
      }).catch(() => {
        // 取消删除弹出提示
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    }
  }
}
</script>

// src - views - menu - addMenu.vue文件

<template>
<!-- 使用子组件 -->
  <son-card title="添加菜单"></son-card>
</template>

<script>
// 引入子组件
import sonCard from './son/card'
export default {
  name: 'addMenu',
  // 注册子组件
  components: {
    sonCard
  }
}
</script>

// src - views - menu - editMenu.vue文件

<template>
<!-- 使用子组件,并向子组件传值 -->
  <son-card title="编辑菜单"></son-card>
</template>

<script>
// 引入子组件
import sonCard from './son/card'
export default {
  name: 'addMenu',
  // 在钩子函数中可以访问到路由中的id
  created () {
    console.log(this.$route.params)
  },
  // 注册子组件
  components: {
    sonCard
  }
}
</script>

// src - views - menu - son -  card.vue文件,这是添加和编辑菜单的子组件,封装为一个单独的组件

<template>
<!-- 组件容器 -->
  <el-card class="box-card">
    <!-- 组件标题 -->
    <div slot="header" class="clearfix">
      <span>{{title}}</span>
    </div>
    <!-- 表单,绑定form数据 -->
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="菜单名称">
        <el-input v-model="form.name" placeholder="必填"></el-input>
      </el-form-item>
      <el-form-item label="菜单路径">
        <el-input v-model="form.href" placeholder="必填"></el-input>
      </el-form-item>
      <!-- 修改上级菜单 -->
      <el-form-item label="上级菜单">
        <!-- 下拉菜单 -->
        <el-select v-model="form.parentId" placeholder="必选">
          <!-- 用于添加顶层菜单 -->
          <el-option label="无上级菜单" :value="-1"></el-option>
          <!-- 遍历所有顶层菜单,绑定名称和id -->
          <el-option v-for="item in parentMenuList" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="描述">
        <el-input v-model="form.description"></el-input>
      </el-form-item>
      <el-form-item label="前端图标">
        <el-input v-model="form.icon"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="form.shown">
          <el-radio :label="true">是</el-radio>
          <el-radio :label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="form.orderNum"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
        <el-button v-if="title === '添加菜单'">重置</el-button>
      </el-form-item>
    </el-form>
</el-card>

</template>

<script>
// 引入请求接口方法
import { getEditMenuInfo, saveOrUpdate } from '@/services/menu'
export default {
  name: 'addMenu',
  props: ['title'],
  // 数据
  data () {
    return {
      // 表单数据
      form: {
        name: '',
        href: '',
        parentId: '',
        description: '',
        icon: '',
        shown: '',
        orderNum: ''
      },
      // 全部顶层菜单
      parentMenuList: []
    }
  },
  // 生命周期钩子函数
  created () {
    // 调用函数获取菜单数据
    this.getInfo()
  },
  methods: {
    // 点击提交后用于新增菜单
    async onSubmit () {
      // 获取数据
      const form = this.form
      // 校验数据,根据校验数据结果执行操作
      if (form.name !== '' && form.href !== '' && form.parentId !== '') {
        //  - 校验通过调用接口添加菜单
        const { data } = await saveOrUpdate(this.form)
        //  - - 判断是否添加成功,添加成功弹出提示并跳回菜单管管理
        if (data.code === '000000') {
          this.$message.success('菜单添加成功')
          this.$router.push('/menu')
        } else {
          // - - 添加失败弹出提示
          this.$message.error('添加失败')
        }
      } else {
        // - 校验失败弹出提示
        this.$message.error('您填写的信息有误,请重新输入')
      }
    },
    // 用于获取全部顶层菜单
    async getInfo () {
      // 调用接口方法获取数据
      const { data } = await getEditMenuInfo()
      // 判断请求结果是否正确
      if (data.code === '000000') {
        // 将获取到的全部顶层菜单赋值data
        this.parentMenuList = data.data.parentMenuList
      }
    }
  }
}
</script>
// 路由index文件添加一个新路由

{
    // 编辑菜单 - 动态路由
    path: '/editMenu/:id',
    name: 'editMenu',
    component: () => import(/* webpackChunkName:'editMenu' */ '@/views/menu/editMenu')
  }

编辑菜单功能实现

  • 添加编辑可以使用同一个接口,只是相差一个参数而已
  • 跳转的时候使用params传递动态id值
  • 跳转后获取id,并判断是否能获取到编辑菜单数据,有的话把值设置给from
// src - views - menu - son -  card.vue文件,直接修改获取数据的方法

// 用于获取全部顶层菜单并获取编辑菜单信息
async getInfo () {
  // 调用接口获取数据,并尝试获取id值
  const { data } = await getEditMenuInfo(this.$route.params.id)
  // 判断请求结果是否正确
  if (data.code === '000000') {
    // 将获取到的全部顶层菜单赋值data
    this.parentMenuList = data.data.parentMenuList
    // 判断是否获取的了当前编辑菜单的数据
    if (data.data.menuInfo !== null) {
      // 获得菜单数据将数据设置给form
      this.form = data.data.menuInfo
    }
  }
}

资源列表

数据展示、新增、编辑的操作和之前菜单管理一样

资源列表整体布局

  • 新建一个子组件。把所有功能写在子组件内部
  • 整体一个card,分上下两个区域,顶部是一个表单,底部是一个列表
// src - views - resurces - index.vue文件,目前只有整体布局,还没有进行数据对齐

<template>
<!-- 子组件 -->
  <son-card></son-card>
</template>

<script>
// 引入子组件
import sonCard from './son/card'
export default {
  name: 'resources',
  // 注册组件
  components: {
    sonCard
  }
}
</script>

// src - views - resurces - son - card.vue文件

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="资源名称">
          <el-input v-model="formInline.user" placeholder="资源名称"></el-input>
        </el-form-item>
        <el-form-item label="资源分类">
          <el-select v-model="formInline.region" placeholder="资源分类">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script>
export default {
  data () {
    return {
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: []
    }
  },
  methods: {
    // 查询按钮点击事件函数
    onSubmit () {
      console.log('submit!')
    }
  }
}
</script>

资源列表展示

  • 使用按条件分页查询资源接口
  • 新建js文件书写资源相关接口功能
  • 使用vue过滤器处理日期,使用插槽,使用Date处理时间
// 新建 src/services/resources.js 文件,封装资源管理相关功能

// 引入接口模块
import request from '@/utils/request'

// 按条件分页查询资源
export const getResourcePages = data => {
  return request({
    method: 'post',
    url: '/boss/resource/getResourcePages',
    data
  })
}

// src/views/resources/son/card.vue文件,这里书写资源列表展示功能,顶部表单还没写

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="资源名称">
          <el-input v-model="formInline.user" placeholder="资源名称"></el-input>
        </el-form-item>
        <el-form-item label="资源分类">
          <el-select v-model="formInline.region" placeholder="资源分类">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script>
import { getResourcePages } from '@/services/resources'
export default {
  data () {
    return {
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: []
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
  },
  methods: {
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      console.log('submit!')
    },
    // 获取数据
    async loadResourcePages (obj) {
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

资源分页功能布局

  • 使用element的分页组件
  • 把页数同时应用到筛选和全部资源列表
// src/views/resources/son/card.vue

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="资源名称">
          <el-input v-model="formInline.user" placeholder="资源名称"></el-input>
        </el-form-item>
        <el-form-item label="资源分类">
          <el-select v-model="formInline.region" placeholder="资源分类">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件,绑定数据 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="condition.current"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="condition.size"
      layout="total, sizes, prev, pager, next"
      :total="100">
    </el-pagination>
  </el-card>
</template>

<script>
import { getResourcePages } from '@/services/resources'
export default {
  data () {
    return {
      // 筛选条件
      condition: {
        // 这个页数在筛选的时候也会用到
        current: 1,
        size: 10
      },
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: []
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
  },
  methods: {
    // 每页数据量发生变化事件函数
    handleSizeChange (val) {
      // value传递给data
      this.condition.size = val
    },
    // 页数发生变化函数
    handleCurrentChange (val) {
      // value传递给data
      this.condition.current = val
    },
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      console.log('submit!')
    },
    // 获取数据
    async loadResourcePages (obj) {
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

资源分页实现

暂时只声明页数和每页条数、

src/views/resources/son/card.vue

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <el-form :inline="true" :model="formInline" class="demo-form-inline">
        <el-form-item label="资源名称">
          <el-input v-model="formInline.user" placeholder="资源名称"></el-input>
        </el-form-item>
        <el-form-item label="资源分类">
          <el-select v-model="formInline.region" placeholder="资源分类">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件,绑定数据 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="condition.current"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="condition.size"
      layout="total, sizes, prev, pager, next"
      :total="total">
    </el-pagination>
  </el-card>
</template>

<script>
import { getResourcePages } from '@/services/resources'
export default {
  data () {
    return {
      // 筛选条件,设置默认值
      condition: {
        // 这个页数在筛选的时候也会用到
        current: 1,
        size: 10
      },
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: [],
      // 数据总条数
      total: 0
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
  },
  methods: {
    // 每页数据量发生变化事件函数
    handleSizeChange (val) {
      // value传递给data
      this.condition.size = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 页数发生变化函数
    handleCurrentChange (val) {
      // value传递给data
      this.condition.current = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      console.log('submit!')
    },
    // 获取数据
    async loadResourcePages (obj) {
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
        // 把数据量传递给data
        this.total = data.data.total
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

资源筛选

  • 使用条件分页查询资源接口进行分页资源获取
  • 使用资源分类获取全部资源的分类列表
  • 在顶部form表单 绑定需要使用的数据
  • 注意搜索资源页数应该复位
src/views/resources/son/card.vue

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <el-form :inline="true" :model="condition" class="demo-form-inline">
        <el-form-item label="资源名称">
          <!-- 双向绑定数据 -->
          <el-input v-model="condition.name" placeholder="资源名称"></el-input>
        </el-form-item>
        <el-form-item label="资源路径">
          <!-- 双向绑定数据 -->
          <el-input v-model="condition.url" placeholder="资源路径"></el-input>
        </el-form-item>
        <el-form-item label="资源分类">
          <!-- 双向绑定数据 -->
          <el-select v-model="condition.categoryId" placeholder="资源分类">
            <!-- 使用v-for遍历全部资源分类,形成下拉菜单 -->
            <el-option v-for="item in categoryIds" :key="item.id" :label="item.name" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件,绑定数据 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="condition.current"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="condition.size"
      layout="total, sizes, prev, pager, next"
      :total="total">
    </el-pagination>
  </el-card>
</template>

<script>
import { getResourcePages, getAll } from '@/services/resources'
export default {
  data () {
    return {
      // 筛选条件,设置默认值
      condition: {
        // 这个页数在筛选的时候也会用到
        current: 1,
        size: 10
      },
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: [],
      // 数据总条数
      total: 0,
      // 全部资源分类数据
      categoryIds: []
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
    // 调用函数获取全部资源分类
    this.getAllList()
  },
  methods: {
    // 获取全部资源分类
    async getAllList () {
      // 获取数据
      const { data } = await getAll()
      // 判断数据是否正常
      if (data.code === '000000') {
        // 数据正常,将全部资源分类数据传入data
        this.categoryIds = data.data
      }
    },
    // 每页数据量发生变化事件函数
    handleSizeChange (val) {
      // value传递给data
      this.condition.size = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 页数发生变化函数
    handleCurrentChange (val) {
      // value传递给data
      this.condition.current = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      // 复原页码为 1
      this.condition.current = 1
      // 调用获取数据
      this.loadResourcePages(this.condition)
    },
    // 获取数据
    async loadResourcePages (obj) {
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
        // 把数据量传递给data
        this.total = data.data.total
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

清除资源筛选数据

  • 使用element选择器组件实现单个组件可清空,方法同样适用于输入框

  • 点击重置删除全部顶部form数据,表单组件提供快速清空功能,注意需要使用prop绑定数据

// src/views/resources/son/card.vue

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <!-- 设置表单重置功能,注意:设置的ref要和form绑定的数据名一致 -->
      <el-form :inline="true" :model="condition" class="demo-form-inline" ref="condition">
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源名称" prop="name">
          <!-- 双向绑定数据,添加clearable属性表示可以快速清空 -->
          <el-input v-model="condition.name" placeholder="资源名称" clearable></el-input>
        </el-form-item>
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源路径" prop="url">
          <!-- 双向绑定数据 -->
          <el-input v-model="condition.url" placeholder="资源路径" clearable></el-input>
        </el-form-item>
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源分类" prop="categoryId">
          <!-- 双向绑定数据 -->
          <el-select v-model="condition.categoryId" placeholder="资源分类" clearable>
            <!-- 使用v-for遍历全部资源分类,形成下拉菜单 -->
            <el-option v-for="item in categoryIds" :key="item.id" :label="item.name" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
          <el-button @click="onReset">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件,绑定数据 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="condition.current"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="condition.size"
      layout="total, sizes, prev, pager, next"
      :total="total">
    </el-pagination>
  </el-card>
</template>

<script>
import { getResourcePages, getAll } from '@/services/resources'
export default {
  data () {
    return {
      // 筛选条件,设置默认值
      condition: {
        // 这个页数在筛选的时候也会用到
        current: 1,
        size: 10
      },
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: [],
      // 数据总条数
      total: 0,
      // 全部资源分类数据
      categoryIds: []
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
    // 调用函数获取全部资源分类
    this.getAllList()
  },
  methods: {
    // 重置按钮点击事件函数
    onReset () {
      // 重置表单
      this.$refs.condition.resetFields()
    },
    // 获取全部资源分类
    async getAllList () {
      // 获取数据
      const { data } = await getAll()
      // 判断数据是否正常
      if (data.code === '000000') {
        // 数据正常,将全部资源分类数据传入data
        this.categoryIds = data.data
      }
    },
    // 每页数据量发生变化事件函数
    handleSizeChange (val) {
      // value传递给data
      this.condition.size = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 页数发生变化函数
    handleCurrentChange (val) {
      // value传递给data
      this.condition.current = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      // 复原页码为 1
      this.condition.current = 1
      // 调用获取数据
      this.loadResourcePages(this.condition)
    },
    // 获取数据
    async loadResourcePages (obj) {
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
        // 把数据量传递给data
        this.total = data.data.total
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

数据加载细节处理

  • 如果网络比较慢,会导致加载缓慢
    • 设置加载中仅用状态效果
    • 使用element的loader组件
    • 加载中禁用查询按钮和分页选项
// src/views/resources/son/card.vue

<template>
<!-- 卡片容器 -->
  <el-card class="box-card">
    <!-- 顶部表单 -->
    <div slot="header" class="clearfix">
      <!-- 设置表单重置功能,注意:设置的ref要和form绑定的数据名一致 -->
      <el-form :inline="true" :model="condition" class="demo-form-inline" ref="condition">
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源名称" prop="name">
          <!-- 双向绑定数据,添加clearable属性表示可以快速清空 -->
          <el-input v-model="condition.name" placeholder="资源名称" clearable></el-input>
        </el-form-item>
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源路径" prop="url">
          <!-- 双向绑定数据 -->
          <el-input v-model="condition.url" placeholder="资源路径" clearable></el-input>
        </el-form-item>
        <!-- el-form-item设置prop绑定相应的参数名才能实现重置效果 -->
        <el-form-item label="资源分类" prop="categoryId">
          <!-- 双向绑定数据 -->
          <el-select v-model="condition.categoryId" placeholder="资源分类" clearable>
            <!-- 使用v-for遍历全部资源分类,形成下拉菜单 -->
            <el-option v-for="item in categoryIds" :key="item.id" :label="item.name" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
          <el-button @click="onReset"  :disabled="loading">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 列表,设置数据对齐 -->
    <el-table
      :data="tableData"
      style="width: 100%"
      v-loading="loading">
      <el-table-column
        type="index"
        label="编号">
      </el-table-column>
      <el-table-column
        prop="name"
        label="资源名称">
      </el-table-column>
      <el-table-column
        prop="url"
        label="资源路径">
      </el-table-column>
      <el-table-column
        prop="description"
        label="描述">
      </el-table-column>
      <el-table-column
        label="添加时间">
        <!-- 添加时间插槽,使用过滤器处理时间 -->
        <template slot-scope="scope">
          <span>{{scope.row.updatedTime | time}}</span>
        </template>
      </el-table-column>
      <!-- 操作列,使用插槽创建两个按钮 -->
      <el-table-column
        label="操作">
        <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件,绑定数据 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="condition.current"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="condition.size"
      layout="total, sizes, prev, pager, next"
      :total="total"
      :disabled="loading">
    </el-pagination>
  </el-card>
</template>

<script>
import { getResourcePages, getAll } from '@/services/resources'
export default {
  data () {
    return {
      // 筛选条件,设置默认值
      condition: {
        // 这个页数在筛选的时候也会用到
        current: 1,
        size: 10
      },
      // 表单数据
      formInline: {
      },
      // 列表数据
      tableData: [],
      // 数据总条数
      total: 0,
      // 全部资源分类数据
      categoryIds: [],
      // 信号量:表示是否表格组件正在加载,上面的组件可以设置v-loading或者disabled绑定这个数据实现是否禁用和显示加载
      loading: false
    }
  },
  // 钩子函数
  created () {
    // 获取数据
    this.loadResourcePages({})
    // 调用函数获取全部资源分类
    this.getAllList()
  },
  methods: {
    // 重置按钮点击事件函数
    onReset () {
      // 重置表单
      this.$refs.condition.resetFields()
    },
    // 获取全部资源分类
    async getAllList () {
      // 获取数据
      const { data } = await getAll()
      // 判断数据是否正常
      if (data.code === '000000') {
        // 数据正常,将全部资源分类数据传入data
        this.categoryIds = data.data
      }
    },
    // 每页数据量发生变化事件函数
    handleSizeChange (val) {
      // value传递给data
      this.condition.size = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 页数发生变化函数
    handleCurrentChange (val) {
      // value传递给data
      this.condition.current = val
      // 调用函数获取数据,直接传参condition
      this.loadResourcePages(this.condition)
    },
    // 编辑按钮点击事件
    handleEdit () {
    },
    // 删除按钮点击事件
    handleDelete () {
    },
    // 查询按钮点击事件函数
    onSubmit () {
      // 复原页码为 1
      this.condition.current = 1
      // 调用获取数据
      this.loadResourcePages(this.condition)
    },
    // 获取数据
    async loadResourcePages (obj) {
      // 将信号量设置为true - 加载中
      this.loading = true
      const { data } = await getResourcePages(obj)
      // 判断数据是否正常获取
      if (data.code === '000000') {
        // 将获取的数据传给表格
        this.tableData = data.data.records
        // 把数据量传递给data
        this.total = data.data.total
        // 设置信号量为false - 非加载中
        this.loading = false
      }
    }
  },
  // 过滤器
  filters: {
    // 时间过滤器
    time (data) {
      // 将时间使用Date处理
      data = new Date(data)
      // 返回处理后的数据
      return `
        ${data.getFullYear()}/${data.getMonth()}/${data.getDay()}
        ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
    }
  }
}
</script>

添加编辑删除功能

以后再写