一个VUE3的页面demo

样子是这样的

目录是这样的

index.vue文件内容

html 复制代码
<template>
  <div class="app-container">
    <div class="content">
      <div class="form" v-show="showSearch">
        <el-form
          ref="queryRef"
          :inline="true"
          :model="queryParams"
          label-width="72px"
        >
          <el-form-item label="名称" prop="name">
            <el-input
              v-model="queryParams.name"
              placeholder="请输入名称"
            ></el-input>
          </el-form-item>
          <el-form-item class="btns">
            <el-button @click="resetQuery">重置</el-button>
            <el-button
              type="primary"
              @click="handleQuery"
              class="btnClick"
              >搜索</el-button
            >
          </el-form-item>
        </el-form>
      </div>
      <div class="table">
        <div class="table-top-btn">
          <div class="mt-12">
            <el-button @click="handleAdd">
              <el-icon
                ><img src="@/assets/images/Plus.png" alt="" class="mr10"
              /></el-icon>
              新增
            </el-button>
            <el-button :disabled="attribute.single" @click="handleUpdate" >
              <el-icon
                ><img src="@/assets/images/Edit.png" alt="" class="mr10"
              /></el-icon>
              修改
            </el-button>
            <el-button :disabled="attribute.multiple" @click="handleDelete" >
              <el-icon
                ><img src="@/assets/images/Delete.png" alt="" class="mr10"
              /></el-icon>
              删除
            </el-button>
            <el-button type="primary" plain @click="download" >
              <el-icon
                ><img src="@/assets/images/export.png" alt="" class="mr10"
              /></el-icon>
              导出
            </el-button>
          </div>
          <right-toolbar
            v-model:showSearch="showSearch"
            @queryTable="getTable"
            :columns="columns"
          />
        </div>
        <TableInfo
          :dataList="dataList"
          :total="total"
          :queryParams="queryParams"
          :columns="columns"
          @fatherClick="getTable"
          @hidden="showButton"
        />
      </div>
    </div>

    <AddModify
      ref="addModifyRef"
      @closeDialog="offBtn"
      @define="submitButton"
    />
  </div>
</template>

<script setup>
import { reactive } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { parseTime } from "@/utils/ruoyi";
// import {
//   servicesList,
//   getServices,
//   addServices,
//   updateServices,
//   deleteServices,
// } from "@/api/archives/services.js";
import TableInfo from "./components/table";
import AddModify from "./components/addmodify.vue";

const { proxy } = getCurrentInstance();

const showSearch = ref(true);

// 查询条件
const queryParams = reactive({ name: "", pageNum: 1, pageSize: 10 });
// 选中表格相关参数
const attribute = reactive({
  ids: [],
  names: [],
  single: true,
  multiple: true,
});

const total = ref(0);
const dataList = ref([]);
const getTable = () => {

  // servicesList(queryParams).then((res) => {
  //   dataList.value = res.rows;
  //   total.value = res.total;
  // });
};
getTable();

// 查询
const handleQuery = () => {
  queryParams.pageNum = 1;
  getTable();
};
// 重置
const resetQuery = () => {
  proxy.resetForm("queryRef");
  queryParams.pageNum = 1;
  handleQuery();
};

// 列显隐信息
const columns = ref([
  { key: 0, label: `名称`, visible: true },
  { key: 1, label: `年龄`, visible: true },
  { key: 2, label: `性别`, visible: true },
  { key: 3, label: `职业`, visible: true },
  { key: 4, label: `地址`, visible: true },
  { key: 5, label: `备注`, visible: true },
]);

// 表格选中时触发的事件
const showButton = (val) => {
  attribute.ids = val.ids;
  attribute.names = val.names;
  attribute.single = val.single;
  attribute.multiple = val.multiple;
};

// 新增
const addModifyRef = ref(null);
const handleAdd = () => {
  addModifyRef.value.init({ title: "新增", open: true });
};
// 修改
const handleUpdate = async () => {
  if (attribute.single) {
    proxy.$modal.msgWarning("只能选择一条数据");
    return false;
  }
  const id = attribute.ids[0];
  let { rows } = await getServices({ id: id });
  addModifyRef.value.init({ title: "修改", open: true, obj: rows[0] });
};

// 新增、修改弹窗确认
const submitButton = (val) => {
  if (val.id != undefined && val.id != "") {
    updateServices(val).then((res) => {
      proxy.$modal.msgSuccess("修改成功");
      addModifyRef.value.resetForm();
      handleQuery();
    });
  } else {
    addServices(val).then((res) => {
      proxy.$modal.msgSuccess("新增成功");
      addModifyRef.value.resetForm();
      handleQuery();
    });
  }
};
// 新增、修改弹窗取消
const offBtn = () => {};

// 删除
const handleDelete = () => {
  const names = attribute.names;
  proxy.$modal
    .confirm('是否确认删除数据名称为"' + names + '"的数据项?')
    .then(function () {
      return deleteServices(attribute.ids);
    })
    .then(() => {
      handleQuery();
      proxy.$modal.msgSuccess("删除成功");
    })
    .catch(() => {});
};

// 导入
const importUpload = ref(null);
const handleImport = () => {
  importUpload.value.init();
};
const loadSucccess = () => {
  handleQuery();
};

// 导出
const download = () => {
  let date = parseTime(new Date().getTime(), "{y}-{m}-{d}");
  ElMessageBox.confirm("是否确认下载所有数据?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      proxy.download(
        "/archivesMgr/communication/export",
        { ...queryParams },
        `导出-${date}.xlsx`
      );
    })
    .catch(() => {
      ElMessage({ type: "info", message: "下载失败" });
    });
};
</script>

<style src="@/assets/styles/custom.scss" scoped />

其中里面引用日期组件在这里常用日期组件封装-CSDN博客

封装的显隐列在这里VUE2/3:element ui table表格的显隐列(若依框架)_elementui表格隐藏列-CSDN博客

table表格部分

html 复制代码
<template>
  <div class="table-container">
    <el-table
      stripe
      border
      :data="props.dataList"
      height="95%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="40" />
      <el-table-column type="index" label="序号" width="55" />
      <el-table-column
        prop="name"
        label="名称"
        min-width="110"
        v-if="props.columns[0].visible"
        show-overflow-tooltip
      >
        <template #default="scope">
          <div>
            {{ scope.row.name }}
          </div>
        </template>
      </el-table-column>
      <el-table-column
        prop="age"
        label="年龄"
        min-width="110"
        v-if="props.columns[1].visible"
        show-overflow-tooltip
      >
        <template #default="scope">
          <div>
            {{ scope.row.age }}
          </div>
        </template>
      </el-table-column>
     
      <el-table-column
        prop="sex"
        label="性别"
        min-width="110"
        v-if="props.columns[2].visible"
        show-overflow-tooltip
      />
      <el-table-column
        prop="job"
        label="职业"
        min-width="110"
        v-if="props.columns[3].visible"
        show-overflow-tooltip
      />
      <el-table-column
        prop="address"
        label="地址"
        min-width="110"
        v-if="props.columns[4].visible"
        show-overflow-tooltip
      />
    

      <el-table-column
        prop="note"
        :show-overflow-tooltip="true"
        min-width="120"
        label="备注"
        v-if="props.columns[5].visible"
      />
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>

<script setup>
import { reactive } from "vue";
const { proxy } = getCurrentInstance();

const props = defineProps({
  dataList: { default: [] },
  total: { default: 0 },
  queryParams: {
    pageNum: { default: 1 },
    pageSize: { default: 10 },
  },
  columns: { default: [] },
});

const emit = defineEmits(["fatherClick", "hidden"]);

const getList = () => {
  emit("fatherClick");
};

// 自定义参数
const attribute = reactive({
  ids: [],
  names: [],
  single: true,
  multiple: true,
});
// 表格选中事件
const handleSelectionChange = (selection) => {
  attribute.ids = selection.map((item) => item.id);
  attribute.names = selection.map((item) => item.name);
  attribute.single = selection.length != 1;
  attribute.multiple = !selection.length;
  emit("hidden", attribute);
};
</script>

<style lang="scss" scoped></style>

新增修改的弹出层

html 复制代码
<template>
  <el-dialog
    :title="params.title"
    v-model="params.open"
    width="550px"
    append-to-body
    destroy-on-close
    @closed="closeBtn"
  >
    <el-form ref="userRef" :model="form" :rules="rules" label-width="80px">
      <el-row>
        <el-col :span="12">
          <el-form-item label="名称" prop="name">
            <el-input
              v-model="form.name"
              placeholder="请输入名称"
              
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="年龄" prop="age">
            <el-input
              v-model="form.age"
              placeholder="请输入年龄"
              
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="性别" prop="sex">
            <el-input v-model="form.sex" placeholder="请输入性别"  />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="职业" prop="job" label-width="80px">
            <el-input
              v-model="form.job"
              placeholder="请输入职业"
              
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
       
        <el-col :span="12">
          <el-form-item label="地址" prop="address">
            <el-input
              v-model="form.address"
              placeholder="请输地址"
              
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="备注" prop="note">
            <el-input
              v-model="form.note"
              rows="4"
              type="textarea"
              placeholder="请输入内容"
              maxlength="255"
              show-word-limit
            />
          </el-form-item>
        </el-col>
      </el-row>
    </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>
</template>

<script setup>
import { reactive } from "vue";

const emit = defineEmits();
const { proxy } = getCurrentInstance();

// 自定义参数
const params = reactive({ title: "", open: false });
// 表单及校验
const form = ref({
  name: "",
});
const rules = reactive({
  name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
});


// 确定
const userRef = ref(null);
const submitForm = () => {
  userRef.value.validate((valid) => {
    if (!valid) return;
    emit("define", form.value);
  });
};
// 取消
const cancel = () => {
  resetForm();
  emit("closeDialog");
};
// 关闭
const closeBtn = () => {
  resetForm();
  emit("closeDialog");
};
// 重置表单
const resetForm = () => {
  params.open = false;
  proxy.resetForm("userRef");
};

const init = ({ title, open, obj = null }) => {
  params.title = title;
  params.open = open;
  if (obj) {
    form.value.id = obj.id;
    form.value.name = obj.name;
    form.value.sex = obj.sex;
    form.value.job = obj.job;
    form.value.address = obj.address;
    form.value.note = obj.note;
  } else {
    form.value = {};
  }
};

defineExpose({ init, resetForm });
</script>

<style lang="scss" scoped>
</style>

css部分

css 复制代码
.redNum {
    color: #e2463d;
}

.bulNum {
    color: #326aff;
}

.paramsClass {
    color: #326aff;
}

.app-container {
    width: 100%;
    height: 100%;
    display: flex;
    padding: 12px 20px 0 20px;

    .content {
        width: 100%;
        height: 100%;

        .form {
            padding: 12px 5px 0px 5px;
            background: #f7f8fa;
            border-radius: 4px;

            .el-form-item {
                margin: 0 40px 10px 0;
            }

            .el-input {
                width: 200px;
            }

            .btnClick {
                background-color: #326aff;
                border-color: #326aff;
            }
        }

        .table {
            height: 80%;
            padding: 5px;
            padding-top: 16px;
            background: #fff;

            .table-top-btn {
                display: flex;
                justify-content: space-between;
            }

            .mt-12 {
                margin-bottom: 12px;
            }

            .table-container {
                height: 100%;
            }

        }


    }
}

// 顶部带有tab分页
.tab-container {
    width: 100%;
    height: 90%;
    display: flex;

    .content {
        width: 100%;
        height: 100%;

        .form {
            padding: 12px 5px 0px 5px;
            background: #f7f8fa;
            border-radius: 4px;

            .el-form-item {
                margin: 0 40px 10px 0;
            }

            :deep(.el-form .el-form-item__label) {
                margin-right: 12px;
                padding: 0;
            }

            .el-input {
                width: 200px;
            }

            .btnClick {
                background-color: #326aff;
                border-color: #326aff;
            }
        }

        .table {
            height: 80%;
            padding: 5px;
            padding-top: 16px;
            background: #fff;

            .table-top-btn {
                display: flex;
                justify-content: space-between;
            }

            .mt-12 {
                margin-bottom: 12px;
            }

            .btnClick {
                background-color: #326aff;
                border-color: #326aff;
            }

            .table-container {
                height: 100%;
            }
        }
    }
}

.w-200 {
    width: 200px;
}

css的目录

相关推荐
徐同保12 分钟前
上传文件,在前端用 pdf.js 提取 上传的pdf文件中的图片
前端·javascript·pdf
怕浪猫13 分钟前
React从入门到出门第四章 组件通讯与全局状态管理
前端·javascript·react.js
博主花神13 分钟前
【React】扩展知识点
javascript·react.js·ecmascript
内存不泄露18 分钟前
基于Spring Boot和Vue 3的智能心理健康咨询平台设计与实现
vue.js·spring boot·后端
欧阳天风20 分钟前
用setTimeout代替setInterval
开发语言·前端·javascript
EndingCoder24 分钟前
箭头函数和 this 绑定
linux·前端·javascript·typescript
沐墨染26 分钟前
大型数据分析组件前端实践:多维度检索与实时交互设计
前端·elementui·数据挖掘·数据分析·vue·交互
xkxnq30 分钟前
第一阶段:Vue 基础入门(第 11 天)
前端·javascript·vue.js
小oo呆35 分钟前
【自然语言处理与大模型】LangGraphV1.0入门指南:核心组件Nodes
前端·javascript·easyui
行走的陀螺仪1 小时前
在UniApp H5中,实现路由栈的持久化
前端·javascript·uni-app·路由持久化·路由缓存策略