Bootstrap

element-plus 自定义列表(非table)实现分页功能

  •  自定义列表实现分页功能
  • 增,删,改功能
  • 点击图片放大功能

template模块代码如下:

<template>

    <div class="booth_manager">

      <el-affix :offset="0">

        <div class="sticky_top">

          <div class="line">

            <div class="lf">

              <el-button type="primary" :icon="Plus" @click="handleAdd">新增</el-button>

            </div>

            <div class="rt">

              <el-button :type="0==search_options.is_in_outer?'danger':'info'" plain @click="toInBoothFun">对内展位图</el-button>

              <el-button :type="1==search_options.is_in_outer?'danger':'info'" plain @click="toOuterBoothFun">对外展位图</el-button>

              <el-input

                v-model="search_options.select_input"

                style="max-width: 400px"

                placeholder="请输入"

                class="input-with-select search_input"

              >

                <template #prepend>

                  <el-select v-model="search_options.select_option" placeholder="下拉选择" style="width: 115px">

                    <el-option  label="品牌" value="brand" />

                    <el-option label="展位号" value="booth" />

                  </el-select>

                </template>

                <template #append>

                  <el-button :icon="Search" />

                </template>

              </el-input>

            </div>

          </div>

          <div class="page">

            <el-pagination

              @size-change="handleSizeChange"

              @current-change="handleCurrentChange"

              :current-page="currentPage"

              :page-sizes="[5, 10, 20, 50]"

              :page-size="pageSize"

              :total="total"

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

            </el-pagination>

          </div>

        </div>

      </el-affix>

      <div class="content_box">

        <div class="li" v-for="(item,index) in paginatedData" :key="item.id">

          <div class="small demo-image__preview">

            <el-image

              class="img"

              :src="item.field1"

              :zoom-rate="1.2"

              :preview-teleported="true"

              :preview-src-list="[item.field1]"

              fit="cover"

              ref="imgViewRef"

            />

          </div>

          <div class="info_text">

            <div class="info brand_name">

              <div class="label">品牌:</div>

              <div class="name">{{item.field2}}</div>

            </div>

            <div class="info brand_name">

              <div class="label">展位号:</div>

              <div class="name">{{item.field3}}</div>

            </div>

          </div>

          <div class="btns">

            <el-button :icon="Search" circle @click="bigImgFun(index)"/>

            <el-button type="primary" :icon="Edit" circle @click="handleUpdate(item)" />

            <el-button type="danger" :icon="Delete" circle  @click="handleDelete(item)"/>

          </div>

        </div>

      </div>

      <!-- 添加或修改参数配置对话框 -->

      <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>

        <el-form ref="dictFormRef" :model="dialog_form" :rules="rules" label-width="80px">

          <el-form-item label="品牌名称" prop="field2">

            <el-input v-model="dialog_form.field2" placeholder="请输入品牌名称" />

          </el-form-item>

          <el-form-item label="展位号" prop="field3">

            <el-input v-model="dialog_form.field3" placeholder="请输入展位号" />

          </el-form-item>

          <el-form-item label="备注" prop="remark">

            <el-input v-model="dialog_form.remark" type="textarea" placeholder="请输入内容"></el-input>

          </el-form-item>

        </el-form>

        <template #footer>

          <div class="dialog-footer">

            <el-button type="primary" @click="submitForm">确 定</el-button>

            <el-button @click="cancel">取 消</el-button>

          </div>

        </template>

      </el-dialog>

      <el-backtop :right="80" :bottom="80" />

    </div>

</template>

script模块代码如下

<script setup name="Booth">

import { onMounted, onUnmounted,ref,computed } from 'vue';

import {Plus,Delete,Edit,Search} from '@element-plus/icons-vue';

const imgViewRef = ref(null)

const total = ref(100); // 假设总数据量为100

const pageSize = ref(10); // 每页显示数量

const currentPage = ref(1); // 当前页

const { proxy } = getCurrentInstance();

const search_options = ref({

  select_option:'',

  select_input:'',

  is_in_outer:0  //是否对内或对外

})

const dialog = reactive({

  visible: false,

  title: ''

});

const initFormData = {

  id: undefined,

  field1:'',

  field2: '',

  field3: '',

  remark: ''

}

const dialog_form = ref({ ...initFormData })

const rules =  reactive({

    field2: [{ required: true, message: "品牌名称不能为空", trigger: "blur" }],

    field3: [{ required: true, message: "展位号不能为空", trigger: "blur" }]

})

const dictFormRef = ref();

const dataList = ref(Array.from({ length: total.value }, (_, idx) => ({ id:idx+1,field1:'https://t12.baidu.com/it/u=4041564023,208120212&fm=30&app=106&f=JPEG?w=640&h=1138&s=1685B948F4723B966EB11E170300C0D4',field2:`慕思${idx+1}`,field3:'8-1ARR'}))); // 示例数据列表

/**

 * 放大图片

 */

const bigImgFun = (index)=>{

  setTimeout(() => {imgViewRef.value[index].$el.children[0].click();}, 0);

}

/**

 * 对内展位图

 */

const toInBoothFun = ()=>{

  search_options.value.is_in_outer = 0

}

/**

 * 对外展位图

 */

 const toOuterBoothFun = ()=>{

  search_options.value.is_in_outer = 1

}

/** 新增按钮操作 */

const handleAdd = () => {

  reset();

  dialog.visible = true;

  dialog.title = "新增";

}

/** 修改按钮操作 */

const handleUpdate = async (row) => {

  reset();

  console.log('row',row);

  // const dictId = row?.id || ids.value[0];

  // const res = await getType(dictId);

  Object.assign(dialog_form.value, row);

  dialog.visible = true;

  dialog.title = "修改";

}

/** 删除按钮操作 */

const handleDelete = async (row) => {

  const id = row?.id;

  await proxy?.$modal.confirm('是否确认删除编号为"' + id + '"的数据项?');

  // await delType(dictIds);

  // getList();

  proxy?.$modal.msgSuccess("删除成功");

}

/** 取消按钮 */

const cancel = () => {

  reset();

  dialog.visible = false;

}

/** 表单重置 */

const reset = () => {

  dialog_form.value = { ...initFormData };

  dictFormRef.value?.resetFields();

}

/** 提交按钮 */

const submitForm = () => {

  console.log('dialog_form',dialog_form.value);

  dictFormRef.value?.validate(async (valid) => {

    if (valid) {

      console.log('校验通过');

      // form.value.dictId ? await updateType(form.value) : await addType(form.value);

      // proxy?.$modal.msgSuccess("操作成功");

      dialog.visible = false;

      // getList();

    }

  });

}

// 计算分页后的数据

const paginatedData = computed(() => {

  const start = (currentPage.value - 1) * pageSize.value;

  const end = start + pageSize.value;

  console.log('start',start);

  console.log('end',end);

  return dataList.value.slice(start, end);

});

// 页面大小改变时的回调

function handleSizeChange(val) {

  pageSize.value = val;

}

// 当前页改变时的回调

function handleCurrentChange(val) {

  currentPage.value = val;

}

// 监听窗口大小变化

function handleResize() {

  // console.log('页面高度变化了!');

  // 在这里处理页面高度变化后的逻辑

}

onMounted(() => {

  // 组件挂载时添加监听器

  window.addEventListener('resize', handleResize);

});

onUnmounted(() => {

  // 组件销毁时移除监听器

  window.removeEventListener('resize', handleResize);

})

</script>

 样式代码如下

<style lang="scss">

.booth_manager{

  padding: 0 0 25px;

  .sticky_top{

    background-color: #fff;

    padding: 25px 25px 8px;

    box-shadow: 0px 1px 3px #bbb;

  .line{

    display: flex;

    justify-content: space-between;

    align-items: center;

    margin-bottom: 10px;

    .rt{

      display: flex;

      align-items: center;

      .search_input{

        margin-left: 12px;

      }

    }

  }

  .page{

    margin-bottom: 10px;

    display: flex;

    justify-content: flex-end;

  }

}

  .content_box{

    margin-top: 10px;

    padding: 0 25px;

    display: grid;

    grid-template-columns: repeat(auto-fill,minmax(260px,1fr));

    gap: 10px;

    .li{

      background-color: #f7f8f9;

      border: 1px solid #efeff0;

      border-radius: 5px;

      overflow: hidden;

      .small{

        width: 100%;

        height: 260px;

        overflow: hidden;

        padding: 1px;

        .img{

          width: 100%;

          height: 100%;

        }

      }

      .info_text{

        background-color: #fff;

        box-shadow: 0px 1px 1px 1px #ededed;

        padding: 5px;

        .info{

          display: flex;

          margin-bottom: 8px;

          .label{

            color: #898989;

            font-size: 15px;

            width: 25%;

            margin-right: 5px;

            text-align: right;

            font-weight: bold;

          }

          .name{

            width: 0;

            flex: 1;

            color: #333;

            font-size: 14px;

          }

        }

      }

      .btns{

        display: flex;

        justify-content: end;

        padding: 14px;

      }

    }

  }

}

</style>

;