使用 Vue 实现包含单选框的弹窗功能(附Demo)

news2025/1/18 3:53:11

目录

  • 前言
  • 1. Vue2
  • 2. Vue3

前言

如果在弹窗中单独增设一些选项或者少部分的数据,可用如下的方式
(不用单独创建专门的表单样式)
如果单纯可以通过基本的按钮传输给后端,可用如下知识点

对于弹窗的基本知识推荐阅读:

  1. Vue2:详细分析Element中的MessageBox基本知识(附Demo)
  2. 详细分析Element Plus中的ElMessageBox弹窗用法(附Demo及模版)

1. Vue2

此处涉及avue的知识点,推荐阅读:【vue】avue-crud表单属性配置(表格以及列)

基本的功能如下:

在这里插入图片描述

对应的template部分(以下代码为从实战中抽取)

<template>
  <avue-crud :option="option"
             :table-loading="loading"
             :data="data"
             :page="page"
             :permission="permissionList"
             :before-open="beforeOpen"
             :cell-style="cellStyle"
             v-model="form"
             ref="crud"
             @row-update="rowUpdate"
             @row-save="rowSave"
             @row-del="rowDel"
             @search-change="searchChange"
             @search-reset="searchReset"
             @selection-change="selectionChange"
             @current-change="currentChange"
             @size-change="sizeChange"
             @refresh-change="refreshChange"
             @on-load="onLoad">
    <template slot="menuLeft">
      <el-button type="primary" size="small" plain @click="showWeekPlanDialog">生成周月计划</el-button>

      <el-dialog title="周计划" :visible.sync="showWeekPlanDialogBox" :append-to-body="true" width="20%">
        <el-radio-group v-model="selectedPeriod" @change="handlePeriodChange">
          <el-table :data="weekPeriods" border>
            <el-table-column label="时间段" width="100">
              <template slot-scope="scope">
                <el-radio :label="scope.row.label"></el-radio>
              </template>
            </el-table-column>
            <el-table-column prop="dateRange" label="日期范围" width=200></el-table-column>
          </el-table>
        </el-radio-group>
        <el-button type="primary" size="small" @click="submitWeekPlan" style="margin: 10px;">提交</el-button>
      </el-dialog>
    </template>
  </avue-crud>
</template>

对应的功能部分如下:

<script>
  import { doCheckWeekPlan } from "@/api/equipment/basicInfo/inforunningdata";
  import moment from 'moment';

  export default {
    data() {
      return {
        showWeekPlanDialogBox: false, // 控制弹窗显示
        selectedPeriod: '', // 选中的时间段
        weekPeriods: [], // 时间段数组
        loading: true,
        page: {
          pageSize: 100,
          currentPage: 1,
          total: 0
        },
        selectionList: []
      };
    },
    methods: {
      // 显示周月计划弹窗
      showWeekPlanDialog() {
        if (this.selectionList.length === 0) {
          this.$message.warning("请选择至少一条数据");
          return;
        }
        this.calculateWeekPeriods();
        this.showWeekPlanDialogBox = true;
      },
      // 计算时间段
      calculateWeekPeriods() {
        const today = moment();
        const startDateThisWeek = today.clone().startOf('isoWeek');
        const endDateThisWeek = today.clone().endOf('isoWeek');
        const startDateLastWeek = startDateThisWeek.clone().subtract(1, 'week');
        const endDateLastWeek = startDateLastWeek.clone().endOf('isoWeek');
        const startDateNextWeek = startDateThisWeek.clone().add(1, 'week');
        const endDateNextWeek = startDateNextWeek.clone().endOf('isoWeek');

        const formatDateRange = (startDate, endDate) => {
            return `${startDate.format('YYYY-MM-DD')}~${endDate.format('YYYY-MM-DD')}`;
        };

        this.weekPeriods = [
            { label: '上周', dateRange: formatDateRange(startDateLastWeek, endDateLastWeek) },
            { label: '本周', dateRange: formatDateRange(startDateThisWeek, endDateThisWeek) },
            { label: '下周', dateRange: formatDateRange(startDateNextWeek, endDateNextWeek) }
        ];
      },
      // 提交周月计划
      submitWeekPlan() {
        if (this.selectedPeriod === '') {
          this.$message.warning("请选择一个时间段");
          return;
        }
        doCheckWeekPlan(this.ids, this.selectedPeriod).then(() => {
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          this.showWeekPlanDialogBox = false;
        }).catch(error => {
          console.log(error);
        });
      }
    }
  };
</script>
  • showWeekPlanDialogBox:控制弹窗显示的布尔值
  • selectedPeriod:存储用户选择的时间段
  • weekPeriods:存储计算后的时间段数组
  • showWeekPlanDialog:显示弹窗的方法,并在没有选中数据时提示用户
  • calculateWeekPeriods:计算并格式化上周、本周、下周的时间段
  • submitWeekPlan:提交选中的时间段并调用API,成功后刷新数据并关闭弹窗

对于Js的日期,推荐阅读:js获取上周本周下周的日期(附Demo)

2. Vue3

整体界面如下:

在这里插入图片描述

增加一个AuditDialog.vue文件

<template>
  <el-dialog :model-value="modelValue" @update:model-value="updateVisible" title="审批操作" width="15%">
    <el-radio-group v-model="selectedResult">
      <el-radio label="通过">审批通过</el-radio>
      <el-radio label="不通过">审批不通过</el-radio>
    </el-radio-group>
    <template #footer>
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleConfirm">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, watch } from 'vue';
import { ElMessage } from 'element-plus';

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true
  }
});

const emit = defineEmits(['confirm', 'update:modelValue']);

const selectedResult = ref('');

const handleConfirm = () => {
  if (!selectedResult.value) {
    ElMessage.error('请选择审批结果');
    return;
  }
  emit('confirm', selectedResult.value);
  emit('update:modelValue', false);
};

const handleCancel = () => {
  emit('update:modelValue', false);
};

const updateVisible = (value) => {
  emit('update:modelValue', value);
};

watch(() => props.modelValue, (newVal) => {
  if (!newVal) {
    selectedResult.value = ''; // 重置选择
  }
});
</script>

对应的父组件如下:

<template>
  <ContentWrap>
    <!-- 列表 -->
    <el-row justify="center" class="table-title">
      <el-col :span="24" class="text-center">
        委托单列表
      </el-col>
    </el-row>
    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
      <el-table-column label="预约编号" align="center" prop="appointmentId" />
      <el-table-column label="操作" align="center" width="180px">
        <template #default="scope">
          <div class="action-buttons">
            <el-button
              link
              type="primary"
              @click="openAuditDialog(scope.row.id)"
              v-if="scope.row.appointmentStatus === '待码头确认'"
              v-hasPermi="['dangerous:appointment-commission:audit']"
            >
              审核
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <Pagination
      :total="total"
      v-model:page="queryParams.pageNo"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
    <!-- 审核对话框 -->
    <AuditDialog v-model:modelValue="isAuditDialogVisible" @confirm="handleAudit" />
  </ContentWrap>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import AuditDialog from './AuditDialog.vue'; // 导入自定义对话框组件
import AppointmentCommissionApi from './api'; // 假设你有一个 API 模块
import { getList } from './utils'; // 假设你有一个获取列表的工具函数

const loading = ref(false);
const list = ref([]);
const total = ref(0);
const queryParams = ref({
  pageNo: 1,
  pageSize: 10
});
const isAuditDialogVisible = ref(false);
const currentAuditId = ref(null);

const openAuditDialog = (id) => {
  currentAuditId.value = id;
  isAuditDialogVisible.value = true;
};

const handleAudit = async (result) => {
  try {
    const response = await AppointmentCommissionApi.auditAppointmentCommission(currentAuditId.value, result === '通过');
    if (response === true) {
      ElMessage.success('审批成功');
      await getList(); // 成功后刷新列表
    } else {
      ElMessage.error('审批失败'); // 处理失败情况
    }
  } catch (error) {
    ElMessage.error('审批操作失败'); // 处理任何错误
  } finally {
    isAuditDialogVisible.value = false; // 关闭对话框
  }
};

// 模拟获取列表数据
const getList = async () => {
  loading.value = true;
  // 模拟异步请求
  setTimeout(() => {
    list.value = [
      { id: 1, appointmentId: 'A123', appointmentStatus: '待码头确认' },
      { id: 2, appointmentId: 'A456', appointmentStatus: '已确认' },
      // 添加更多数据
    ];
    total.value = list.value.length;
    loading.value = false;
  }, 1000);
};

getList();
</script>

<style scoped>
.table-title {
  margin: 20px 0;
}
.action-buttons {
  display: flex;
  justify-content: center;
  gap: 10px;
}
</style>

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

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

相关文章

了解 ZooKeeper:关键概念和架构

ZooKeeper 是一种分布式协调服务&#xff0c;广泛用于分布式系统中&#xff0c;用于维护配置信息、命名、同步和组服务。它最初由雅虎开发&#xff0c;现在是一个 Apache 项目&#xff0c;已成为许多大型分布式应用程序不可或缺的一部分。本文深入探讨 ZooKeeper 的关键概念和架…

(四)Appdesigner-文件存在判断及对话框设计

目录 前言 一、文件存在判断 &#xff08;一&#xff09;基础知识 &#xff08;二&#xff09;实际操作 二、对话框设计 &#xff08;一&#xff09;基础知识 1.提示对话框 2.询问对话框 3.文件选择对话框 &#xff08;二&#xff09;实际操作 1.提示对话框 2.询问…

考研生活day1--王道课后习题2.2.1、2.2.2、2.2.3

2.2.1 题目描述&#xff1a; 解题思路&#xff1a; 这是最基础的操作&#xff0c;思路大家应该都有&#xff0c;缺少的应该是如何下笔&#xff0c;很多同学都是有思路但是不知道如何下笔&#xff0c;这时候看思路的意义不大&#xff0c;可以直接看答案怎么写&#xff0c;最好…

关于内存和外存文件不同字符集下占用空间大小问题

关于内存和外存不同字符集下文件占用空间大小问题 存储&#xff08;外存&#xff09;的文件中的字符&#xff1a; ASCII&#xff1a;每个字符占用1个字节&#xff0c;用来存储英文字符和常用标点符号。ISO-8859-1&#xff1a;每个字符占用1个字节&#xff0c;向下兼容ASCII。G…

【代码随想录】【算法训练营】【第53天】 [739]每日温度 [496]下一个更大元素I [503]下一个更大元素II

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 48&#xff0c;周六&#xff0c;不能再坚持~ 题目详情 [739] 每日温度 题目描述 739 每日温度 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 [496] 下一…

【一篇搞懂】操作系统期末大题:进程同步与互斥 PV操作

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️题型一&#xff1a;利用信号量实现前驱关系题型二&#xff1a;利用信号量实现资源同步与互斥 一、前言&#x1f680;&#x1f680;&#x1f680; 本文简介&#xff1a;这是一篇基于b…

Pycharm常用快捷键整理

1&#xff0c;格式化代码 【ctrlAltL】 写代码的时候会发现有很多黄色的波浪号&#xff0c;这个时候可以点击任意黄色波浪号的代码&#xff0c;然后按下【Ctrl Alt L】进行代码格式化 2&#xff0c;快速往返 ctrll Alt ⬅ &#xff0c;表示查看上一步调用函数位置&#xff0…

Redis 7.x 系列【9】数据类型之自动排重集合(Set)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 前言2. 常用命令2.1 SADD2.2 SCARD2.3 SISMEMBER2.4 SREM2.5 SSCAN2.6 SDIFF2.7 SU…

华为OD机试 - 启动多任务排序 - 拓扑排序(Java 2024 D卷 200分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

如何做好一个企业家IP:塑造独特的个人品牌

在当今数字化时代&#xff0c;个人品牌的力量愈发凸显&#xff0c;对于企业家而言&#xff0c;一个强大的IP&#xff08;Intellectual Property&#xff0c;即知识产权或个人品牌&#xff09;不仅有助于提升个人影响力&#xff0c;还能为企业的发展注入强大动力。那么&#xff…

BGE M3-Embedding 模型介绍

BGE M3-Embedding来自BAAI和中国科学技术大学&#xff0c;是BAAI开源的模型。相关论文在https://arxiv.org/abs/2402.03216&#xff0c;论文提出了一种新的embedding模型&#xff0c;称为M3-Embedding&#xff0c;它在多语言性&#xff08;Multi-Linguality&#xff09;、多功能…

Feign 原理流程图练习-01

目录 作业: 老师给的参考流程图 要求 解答 知识扩展 Feign基础原理 接口定义 代理对象生成 请求调用 请求发送 响应处理 容错与熔断 总结 作业: 老师给的参考流程图 pdf版本 【金山文档 | WPS云文档】 Feign https://kdocs.cn/l/ctbagIyxN348 ​ 要求 结合上面…

[C++][设计模式][状态模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受1.代码一2.代码二 1.动机 在软件构建过程中&#xff0c;某些对象的状态如果改变&#xff0c;其行为也会随之而放生变化 比如文档处于只读状态&#xff0c;其支持的行为和读写状态支持的行为就可能完全不同 如何在运行时根据对象的状…

STM32 SWD烧写

最小电路 stm32f103x 内部已经集成了振荡电路&#xff0c;可以省略&#xff1b;rst引脚电路&#xff0c;可以省略&#xff0c;boot0,boot1不需要设置 正常烧录 -------------------------------------------------------------------STM32CubeProgrammer v2.9.0 …

antd Select前端加模糊搜索

背景&#xff1a;前端的小伙伴经常在开发antd Select的时候后端不提供搜索模糊搜索接口&#xff0c;而是全量返回数据&#xff0c;这个时候就需要我们前端自己来写一个模糊搜索了。 效果 代码截图 代码 <SelectshowSearchmode"multiple"options{studioList}filte…

读AI新生:破解人机共存密码笔记17不确定性和概率

1. 前向搜索 1.1. 通过前向搜索&#xff0c;通过考虑各种可能的动作序列的结果&#xff0c;来选择动作&#xff0c;是智能系统的基本能力 1.2. 如果一家卡车运输公司想要优化其100辆卡车在美国的运输&#xff0c;那么该公司可能需要考虑的状态数量将是10^700个 1.3. 几乎所有…

leetcode 第133场双周赛 100333.统计逆序对的数目【计数dp/滚动数组/前缀和优化】

分析&#xff1a; 先考虑如下问题。 求长度为n&#xff0c;逆序对为m的排列数量。 可以考虑dp&#xff0c;dp[i][j]定义为长度为i&#xff0c;逆序对为j的排列数量。 dp[1][0] 1; //枚举排列长度&#xff0c;或者认为枚举当前需要插到长度为i-1的排列中的数字 for(int i 1…

Mini-Contract电子合同在线签署小程序源码

Mini-Contract电子合同在线签署小程序源码&#xff0c;采用的是uniapp Vue3框架搭建&#xff0c;只有前端源码是一个聚合市场上各类电子合同解决方案商的工具&#xff0c;让用户无需一个个对接电子合同厂商&#xff0c;节省时间和精力。该程序提供了简洁的代码和最新的技术栈&a…

C++ | Leetcode C++题解之第208题实现Trie(前缀树)

题目&#xff1a; 题解&#xff1a; class Trie { private:vector<Trie*> children;bool isEnd;Trie* searchPrefix(string prefix) {Trie* node this;for (char ch : prefix) {ch - a;if (node->children[ch] nullptr) {return nullptr;}node node->children[…

现代信息检索笔记(二)

目录 信息检索概述 IR vs数据库: 结构化vs 非结构化数据 结构化数据 非结构化数据 半结构化数据 传统信息检索VS现代信息检索 布尔检索 倒排索引 一个例子 建立词项&#xff08;可以是字、词、短语、一句话&#xff09;-文档的关联矩阵。 关联向量 检索效果的评价 …