前端分页查询elementUI-vue3、后台管理列表页面组件之间的状态关系

2023-10-06 0 3,124 百度已收录

设计状态

我们来梳理一下需求,并用思维导图来表达:

使用“轻量级状态管理”定义状态:

/store-ds/index.js

import VuexDataState from 'vue-data-state'
export default VuexDataState.createStore({
  global: { // 全局状态
    userOnline: {
      name: 'jyk' //
    }
  },
  local: { // 局部状态
    dataListState () { // 获取列表数据的状态 dataPagerState
      return {
        query: {}, // 查询条件
        pager: { // 分页参数
          pageTotal: 100, // 0:需要统计总数;其他:不需要统计总数
          pageSize: 5, // 一页记录数
          pageIndex: 1, // 第几页的数据,从 1  开始
          orderBy: { id: false } // 排序字段
        },
        choice: { // 列表里面选择的记录
          dataId: '', // 单选,便于修改和删除
          dataIds: [], // 多选,便于批量删除
          row: {}, // 选择的记录数据,仅限于列表里面的。
          rows: [] // 选择的记录数据,仅限于列表里面的。
        },
        hotkey: () => {}, // 处理快捷键的事件,用于操作按钮
        reloadFirstPager: () => {}, // 重新加载第一页,统计总数(添加后)
        reloadCurrentPager: () => {}, // 重新加载当前页,不统计总数(修改后)
        reloadPager: () => {} // 重新加载当前页,统计总数(删除后)
      }
    } 
  },
  init (state) {
  }
})

这里没有使用Vuex,因为我觉得Vuex有点臃肿,所以我想自己弄点新鲜的。

另外,除了数据之外,状态还可以有方法(stormbus)。

如何在组件上使用轻量级状态

// 引入状态
import VueDS from 'vue-data-state'
// 访问状态
const { reg, get } = VueDS.useStore()
// 父组件注册列表的状态
const state = reg.dataListState()
// 子组件里面获取父组件注册的状态
const dataListState = get.dataListState()

首先引入状态,然后在父组件中注册(即注入)状态,然后在子组件中获取状态。

函数名称是上面定义的名称/store-ds/index.js。

后来我们还可以模仿MVC的Controller,做一个控制类,其实也可以称为管理类。

调用什么不是重点,重点是实现什么功能。

列表管理类

我们可以为列表的状态编写一个状态管理类。

该类位于单独的 js 文件中,不需要像 Vuex 那样设置操作或模块。

/control/data-list.js

import { watch, reactive } from 'vue'
// 状态
import VueDS from 'vue-data-state'
// 仿后端API
import service from '../api/dataList-service.js'
/**
 * * 数据列表的通用管理类
 * * 注册列表的状态
 * * 关联获取数据的方式
 * * 设置快捷键
 * @param {string} modeluId 模块ID
 * @returns 列表状态管理类
 */
export default function dataListControl (modeluId) {
  // 显示数据列表的数组
  const dataList = reactive([])
  // 模拟后端API
  const { loadDataList } = service()
  // 访问状态
  const { reg, get } = VueDS.useStore()
  // 子组件里面获取父组件注册的状态
  const dataListState = get.dataListState()
  // 数据加载中
  let isLoading = false
  /**
   * 父组件注册状态
   * @returns 注册列表状态
   */
  const regDataListState = () => {
    // 注册列表的状态,用于分页、查询、添加、修改、删除等
    const state = reg.dataListState()
    //  重新加载第一页,统计总数(添加、查询后)
    state.reloadFirstPager = () => {
      isLoading = true
      state.pager.pageIndex = 1 // 显示第一页
   
      // 获取数据
      loadDataList(modeluId, state.pager, state.query, true).then((data) => {
        state.pager.pageTotal = data.count
        dataList.length = 0
        dataList.push(...data.list)
        isLoading = false
      })
    }
    // 先执行一下,获取初始数据
    state.reloadFirstPager()
    // 重新加载当前页,不统计总数(修改后)
    state.reloadCurrentPager = () => {
      // 获取数据
      loadDataList(modeluId, state.pager, state.query).then((data) => {
        dataList.length = 0
        dataList.push(...data)
      })
    }
    // 重新加载当前页,统计总数(删除后)
    state.reloadPager = () => {
      // 获取数据
      loadDataList(modeluId, state.pager, state.query, true).then((data) => {
        state.pager.pageTotal = data.count
        dataList.length = 0
        dataList.push(...data.list)
      })
    }
    // 监听,用于翻页控件的翻页。翻页,获取指定页号的数据
    watch(() => state.pager.pageIndex, () => {
      // 避免重复加载
      if (isLoading) {
        // 不获取数据
        return
      }
      // 获取数据
      loadDataList(modeluId, state.pager, state.query).then((data) => {
        dataList.length = 0
        dataList.push(...data)
      })
    })
    return state
  }
 
  return {
    setHotkey, // 设置快捷键,(后面介绍)
    regDataListState, // 父组件注册状态
    dataList, // 父组件获得列表
    dataListState // 子组件获得状态
  }
}

管理类的功能: 父组件注册状态 获取状态定义列表数据的子组件容器 各类窃听风暴总线 父组件注册状态

由于使用的是本地状态,而不是全局状态,所以当需要使用它时,首先需要向父组件注册。 看起来不像全局状态那么简单,而且可以实现更好的复用前端分页查询elementUI,更容易区分数据,兄弟组件的状态也不会混淆。

子组件获取状态

因为状态必须在vue的直接函数内,所以需要先获取状态,不能等到暴风雨触发。

定义列表数据的容器

列表数据不是定义在状态上,而是定义在管理类上,因为只有主列表组件需要这个列表数据,其他组件不关心列表数据。

窃听:Storm:是否重新统计总数

你可能会发现获取数据有一个明显的区别,那就是是否需要总计统计。

当数据量非常大时,如果每次翻页都重新计算总量,这样会严重影响性能!

虽然仔细想想,有些情况下是不需要重新统计总数的,比如翻页、修改更新等,这样的操作不会影响记录总数(不管并发操作如何),所以我们不需要每次都数它们。 叙事。

文件结构

基本功能搭建完成后,剩下的就简单了。 只需构建组件并设置模板、控件、组件和使用状态。

整体结构如下:

使用列表状态

基础工作完成后,我们来看看如何在各个组件上使用状态。

查询

首先,让我们看一下查询。 用户设置查询条件后,查询控件将查询条件计入状态。

然后调用状态管理中的reloadFirstPager来获取列表数据。

查询控件支持长焦功能。


  
  

直接使用查询控件,模板内容是不是很简单?

import { reactive } from 'vue'
// 加载json
import loadJson from './control/loadjson.js'
// 状态
import VueDS from 'vue-data-state'
  // 组件
  import nfElFind from '/ctrl/nf-el-find/el-find-div.vue'
  // 属性:模块ID、查询条件
  const props = defineProps({
    moduleId:  [Number, String]
  })
  // 设置 查询的 meta
  const findProps = reactive({reload: true})
  loadJson(props.moduleId, 'find', findProps)
  // 访问状态
  const { get } = VueDS.useStore()
  // 获取状态
  const listState = get.dataListState()
  // 用户设置查询条件后触发
  const myChange = (query) => {
    // 获取第一页的数据,并且重新统计总数
    listState.reloadFirstPager()
  }

分页

分页非常简单。 查询条件是由查询控件决定的,所以这里只需按照el-pagination的要求将分页状态设置到el-pagination的属性即可。


  
  
  

直接使用状态作为属性值。

// 状态
import VueDS from 'vue-data-state'
// 访问状态
const { get } = VueDS.useStore()
// 获取分页信息
const pager = get.dataListState().pager

获取分页状态直接设置el-pagination属性即可。

翻页时,el-pagination会手动改变pager.pageIndex的值,状态管理会监听其改变,然后获取对应的列表数据。

添加、修改

添加完成后,总记录数会减少,需要重新统计总记录数,然后翻到第一页。

更改后,通常记录总数不会发生变化,因此只需重新获取当前页码的数据即可。


  
取 消 确 定

使用表单控件和两个按钮。

import { computed, reactive, watch } from 'vue'
import { ElMessage } from 'element-plus'
// 加载json
import loadJson from './control/loadjson.js'
// 状态
import VueDS from 'vue-data-state'
// 仿后端API
import service from './api/data-service.js'
 
  // 表单组件
  import elForm from '/ctrl/nf-el-form/el-form-div.vue'
  // 访问状态
  const { get } = VueDS.useStore()
  // 定义属性
  const props = defineProps({
    moduleId:  [Number, String], // 模块ID
    formMetaId:  [Number, String], // 表单的ID
    dataId: Number, // 修改或者显示的记录的ID
    type: String // 类型:添加、修改、查看
  })
  // 模块ID + 表单ID = 自己的标志
  const modFormId = computed(() => props.moduleId + props.formMetaId)
  // 子组件里面获取状态
  const dataListState = get.dataListState(modFormId.value)
  
  // 表单控件的 model
  const model = reactive({})
  
  // 表单控件需要的属性
  const formProps = reactive({reload:false})
  // 加载需要的 json
  loadJson(props.moduleId, 'form_' + props.formMetaId,  formProps)
  
  // 仿后端API
  const { getData, addData, updateData } = service(modFormId.value)
  // 监听记录ID的变化,加载数据便于修改
  watch(() => props.dataId, (id) => {
    if (props.type !== 'add') {
      // 加载数据
      getData( id ).then((data) => {
        Object.assign(model, data[0])
        formProps.reload = !formProps.reload
      })
    }
  },
  {immediate: true})
  // 提交数据
  const mysubmit = () => {
    // 判断是添加还是修改
    if (props.type === 'add'){
      // 添加数据
      addData(model).then(() => {
        ElMessage({
          type: 'success',
          message: '添加数据成功!'
        })
        // 重新加载第一页的数据
        dataListState.reloadFirstPager()
      })
    } else if (props.type === 'update') {
      // 修改数据
      updateData(model, props.dataId).then(() => {
        ElMessage({
          type: 'success',
          message: '修改数据成功!'
        })
        // 重新加载当前页号的数据
        dataListState.reloadCurrentPager()
      })
    }
  }

代码稍微多了一点,基本上就是在合适的时候调用状态下重新加载数据的风暴。

删除

删除也会影响记录总数,所以需要重新统计然后刷新当前页码的列表数据。

删除的代码写在操作按钮的组件上,对应删除按钮引发的争议:

      case 'delete':
        dialogInfo.show = false
        // 删除
        ElMessageBox.confirm('此操作将删除该记录, 是否继续?', '温馨提示', {
          confirmButtonText: '删除',
          cancelButtonText: '后悔了',
          type: 'warning'
        }).then(() => {
          // 后端API
          const { deleteData } = service(props.moduleId + meta.formMetaId)
          deleteData(dataListState.choice.dataId).then(() => {
            ElMessage({
              type: 'success',
              message: '删除成功!'
            })
            dataListState.reloadPager() // 刷新列表数据
          })
        }).catch(() => {
          ElMessage({
            type: 'info',
            message: '已经取消了。'
          })
        })
        break

删除成功后,调用state的dataListState.reloadPager()刷新列表页面。

快捷键

我喜欢用快捷键来进行一些操作前端分页查询elementUI,比如翻页、添加等。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 elementui 前端分页查询elementUI-vue3、后台管理列表页面组件之间的状态关系 https://www.wkzy.net/game/198632.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务