美文网首页
权限管理:资源管理

权限管理:资源管理

作者: amanohina | 来源:发表于2021-03-05 18:10 被阅读0次

    说明:

    • 资源管理讲解数据展示数据分页数据筛选。添加,编辑,删除,以及资源分类中的所有功能均与菜单管理功能类似,这里就不再多赘述了

    整体布局

    将资源列表设置为单独组件(独立于resource/index.vue)
    创建目录以及文件:
    resource/components/list.vue

    • 使用Card组件设置外部结构
    • 头部使用Form组件的行内表单形式与数据
    • 内容设置Table组件并且设置数据
    // resource/components/list.vue,暂且设置为这个样子
    <template>
      <div class="resource-list">
        <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>
          <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>
          </div>
        </el-card>
      </div>
    </template>
    
    <script>
    export default {
      name: 'ResourceList',
      data () {
        return {
          formInline: {},
          tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          },
          {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          },
          {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          },
          {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }]
        }
      },
      methods: {
        onSubmit () {
          console.log('submit!')
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    </style>
    
    

    在resource/index.vue导入

    <template>
      <div class="resource">
        <resource-list></resource-list>
      </div>
    </template>
    
    <script>
    import ResourceList from './components/list'
    export default {
      name: 'ResourceIndex',
      components: {
        ResourceList
      }
    }
    </script>
    
    <style lang="scss" scoped></style>
    
    

    布局完毕

    展示资源列表

    使用的接口是按条件分页查询资源接口:接口地址
    Postman 测试时注意,所有参数可选:

    • 无参数时需要传入空对象,这时响应数据的data.records为第一页的多余数据
    • 传入参数用于按条件筛选,如传入name,或者url,这时响应数据的data.records为筛选后的第一条
      • 接口支持模糊查询,例如传入"url":"menu",这时会响应多条满足条件的资料信息
        测试完毕之后,就可以封装接口到新模块中啦
    // services/resource.js
    import request from '@/utils/request'
    
    // 资源请求
    export const getResourcePages = data => {
      return request({
        method: 'POST',
        url: '/boss/resource/getResourcePages',
        data
      })
    }
    

    引入调用

    // resource/components/list.vue
    ...
    <script>
    // 引入
    import { getResourcePages } from '@/services/resource.js'
    
    export default {
      ...
      created () {
        // 调用
        this.loadResources()
      },
      methods: {
        ...
        async loadResources () {
          // 请求,空对象必须传入,否则参数不完整导致接口报错
          const { data } = await getResourcePages({})
          console.log(data)
        }
      }
    }
    </script>
    

    成功之后将数据存储到data.resourcs并且绑定到table组件中,要注意一点,日期的格式需要使用过滤器进行调整,详细参考代码:

    <template>
      <div class="resource-list">
        <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">查询</el-button>
              </el-form-item>
            </el-form>
          </div>
          <div>
            <el-table
            :data="resources"
            style="width: 100%">
              <el-table-column
              type="index"
              label="编号"
              width="100"
              ></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.createdTime | dateFormat }}</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"
                  @click="handleDelete(scope.row)"
                  type="danger"
                  >删除</el-button>
              </template>
              </el-table-column>
            </el-table>
          </div>
        </el-card>
      </div>
    </template>
    
    <script>
    import { getResourcePages } from '@/services/resource'
    export default {
      name: 'ResourceList',
      data () {
        return {
          formInline: {},
          //   用于存储资源列表数据
          resources: []
        }
      },
      created () {
        this.loadResources()
      },
      methods: {
        onSubmit () {
          console.log('submit!')
        },
        async loadResources () {
          const { data } = await getResourcePages({})
          if (data.code === '000000') {
            this.resources = data.data.records
          }
        },
        handleEdit () {
        },
        handleDelete () {
        }
      },
      filters: {
        // 日期过滤器
        dateFormat (date) {
          date = new Date(date)
          return `
          ${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}
          ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}
          `
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    </style>
    
    

    table组件数据要使用过滤器,得需要通过自定义列模板方式设置插值表达式

    分页处理

    分页布局

    使用Element的Pagination分页组件->附加功能->完善功能设置,将结构,方法,数据添加到list.vue中

    // list.vue
    <el-card class="box-card">
      ...
      <!-- 给 table 与 pagination 设置间距,看起来更美观 -->
      <el-table
        :data="resources"
        style="width: 100%; margin-bottom: 20px;">
      ...
      <!-- 分页功能 -->
      <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="currentPage4"
            :page-sizes="[100, 200, 300, 400]"
            :page-size="100"
            layout="total, sizes, prev, pager, next, jumper"
            :total="400">
      </el-pagination>
    </el-card>
    ...
    <script>
    ...
    data () {
      return {
        ...
        currentPage1: 5,
        currentPage2: 5,
        currentPage3: 5,
        currentPage4: 4
      }
    },
    ...
    methods: {
      ...
      handleSizeChange (val) {
        console.log(`每页 ${val} 条`)
      },
      handleCurrentChange (val) {
        console.log(`当前页: ${val}`)
      }
    },
    ...
    </script>
    

    分页功能

    分页功能的接口存在两个比较重要的请求参数

    • current(当前页数)
    • size(每页条数)
      由于分页需要与筛选功能结合,所以将数据声明到data.form
      • 更改了form的名称之后,注意将模板中的数据名称同时修改(简单处理就可以了,后续还要设置功能)
      • 修改current时页面会渲染不同页的数据
    // list.vue
    data () {
      return {
        ...
        form: {
          ...
          // 当前页号,默认为 1
          current: 1,
          // 每页数据条数,例如为10,按需设置
          size: 10
        },
        ...
      }
    },
    methods: {
        async loadResources () {
      // 将参数传入请求
      const { data } = await getResourcePages({
        current: this.form.current,
        size: this.form.size
      })
      ...
    },
    }
    

    分页组件的页面变化会触发handleCurrentChange事件,参数为当前页号,操作时请求当前页码的数据即可

    // list.vue
    // 页码变化时触发
    handleCurrentChange (val) {
      // 将 val 同步给 current
      this.form.current = val
      // 请求更新数据
      this.loadResources()
    }
    

    注意:
    这是我们发现页码按钮个数为固定值,应该进行设置,观察组件的属性

    • current-page:当前组件显示页码
      • this.form.current会更新请求的数据页码为1,而显示页码需要通过当前属性控制
      • 文档中说明当前属性支持.sycn修饰符
        设置:current-page.sync = "form.current"
        这样一来之前事件中的this.form.current = val就可以不需要设置了,视图操作导致属性的改变会自动同步到form.current中,反之亦然(与v-model有点类似)
    • total为数据总数
    • page-size为每页大小,应该绑定到form.size
    • page-sizes为左侧设置每页条数的下拉菜单,第一个值为初始值,不应大于总条数,否则只会出现一页,后续值自行按需设置

    组件会根据上面的属性自动计算总页数,现在只有total应该通过请求获取

    <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page.sync="form.current"
          :page-sizes="[10, 15, 20]"
          :page-size="form.size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalCount">
        </el-pagination>
    

    在请求数据的时候,接口响应数据包含了total为总数据条数,保存到data中并在created中接收

    • 数据中的currentPage1/2/3/4为文档提供的数据,可以直接删掉
    data () {
      return {
        ...
        // 数据总条数
        totalCount: 0
      }
    },
    ...
    methods: {
      ...
      async loadResources () {
        ...
        if (data.code === '000000') {
          this.resources = data.data.records
          // 保存总条数
          this.totalCount = data.data.total
        }
      }
      ...
    },
    

    设置后页码可以切换了,但是更新每页条数只更改了页码,数据没有更新,于是我们这个时候可以通过组件的size-change事件处理

    • size-change会在每页条数发生变化时触发,参数为新的条数,赋值给form.size
    • 重置页码为1
    • 更新数据
    // 每页显示条数触发事件
        handleSizeChange (val) {
          this.form.size = val
          // 由于修改了每一页现实的条数,应该归零页数
          this.form.current = 1
          this.loadResources()
        },
    

    复杂但是也不是很难的分页功能就搞定了。

    筛选处理

    筛选功能

    data 中声明数据,更新模板绑定数据,资源分类功能需要请求接口操作

    • 声明的数据名称需要根据接口请求参数设置,最后将form整体发送给接口
    • 添加一个重置按钮
    form: {
      // 资源名称
      name: '',
      // 资源路径
      url: '',
      // 资源分类
      categoryId: ''
      ...
    },
    
    <el-form :inline="true" :model="form" class="demo-form-inline">
      <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.url" placeholder="资源路径"></el-input>
      </el-form-item>
      <el-form-item label="资源分类">
        <el-select v-model="form.categoryId" 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-button>重置</el-button>
      </el-form-item>
    </el-form>
    

    查询资源分类列表:接口

    // 新建文件 services/resource-category.js
    import request from '@/utils/request'
    
    // 资源分类请求
    export const getResourceCategory = () => {
      return request({
        method: 'GET',
        url: '/boss/resource/category/getAll'
      })
    }
    

    引入并且请求数据

    ...
    import { getResourceCategory } from '@/services/resource-category.js'
    ...
    created () {
      ...
      this.loadResourceCategory()
    },
    ...  
    data () {
      return {
        // 资源分类列表
        resourceCategories: [],
        ...
      }
    },
    methods: {
      async loadResourceCategory () {
        const { data } = await getResourceCategory()
        if (data.code === '000000') {
          this.resourceCategories = data.data
        }
      },
      ...
    

    遍历生成资源分类下拉菜单

    <el-form-item label="资源分类">
      <el-select v-model="form.categoryId" placeholder="资源分类">
        <el-option
          :label="item.name"
          :value="item.id"
          v-for="item in resourceCategories"
          :key="item.id"
        ></el-option>
      </el-select>
    </el-form-item>
    

    提交时请求数据,同时更改页数为1

    onSubmit () {
      // 筛选提交,请求数据 (将请求参数更改为整个 form)
      this.form.current = 1
      this.loadResources()
    },
    ...
    async loadResources () {
      // 将参数传入请求
      /* const { data } = await getResourcePages({
        current: this.form.current,
        size: this.form.size
      }) */
      const { data } = await getResourcePages(this.form)
      ...
    },
    

    清除功能

    清除分为下拉菜单清除和统一清除(重置)
    单个清除使用Element中select下拉框组件中的可清空单选功能

    • 给下拉框组件设置clearable属性就可以了
    // list.vue
    <el-select
      v-model="form.categoryId"
      placeholder="资源分类"
      clearable
    >
    

    表单重置操作需要清空表单

    • 表单组件提供了resetFields()用于重置具有prop的表单项
    • 表单需要设置ref
    • 需要给表单项添加prop才能使用,未设置prop的表单项不受重置影响
    <el-form 
      :inline="true"
      :model="form"
      class="demo-form-inline"
      ref="form"
    >
      <el-form-item label="资源名称" prop="name">
        <el-input v-model="form.name" placeholder="资源名称"></el-input>
      </el-form-item>
      <el-form-item label="资源路径" prop="url">
        <el-input v-model="form.url" placeholder="资源路径"></el-input>
      </el-form-item>
      <el-form-item label="资源分类" prop="categoryId">
    ...
    <el-button
      @click="onReset"
    >重置</el-button>
    ...
    onReset () {
      this.$refs.form.resetFields()
    },
    

    这个方法可以将我们在菜单管理那里进行粗暴的清空方式给替换掉了

    数据加载细节处理

    网速慢的时候,显示加载中提示,同时禁用所有操作
    这个时候使用Element的Loading加载组件设置

    • 通过指令v-loading控制,true表示加载中,false表示隐藏提示
    • 按钮与分页组件的禁用属性均为disabled
    // list.vue
    ...
    <el-button
      type="primary"
      @click="onSubmit"
      :disabled="isLoading"
    >查询搜索</el-button>
    ...
    <el-table
      :data="resources"
      style="width: 100%; margin-bottom: 20px;"
      v-loading="isLoading"
    >
    <el-button
      @click="onReset"
      :disabled="isLoading"
    >重置</el-button>
    ...
    <el-pagination
      ...
      :disbled="isLoading">
    </el-pagination>
    ...
    <script>
      
    data () {
      return {
        ...
        // 加载状态
        isLoading: false
      }
    },
    ...
    async loadResources () {
      // 开始加载数据
      this.isLoading = true
      ...
      // 请求完毕取消加载中状态
      this.isLoading = false
    },
    </script>
    

    资源的增删改都是重复性的知识,通过element加接口都可以完成
    接口文档:接口

    相关文章

      网友评论

          本文标题:权限管理:资源管理

          本文链接:https://www.haomeiwen.com/subject/uamrqltx.html