vue2制作高复用页面

news2024/9/28 2:29:46

        记录一下页面搭建记录,利用vue2组件化开发的思想。这个页面适合于大部分信息管理系统~。模板固定,每次使用,直接修改表单表格参数,api接口等。

          以上图页面为例,一个基础数据信息页面可以分为,分类(左侧),数据信息(右侧),搜索表单(右上),数据表格(右下),新增或编辑表单(对话框)。

          全局css样式部分

.top_box {
  // min-height: 10vh;
  width: 100%;
  border-radius: 5px;
  background-color: #fff; /* 背景色为白色 */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); /* 添加投影效果 */
  padding: 10px 10px 10px;
  margin-bottom: 10px;
}

.down_box {
  min-height: 10vh;
  width: 100%;
  border-radius: 5px;
  background-color: #fff; /* 背景色为白色 */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); /* 添加投影效果 */
}

.left_box {
  float: left;
  width: 20%;
  border-radius: 5px;
  background-color: #fff; /* 背景色为白色 */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); /* 添加投影效果 */
  padding-bottom: 5%;
}

.right_box {
  float: left;
  min-height: 90vh;
  width: 79%;
  margin-left: 1%;
  border-radius: 5px;
  background-color: #fff; /* 背景色为白色 */
}

index.vue(主页面)

<template>
  <div class="app-container">
    <div class="left_box">
      <CategoryMenu @selectNode="selectNode" />
    </div>
    <div class="right_box">
      <div class="top_box">
        <search-form
          :searchForm="searchForm"
          :size="size"
          @search="performSearch"
          @reset="resetSearch"
        />
        <div style="float: left; margin: 5px 0 0 20px">
          <el-button
            :disabled="currentCategoryId === null || currentCategoryId === ''"
            type="primary"
            plain
            :size="size"
            icon="el-icon-circle-plus-outline"
            @click="toAdd"
          >
            新增
          </el-button>
          <el-button
            type="success"
            plain
            :size="size"
            icon="el-icon-document-copy"
            disabled
          >
            迭代
          </el-button>
         
        </div>
        <div style="clear: both"></div>
      </div>
      <div class="down_box">
        <div style="padding: 20px 20px 10px 20px">
          <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item
              v-for="(item, index) in currentCategory"
              :key="index"
              >{{ item }}</el-breadcrumb-item
            >
          </el-breadcrumb>
        </div>
        <div style="padding: 10px; min-height: 400px">
          <customTable :list="list" @toEdit="toEdit" @toDelete="toDelete" />
        </div>
        <div style="padding-bottom: 10px">
          <el-pagination
            :page-sizes="[10, 20, 40, 100]"
            :page-size="pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="counts"
            :current-page.sync="page"
            @size-change="(val) => handleSizeChange(val, this)"
            @current-change="(val) => handleCurrentChange(val, this)"
            align="center"
          ></el-pagination>
        </div>
      </div>
    </div>
    <editForm
      :edit-vis="editVis"
      :edit-status="editStatus"
      :edit-form="editForm"
      :rules="rules"
      :userOption="userOption"
      @submit="submitForm"
      @cancel="cancel"
    />
  </div>
</template>
  
<script>
import {
  addStorageWarehouse,
  pageStorageWarehouse,
  updateStorageWarehouse,
  deleteStorageWarehouse,
} from "@/api/storage/storage-warehouse";
import { list } from "@/api/system/user";
import {
  confirmAction,
  submitWithConfirmation,
} from "@/utils/confirmationHelper";
import paginationMethods from "@/utils/pagination.js";
import searchForm from "./components/searchForm.vue";
import customTable from "./components/customTable.vue";
import editForm from "./components/editForm.vue";
import CategoryMenu from "./components/CategoryMenu.vue";
export default {
  name: "bom",
  components: {
    searchForm,
    customTable,
    editForm,
    CategoryMenu,
  },
  data() {
    return {
      content: "BOM信息",
      size: "small",
      list: [],
      searchForm: {},

      currentCategoryId: "",
      currentCategoryName: "",
      currentCategory: [],

      counts: 0,
      page: 1,
      pageSize: 10,
      userOption: [],

      editVis: false,
      editStatus: false,

      editForm: {},
      rules: {
        code: [{ required: true, message: "BOM编码不能为空", trigger: "blur" }],
      },
    };
  },
  watch: {},
  created() {
    this.init();
  },
  mounted() {
    document.addEventListener("keyup", this.handleKeyUp);
  },
  beforeDestroy() {
    document.removeEventListener("keyup", this.handleKeyUp);
  },
  methods: {
    init() {
      list().then((res) => {
        this.userOption = res.data.list.map((item) => {
          return {
            value: item.id,
            label: item.name,
          };
        });
      });
      this.fetchData();
    },
    handleKeyUp(event) {
      if (event.key === "Enter") {
        this.fetchData();
      }
    },
    fetchData() {
      var vm = this;
      const params = {
        page: vm.page,
        pageSize: vm.pageSize,
        categoryId: vm.currentCategoryId ? vm.currentCategoryId : undefined,
        code: vm.searchForm.code ? vm.searchForm.code : undefined,
        productCode: vm.searchForm.productCode
          ? vm.searchForm.productCode
          : undefined,
      };
      // pageStorageWarehouse(params).then((res) => {
      //   vm.list = res.data.page.records;
      //   vm.counts = res.data.page.total;
      // });
    },
    ...paginationMethods, // 导入分页方法
    performSearch(searchForm) {
      this.searchForm = searchForm;
      this.handleClickSearch(this);
    },
    resetSearch() {
      this.pageSize = 10;
      this.currentCategoryId = "";
      this.currentCategoryName = "";
      this.currentCategory = [];
      this.resetTable(this);
    },
    toAdd() {
      this.editForm = {};
      this.editStatus = false;
      this.editVis = true;
    },
    toEdit(row) {
      this.editForm = { ...row };
      this.editStatus = true;
      this.editVis = true;
    },
    toDelete(row) {
      const message = "是否删除" + this.content + "?";
      const action = () => deleteStorageWarehouse(row.id);
      confirmAction(this, message, action);
    },
    cancel() {
      this.editVis = false;
      this.editForm = {};
    },
    // 提交
    submitForm(editForm) {
      this.editForm.bomCategoryId = this.currentCategoryId;
      const action = this.editStatus
        ? () => updateStorageWarehouse(editForm)
        : () => addStorageWarehouse(editForm);
      submitWithConfirmation(this, action);
    },
    selectNode(id, name, category) {
      this.currentCategoryId = id;
      this.currentCategoryName = name;
      this.currentCategory = category.split(",");
      this.fetchData();
    },
  },
};
</script>
  
  <style lang="less" scoped>
</style>
  

分类菜单(左侧)

<template>
  <div style="padding: 5px">
    <div>
      <h3 style="margin: 8px 0; color: rgb(111, 111, 111); text-align: center">
        BOM分类
        <span
          style="float: right; margin-right: 10px; cursor: pointer"
          @click="editVis = true"
        >
          <i class="el-icon-edit-outline" />
        </span>
      </h3>
    </div>
    <div style="margin-bottom: 10px">
      <el-input placeholder="输入BOM分类" v-model="filterText" size="mini">
      </el-input>
    </div>
    <el-tree
      :data="data"
      default-expand-all
      :filter-node-method="filterNode"
      :expand-on-click-node="false"
      ref="tree"
    >
      <span slot-scope="{ data }">
        <span style="font-size: 14px" @click="toFind(data)">
          <i class="el-icon-folder" />&nbsp; {{ data.code }} -
          {{ data.name }}
        </span>
      </span>
    </el-tree>
    <el-dialog
      title="BOM分类"
      :visible.sync="editVis"
      width="1280px"
      top="56px"
      append-to-body
    >
      <CategoryEdit />
    </el-dialog>
  </div>
</template>

<script>
import { getBomCategoryList } from "@/api/product/bom-category";
import CategoryEdit from "./CategoryEdit.vue";
export default {
  components: {
    CategoryEdit,
  },
  data() {
    return {
      filterText: "",
      data: [],
      editVis: false,
    };
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.fetchData();
  },
  methods: {
    fetchData() {
      getBomCategoryList().then((res) => {
        this.data = res.data.list;
      });
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    toFind(data) {
      // 返回目录id和目录分级
      this.$parent.selectNode(data.id, data.name, this.findParentById(data.id));
    },
    findParentById(id) {
      const findParentRecursive = (data, id, path = []) => {
        for (let item of data) {
          if (item.id === id) {
            return path.concat(item);
          } else if (item.children) {
            const result = findParentRecursive(
              item.children,
              id,
              path.concat(item)
            );
            if (result) {
              return result;
            }
          }
        }
        return null;
      };
      const result = findParentRecursive(this.data, id);
      if (result) {
        return result.map((item) => item.name).join(",");
      } else {
        return "未找到父级元素";
      }
    },
  },
};
</script>

搜索表单

<template>
  <el-form label-width="100px" v-model="searchForm">
    <el-form-item :size="size" label="BOM编码:" class="searchItem">
      <el-input
        v-model="searchForm.code"
        placeholder="请输入"
        class="searchInput"
        clearable
      />
    </el-form-item>
    <el-form-item :size="size" label="产品编码:" class="searchItem">
      <el-input
        v-model="searchForm.productCode"
        placeholder="请输入"
        class="searchInput"
        clearable
      />
    </el-form-item>
    <div class="searchItem">
      <el-button
        type="primary"
        :size="size"
        icon="el-icon-search"
        @click="handleClickSearch()"
      >
        搜索
      </el-button>
      <el-button
        icon="el-icon-refresh-right"
        :size="size"
        @click="() => resetTable()"
      >
        重置
      </el-button>
    </div>
    <div style="clear: both"></div>
    <!-- 清除浮动 -->
  </el-form>
</template>
  
  <script>
export default {
  name: "SearchForm",
  props: {
    searchForm: {
      type: Object,
      required: true,
    },
    size: {
      type: String,
      default: "mini",
    },
  },
  methods: {
    handleClickSearch() {
      this.$emit("search", this.searchForm);
    },
    resetTable() {
      this.$emit("reset");
    },
  },
};
</script>
  
<style scoped>
.searchItem {
  float: left;
  margin-left: 20px;
}
.searchInput {
  width: 160px;
}
</style>

数据表格

<template>
  <div>
    <el-table :data="list" fit highlight-current-row>
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column label="BOM编码" align="center" prop="code" width="230">
        <template slot-scope="scope">
          <span>
            <el-link
              :underline="false"
              type="primary"
              @click="toEdit(scope.row)"
              >{{ scope.row.code }}</el-link
            ></span
          >
        </template>
      </el-table-column>
      <el-table-column
        label="关联产品"
        align="center"
        prop="productCode"
        width="230"
      />
      <el-table-column label="版本号" align="center" prop="version" />
      <el-table-column label="状态" align="center" prop="status" />
      <!-- 操作栏 -->
      <el-table-column
        label="操作"
        align="center"
        width="230"
        fixed="right"
        prop="operation"
      >
        <template slot-scope="{ row, $index }">
          <el-button size="mini" type="success" @click="toCopy(row)">
            迭代
          </el-button>
          <el-button size="mini" type="success" v-if="row.status === 1">
            提交
          </el-button>
          <el-button size="mini" type="warning" v-if="row.status === 2">
            审核
          </el-button>
          <el-button size="mini" type="primary" @click="toEdit(row)">
            查看
          </el-button>
          <el-button size="mini" type="danger" @click="toDelete(row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "custom-table",
  props: {
    list: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      size: "small",
    };
  },
  watch: {
    list(newVal, oldVal) {},
  },
  methods: {
    toEdit(row) {
      this.$emit("toEdit", row);
    },
    toCopy(row) {},
    toDelete(row) {
      this.$emit("toDelete", row);
    },
  },
};
</script>

<style>
</style>

新增或编辑表单(对话框)

<template>
  <el-dialog
    :title="editStatus ? '查看BOM信息' : '新增BOM信息'"
    :visible="vis"
    width="730px"
    top="56px"
    append-to-body
    :before-close="handleClose"
  >
    <el-form
      ref="editForm"
      :model="editForm"
      :rules="rules"
      label-width="115px"
      size="small"
    >
      <el-form-item
        :size="size"
        label="BOM编码:"
        prop="code"
        style="float: left"
      >
        <el-input
          v-model="editForm.code"
          class="editItem"
          placeholder="请输入"
        />
      </el-form-item>
      <el-form-item
        :size="size"
        label="产品信息:"
        prop="name"
        style="float: left"
      >
        <el-input
          v-model="editForm.name"
          class="editItem"
          placeholder="请输入"
        />
      </el-form-item>
      <div style="clear: both"></div>
      <el-form-item label="备注:" prop="remark" style="float: left">
        <el-input
          v-model="editForm.remark"
          type="textarea"
          placeholder="请输入备注"
          style="width: 515px"
        />
      </el-form-item>
      <div style="clear: both"></div>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <div style="margin-right: 60px">
        <el-button
          v-if="editStatus"
          type="primary"
          size="mini"
          @click="submitForm('editForm')"
          >保 存</el-button
        >
        <el-button
          v-if="!editStatus"
          type="primary"
          size="mini"
          @click="submitForm('editForm')"
          >新 增</el-button
        >
        <el-button size="mini" @click="cancel">取 消</el-button>
      </div>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "edit",

  props: {
    editVis: {
      type: Boolean,
      required: true,
    },
    editStatus: {
      type: Boolean,
      required: true,
    },
    editForm: {
      type: Object,
      required: true,
    },
    rules: {
      type: Object,
      required: true,
    },
    userOption: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      size: "small",
      vis: false,
    };
  },
  watch: {
    editVis(newVal, oldVal) {
      this.vis = this.editVis;
    },
  },
  methods: {
    handleClose(done) {
      this.$confirm("您确定要关闭吗?", "确认", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.cancel();
          done();
        })
        .catch(() => {
          // 用户点击取消时的处理
        });
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$emit("submit", this.editForm);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    cancel() {
      this.$refs["editForm"].resetFields();
      this.$emit("cancel");
    },
  },
};
</script>

<style lang="less" scoped>
.editItem {
  width: 200px;
}

/deep/ .el-collapse-item__header {
  padding-left: 50px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2137221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据恢复软件推荐:轻松找回删除的文件!

在使用电脑的过程中&#xff0c;有时我们会误操作或者因为其他原因而删除了一些重要的文件。当我们需要这些文件却找不到时&#xff0c;就会产生很大的困扰。那么&#xff0c;如果你的电脑中的文件被误删了&#xff0c;应该怎么找回被删除的文件呢?下面&#xff0c;小编整理出…

办公必备的高效翻译工具大揭秘

网易翻译是我最早接触的一款翻译工具&#xff0c;随着翻译时候需求的增加让开始了解其他的翻译工具。如果你也正在为你的翻译需求头疼那不妨看看我今天要介绍的工具有没有符合你需求的。 1.福昕在线翻译 链接直达&#xff1a;https://fanyi.pdf365.cn/doc 这个工具比较适合…

【大模型专栏—实战篇】基于RAG从0到1搭建AI科研知识库

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

nvidia-docker Failed to initialize NVML: Unknown Error

nvidia镜像拉下来了&#xff0c;但是运行不了。 执行以下命令 sudo docker run --rm --runtimenvidia --gpus all ubuntu nvidia-smi报错 Failed to initialize NVML: Unknown Error参考 https://stackoverflow.com/questions/72932940/failed-to-initialize-nvml-unknown-er…

基于springboot 校园闲置物品交换平台设计与实现---附源码74557

摘 要 随着我国互联网技术的飞速发展&#xff0c;网络购物已经成为人们日常生活的重要组成部分。特别是在校园中&#xff0c;由于学生群体的特殊性&#xff0c;闲置物品交易的需求日益增长。然而&#xff0c;目前校园闲置物品物品交易市场仍然存在许多问题&#xff0c;如信息不…

声波的波数,通常用k表示

声波的波数&#xff08;通常用 k 表示&#xff09;是描述声波空间变化的一个参数&#xff0c;它与声波的频率和介质中的传播速度有关。波数 k 是一个具体值&#xff0c;并且在均匀介质中它是固定的&#xff0c;计算公式如下&#xff1a; 均匀介质中的波数是一个具体值&#xff…

react crash course 2024 (1)理论概念

state的作用 react hooks 而无需写一个class jsx 样式用 spa

判断当前环境是否为docker容器下

判断当前环境是否为docker容器下 webshell后或登录到系统后台&#xff0c;判断是否为docker容器可使用如下方法&#xff1a; 方式一&#xff1a;使用ls -alh命令查看是否存在.dockerenv来判断是否在docker容器环境内 ls -alh /.dockerenv如下图无.dockerenv文件&#xff0c;所…

Clickhouse使用笔记

clickhouse官方文档&#xff1a;https://clickhouse.com/docs/zh/sql-reference/data-types/decimal 一&#xff0c;建表 create table acitivity_user_record ( id String DEFAULT generateUUIDv4(), -- 主键自增 activityId String, userId String, userName Nullable(Strin…

【论文解读】图像序列识别:CRNN技术在场景文本识别中的应用与突破(附论文地址)

论文地址&#xff1a;https://arxiv.org/pdf/1507.05717 这篇文章的标题是《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》&#xff0c;作者是Baoguang Shi, Xiang Bai和Cong Yao&#xff0c…

代码随想录训练营 Day58打卡 图论part08 拓扑排序 dijkstra朴素版 + 堆优化版

代码随想录训练营 Day58打卡 图论part08 一、拓扑排序 例题&#xff1a;卡码117. 软件构建 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果…

不同的二叉搜索树

题目 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;n 1 输出&#xff…

JSP经典设计模式流程分析:JSP+JavaBean设计模式+MVC设计模式

JSP两种经典设计模式 Model1设计模式:JSPJavaBean 架构图 什么是JavaBean JavaBean是一种JAVA语言写成的可重用组件&#xff0c;它遵循特定的编程规范&#xff0c;如类必须是公共的、具有无参构造函数&#xff0c;并提供getter/setter方法等。这里的JavaBean不单单指的是实体…

五、回溯算法-算法总结

文章目录 五、回溯算法5.1 背景5.2 模板5.3 集合类5.3.1 子集5.3.2 子集2 5.4 排列类5.4.1 全排列5.4.2 全排列2 5.5 组合类5.5.1 组合总和5.5.2 电话号码的字母组合 五、回溯算法 5.1 背景 回溯法&#xff08;backtrack&#xff09;常用于遍历列表所有子集&#xff0c;是 DF…

OpenAI草莓正式发布,命名o1

一、相关介绍 当地时间 9 月 12 日&#xff0c;OpenAI 推出全新模型 o1&#xff0c;它是该公司计划推出的一系列“推理”模型中的首个&#xff0c;也就是此前业内传闻许久的“Strawberry&#xff08;草莓&#xff09;”项目。 据悉&#xff0c;o1 模型在众多任务中能够比人类更…

LabVIEW机动车动态制动性能校准系统

机动车动态制动性能测试系统通过高精度的硬件设备与LabVIEW软件的紧密配合&#xff0c;实现了对机动车制动性能的精确校准与评估。系统不仅提高了测试的精确性和效率&#xff0c;而且具备良好的用户交互界面&#xff0c;使得操作更加简便、直观。 项目背景 随着机动车辆数量的…

C++:类和对象全解

C&#xff1a;类和对象全解 一、类的定义和初始化&#xff08;一&#xff09;类的定义1、类的成员变量&#xff08;1&#xff09;成员变量&#xff08;2&#xff09;成员函数 2、实例化对象&#xff08;1&#xff09;采用普通构造函数&#xff08;2&#xff09;采用初始化列表 …

MySQL数据的增删改查(二)

目录 约束 非空约束&#xff08;NOT NULL&#xff09; 唯一约束&#xff08;UNIQUE&#xff09; 默认值约束&#xff08;DEFAULT&#xff09; 主键约束&#xff08;PRIMARY KEY&#xff09; 外键约束&#xff08;FOREIGN KEY&#xff09; 检查约束&#xff08;CHECK&…

LabVIEW机械产品几何精度质检系统

随着制造业的发展&#xff0c;对产品质量的要求越来越高&#xff0c;机械产品的几何精度成为衡量其品质的重要指标。为了提高检测效率和精度&#xff0c;开发了一套基于LabVIEW的几何精度质检系统&#xff0c;该系统不仅可以自动化地进行几何尺寸的测量&#xff0c;而且能实时分…

kafka 之 本地部署单机版

安装JDK 查看你选择的版本需要安装哪一个版本的jdk 网址 下载 JDK下载 注&#xff1a;如果网页不允许下载&#xff0c;使用wget命令下载即可&#xff0c;下载之后安装。 建议使用rpm安装&#xff0c;之后使用 update-alternatives --config java 控制当前环境使用Java的版…