封装一个动态增加的tabs

376 阅读1分钟

需求:

image.png 可以添加政策,当前政策在切换的时候要求判断内容有无保存,如果没有保存,需要有提示,如果保存过了,或者没有内容变化,择切换。

<!--
 * @Author: zhangyantao 1326657763@qq.com
 * @Date: 2025-02-07 11:12:16
 * @LastEditors: zhangyantao 1326657763@qq.com
 * @LastEditTime: 2025-02-18 08:27:46
 * @FilePath: \dss-ui\src\views\PlatformSystem\IntelligentDrivingSystem\components\MyTabs.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="tabs-box">
    <el-tabs v-model="currentTab" :before-leave="handleClick" type="card">
      <el-tab-pane
        v-for="(tab, index) in tabs"
        :key="index"
        :name="index.toString()"
      >
        <div slot="label" class="my-label">政策{{ index + 1 }}</div>
      </el-tab-pane>
      <el-tab-pane key="addButton">
        <span slot="label">
          <el-button
            icon="el-icon-circle-plus-outline"
            type="text"
            class="add-item"
            @click.stop.prevent="addTab"
            >添加政策</el-button
          >
        </span>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
export default {
  props: {
    tabs: {
      type: Array,
      default: [{}],
    },
    oldForm: {
      type: Object,
      default: null,
    },
    form: {
      type: Object,
      default: null,
    },
  },

  data() {
    return {
      currentTab: "0",
      current: "0",
    };
  },
  watch: {
    currentTab(val) {
      console.log(val, "---");
    },
  },
  methods: {
    async handleClick(tab, event) {
      if (JSON.stringify(this.oldForm) != JSON.stringify(this.form)) {
        try {
          await this.$confirm("编辑未保存,确定要离开吗?", "提示", {
            confirmButtonText: "保存",
            cancelButtonText: "放弃更改",
            showClose: false,
          });
          const result = await new Promise((resolve) => {
            this.$emit("handleSave", { tab, resolve });
          });
          console.log(result);
          return result; // 返回保存结果,用于控制标签页切换
        } catch (err) {
          this.$emit("handleClick", tab);
        }
      } else {
        this.$emit("handleClick", tab);
      }
    },

    addTab() {
      this.$emit("addTab");
    },
  },
};
</script>
<style lang="scss" scoped>
.tabs-box {
  position: relative;
  ::v-deep {
    .el-tabs__nav {
      .el-tabs__item {
        .el-icon-close {
          display: none !important;
        }
      }
    }
    .el-tabs__header {
      .el-tabs__nav {
        border: none !important;
      }
      .el-tabs__item {
        padding: 0 !important;
        border: none !important;
      }
      .is-active {
        border-bottom: 3px solid #1b3194 !important;
      }
    }
    .el-icon-circle-plus-outline {
      font-size: 18px;
    }
    .el-button span {
      font-size: 18px;
      font-weight: bold;
    }
  }
  .my-label {
    width: 100%;
    height: 50%;
    padding: 0 30px;
    line-height: 30px;
    border-right: 1px solid #ccc;
  }
}
</style>

父组件使用

<template>
  <div class="pages">
    <div class="title">
      <div>{{ title }}</div>
    </div>
    <dynamic-tabs
      components="el-form"
      :tabs="policyList"
      :oldForm="oldForm"
      :form="form"
      ref="dynamicTabRef"
      @addTab="addTab"
      @handleSave="handleSave()"
      @handleClick="handleClick"
    >
    </dynamic-tabs>
    <el-form :model="form" label-width="auto" ref="formRef" :rules="rules">
     xxx
    </el-form>
    <div class="btn-box">
      <div class="sub-btn" @click="handleSave()">保存</div>
    </div>
  </div>
</template>
<script>
export default {
  components: { RegionSelect, DynamicTabs },
  mixins: [policy],
  data() {
    return {
      form: {
       
      },
      companyId: this.$route.query.companyId,
      contractId: this.$route.query.contractId,
      regionData: [], // 地区
      ecoDataScopeRegions: null,
      treeRegions: null,

      current: 0, // 切卡默认位置

     
    };
  },

  created() {
    this.getPolicyList();
    this.title = this.$route.query.customerName;
  },
  methods: {
    async getPolicyList() {
      const data = await channelDetailList({
        contractId: this.contractId,
      });
      if (data.length > 0) {
        data.map((el) => {
          return {
            id: el.id,
            name: "政策",
          };
        });
        this.policyList = data;
        this.form.id = this.policyList[this.current].id;
      } else {
        this.form.id = "";
      }
      this.getDetail(this.form.id);
    },
    /**
     * @Description: 新增政策
     * @Author: zhangyantao
     * @Date: 2025-02-13 14:28:28
     * @LastEditTime:
     * @LastEditors: zhangyantao
     */
    addTab() {
      this.policyList.push({
        name: "政策",
        id: "",
      });
    },
    /**
     * @Description: 切换政策
     * @Author: zhangyantao
     * @Date: 2025-02-13 14:28:39
     * @LastEditTime:
     * @LastEditors: zhangyantao
     * @param {*} data
     */
    handleClick(data) {
      this.current = Number(data);
      this.form.id = this.policyList[this.current].id || "";
      this.getDetail(this.form.id);
    },
    /**
     * @Description: 获取政策详情
     * @Author: zhangyantao
     * @Date: 2025-02-13 14:24:45
     * @LastEditTime:
     * @LastEditors: zhangyantao
     */
    async getDetail(policyId) {
      let params = {
        contractId: this.contractId,
        policyId,
      };
      channelDetail(params).then((res) => {
        
        this.form = res
          this.oldForm = JSON.parse(JSON.stringify(this.form));
        
      });
    },

    /**
     * @Description: 提交
     * @Author: zhangyantao
     * @Date: 2025-02-17 16:53:14
     * @LastEditTime:
     * @LastEditors: zhangyantao
     * @param {*} formName
     */
    async handleSave() {
      return new Promise((resolve) => {
        this.$refs.formRef.validate((valid) => {
          if (valid) {
            const params = {
              ...this.form,
              amount: this.amount,
              companyId: this.companyId,
              contractId: this.contractId,
            };
            saveChannelPolicy(params)
              .then((res) => {
                this.$message.success("保存成功");
                resolve(res);
                this.getPolicyList();
              })
              .catch((error) => {
                resolve(false);
              });
          } else {
            resolve(false);
          }
        });
      });
    },
  },
};
</cript>