【Vue2 + ElementUI】el-table中校验表单

一. 案例

  1. 校验金额
    阐述:校验输入的金额是否正确。如下所示,点击【编辑图标】会变为input输入框当,输入金额。当输入框失去焦点时,若正确则调用接口更新金额且变为不可输入状态,否则返回不合法金额提示
    在这里插入图片描述
<template><el-table v-loading="tableLoading" :data="dataList" row-key="id" @cell-click="cellClick" :row-class-name="tableRowClassName" :cell-class-name="tableCellClassName"><el-table-column show-overflow-tooltip label="额度(元)"><template slot-scope="scope"><el-tooltip effect="dark" :content="scope.row.amt > 0 ? `已设置无法更改` : `点击输入金额`" placement="top"><div v-if="scope.row.index === rowIndex && scope.column.index === columnIndex"><el-input ref='editInput' v-model="scope.row.amt" @blur="inputBlur(scope.row)" size="mini" placeholder="输入额度" clearable></el-input></div><div v-else><span> {{ scope.row.amt| parseFormatNum }}</span><span v-show="scope.row.amt== 0"><i style="color:#409eff" class="el-icon-edit"></i></span></div><el-tooltip></template></el-table-column></el-table>
</template><script>
// 此处引入金额转换后的格式,引入的js文件放于文末
import { parseFormatNum } from "@/utils/index";
// 此处引入接口,更新对应金额
import {updateAmt} from "@api/xxx"export default {data() {return {rowIndex: -1, // 行索引columnIndex: -1, // 列索引 tableLoading:false, dataList:[],  query:{pageSize:10,pageNum:1},totalSize:0,validAmt:null, // 校验金额:符合 true ; 不符合 false}},mounted() {this.fetchData()},filters: {parseFormatNum(number) {return parseFormatNum(number);},},methods: {/***初始化列表数据/fetchData(){this.tableLoading = truegetList(this.query).then(res=>{this.tableLoading = falsethis.dataList = res.data.listthis.totalSize = res.data.total})},/*** 把每一行的索引加到行数据中*/tableRowClassName({ row, rowIndex }) {row.index = rowIndex},/*** 把每一列的索引加到列数据中*/tableCellClassName({ column, columnIndex }) {column.index = columnIndex},/*** 单元格被点击时会触发该事件*/cellClick(row, column) {if (column.label == '额度(元)' && row.cancelVerificationLimit == 0) {this.rowIndex = row.indexthis.columnIndex = column.indexthis.$nextTick(() => {this.$refs['editInput'].focus()//没有自动聚焦效果的话可能是这里出现问题 需要打印出来看一下})}},/*** 修改供应商免核销额度并校验金额*/inputBlur(row) {const reg = /^[0-9,"."]{1,20}$/this.validAmt = reg.test(row.cancelVerificationLimit)if (this.validAmt && row.cancelVerificationLimit > 0) {// 传一个主键id以及输入额度即可updateAmt(row.id, row.amt).then(res => {if (res.success) {this.$notify.success({title: this.$t("message.success"),message: res.message});this.rowIndex = -1this.columnIndex = -1this.validAmt = false}})} else {this.validAmt = falserow.amt = 0this.$message.error("请输入正确格式的金额")return}},},}
</script>
  1. 校验时间
    阐述:选择的时间是否小于当前时间,若是则选择后立即禁用
    在这里插入图片描述
<template><table v-loading="tableLoading" :data="dataList" row-key="id" ><el-table-column align="left" prop="time" label="时间"><template #default="{ row }"><el-tooltip class="item" effect="dark" :content="fittleTime(row.time)? `已经启用 无法更改`: `点击修改`" placement="top"><el-date-picker v-model="row.time" @change="updateTime(row)":disabled="fittleTime(row.time)" :picker-options="pickerOptions" value-format="yyyy-MM-dd"size="mini" style="width: 150px" type="date" placeholder="选择日期时间"></el-date-picker></el-tooltip></template></el-table-column></table>
</template><script>
// 引入对应接口
import {updateTime} from "@/api/xxx"
export default{data(){return{tableLoading:false,dataList:[],query:{pageSize:10,pageNum:1},pickerOptions: {disabledDate(time) {return time.getTime() < Date.now();}},}},mounted() {this.fetchData()},methods: {/***初始化列表数据/fetchData(){this.tableLoading = truegetList(this.query).then(res=>{this.tableLoading = falsethis.dataList = res.data.listthis.totalSize = res.data.total})},/*** 判断是否禁用虚拟记账薄启用时间* @param {Date} time */fittleTime(time) {if (time != null) {let dbTime = new Date(time);let nowTime = new Date();return dbTime <= nowTime;}},/*** 修改供应商虚拟机账簿启用时间*/updateTime(row) {if (!row.time) return this.$message.error("请选择启用时间");updateTime(row.id, row.time).then(res => {this.$message({type: res.code == 200 ? "success" : "error",message: res.message});});},}
}
</script>
  1. 校验不同层级所输入的内容
    阐述:当一级下 无 二级子目录时就可直接添加表,若有允许先添加材料,再通过二级子目录添加表
    在这里插入图片描述
<template><el-card>// 表头<el-row class="catelog-header" :gutter="20" :span="24"><el-col v-for="item in catelogHeaderList" :key="item.id" class="catelog-sub-header" :span="item.span">{{ item.title }}</el-col></el-row><!--表单校验--><el-row style="margin-left: -10px; margin-right: -10px"><el-formref="catelogSettingForm"class="descriptions-form"inline-message:model="catelogUserForm":rules="catalogCollectionRules"><!-- 一级目录 --><el-rowv-for="(item, index) in catelogUserForm.catelogSysList":key="item.id"class="catelog-form-border"><el-row class="catelog-align catelog-border"><el-col :span="1" style="margin-left: 10px">{{ (index + 1) | numberFilter }}</el-col><el-col class="catelog-item-font" :span="7">{{ item.catamanageName }}// 判断是否添加材料(如图所示的 +)<el-buttonv-show="(item.code == 'ARCHIVE_PERSON' &&item.children.length == 0) ||(item.children.length > 0 &&item.children[0].code == 'ARCHIVE_TABLE')"size="mini"style="margin-left: 10px"type="text"@click="handleAddCatelogUser(item)"><vab-iconicon="add-circle-fill"style="font-size: 18px !important"/></el-button></el-col></el-row><!-- 二级目录 --><vab-draggable:data-id="`${item.id}`"v-bind="dragOptions":disabled="disabledDrag":group="{put: false,}":list="item.children"@end="onEnd"><el-rowv-for="(childrenItem, childrenIndex) in item.children":key="childrenIndex"class="children-item"><el-rowv-if="childrenItem.code == 'ARCHIVE_PERSON'"class="catelog-align":gutter="30"><el-col:span="1"style="font-size: xx-small; margin-left: 10px"><div v-if="childrenItem.code == 'ARCHIVE_PERSON'">{{ index + 1 }} - {{ childrenIndex + 1 }}</div><div v-else>{{ childrenIndex + 1 }}</div></el-col><el-col class="catelog-table-border" :span="7"><el-form-item>{{ childrenItem.catamanageName }}<el-buttonsize="mini"style="margin-left: 10px"type="text"@click="handleAddCatelogUser(childrenItem)"><vab-iconicon="add-circle-fill"style="font-size: 18px !important"/></el-button></el-form-item></el-col></el-row><div v-else style="cursor: move"><el-row class="catelog-align" :gutter="30"><el-col:span="1"style="font-size: xx-small; margin-left: 10px"><div v-if="childrenItem.code == 'ARCHIVE_PERSON'">{{ index + 1 }} - {{ childrenIndex + 1 }}</div><div v-else>{{ childrenIndex + 1 }}</div></el-col><el-col class="catelog-table-border" :span="5"><el-form-item>{{ childrenItem.name }}</el-form-item></el-col><el-col :span="5"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].catamanageName`":rules="{required: true,message: '材料名称不能为空',trigger: 'change',}"><el-inputv-model="childrenItem.catamanageName"clearableplaceholder="请输入材料名称"/></el-form-item></el-col><el-col :span="3"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].treeFormationTime`":rules="{required: true,message: '请使用 - 分割年月日分',pattern:/(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]$)/,trigger: 'change',}"><el-inputv-model="childrenItem.treeFormationTime"clearableplaceholder="示例:2023-01-01"/></el-form-item></el-col><el-col :span="2"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].pagesNum`":rules="[{required: true,message: '页数不能为空',pattern: /^[1-9]\d*$/,trigger: 'change',},]"><el-inputv-model="childrenItem.pagesNum"clearableplaceholder="页数"/></el-form-item></el-col><el-col :span="6"><el-form-item><el-inputv-model="childrenItem.remark"clearableplaceholder="请输入备注"/></el-form-item></el-col><el-col :span="2" style="text-align: center"><el-form-item><el-buttonicon="el-icon-view"type="text"@click="handleDelete(index,childrenItem,childrenIndex,'del')">删除</el-button></el-form-item></el-col></el-row></div><!-- 三级目录 --><vab-draggablev-bind="dragOptions":data-id="`${childrenItem.id + '-' + childrenItem.parentId}`":list="childrenItem.children"@end="onEnd"><el-rowv-for="(innerItem, innerIndex) in childrenItem.children":key="innerItem.id"class="catelog-align":gutter="30"style="cursor: move; border-top: 1px solid #8eaac6"><el-col:span="1"style="font-size: xx-small; margin-left: 10px"><div>{{ innerIndex + 1 }}</div></el-col><el-col:span="5"style="border-left: 1px solid #8eaac6;padding-left: 10px !important;"><el-form-item style="padding-left: 10px !important">{{ innerItem.name }}</el-form-item></el-col><el-col :span="5"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].catamanageName`":rules="{required: true,message: '材料名称不能为空',trigger: 'change',}"><el-inputv-model="innerItem.catamanageName"clearableplaceholder="请输入材料名称"/></el-form-item></el-col><el-col :span="3"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].treeFormationTime`":rules="{required: true,message: '请使用 - 将年月日分割',pattern:/(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]$)/,trigger: 'change',}"><el-inputv-model="innerItem.treeFormationTime"clearableplaceholder="示例:2023-01-01"/></el-form-item></el-col><el-col :span="2"><el-form-item:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].pagesNum`":rules="[{required: true,message: '页数不能为空',pattern: /^[1-9]\d*$/,trigger: 'change',},]"><el-inputv-model="innerItem.pagesNum"clearableplaceholder="页数"/></el-form-item></el-col><el-col :span="6"><el-form-item><el-inputv-model="innerItem.remark"clearableplaceholder="请输入备注"/></el-form-item></el-col><el-col :span="2" style="text-align: center"><el-form-item><el-buttonicon="el-icon-view"type="text"@click="handleDelete(index,innerItem,childrenIndex,innerIndex)">删除</el-button></el-form-item></el-col></el-row></vab-draggable></el-row></vab-draggable></el-row></el-form></el-row><ArchiveCatelogUserTable  ref="catelogUser"/></el-card>
</template>
<script>
// 引入将阿拉伯数字转为中文的js文件import { numberToChinese } from '@/utils/index'// 允许同级目录进行拖拽排序import VabDraggable from 'vuedraggable'// 将拖拽后的排序重新更新// 删除import {updateSortById,remove} from "@/api/xxx"export default{props: {archiveId: {type: String,default: '',require: true,},},filters: {numberFilter(num) {return numberToChinese(num)},},components: {VabDraggable,},computed: {dragOptions() {return {animation: 600,group: 'description',}},},data(){return{catelogHeaderList: [{ id: 1, title: '类号', span: 1 },{ id: 2, title: '类别名称', span: 5 },{ id: 3, title: '材料', span: 5 },{ id: 4, title: '材料形成时间 年 月 日', span: 3 },{ id: 5, title: '页数', span: 2 },{ id: 6, title: '备注', span: 6 },{ id: 7, title: '操作', span: 2 },],catelogUserForm: {catelogSysList: [],},catalogCollectionRules: {},catelogSysLoading:false, disabledDrag: false, // 是否禁止同级拖拽}},mounted(){this.fetchData()},methods:{/*** 获取catelogUser一级目录列表*/fetchData() {this.catelogSysLoading = truegetMenyByArchiveId(this.archiveId).then((res) => {this.catelogUserForm.catelogSysList = res.datathis.list = JSON.parse(JSON.stringify(res.data))this.catelogSysLoading = false})},/*** 打开添加材料对话框,添加材料(此功能不详细赘述)*/handleAddCatelogUser(item) {// this.$refs.catelogUser.showDetailDialog(item.id,item.catelogSysId,item.catamanageName)},/*** 拖拽排序* @param {Object} event*/onEnd(evt) {//父级idlet parentId = evt.from.dataset.id//找到父级所在的索引let parentIi = this.catelogUserForm.catelogSysList.findIndex((e) => e.id == parentId)//父级let nowList = this.catelogUserForm.catelogSysList[parentIi]let buhui = this.list[parentIi]//当前拖动对象// debuggerlet nowItemId = evt.item._underlying_vm_.idlet nowIndex = nowList.children.findIndex((e) => e.id == nowItemId)let flag = nowList.children[nowIndex].id == buhui.children[nowIndex].idnowList.children.forEach((e, i) => {e.sort = i + 1})if (!flag) {updateSortById(nowList.children).then((res) => {this.$baseMessage(res.msg, 'success')this.fetchData()})}},/*** 删除:保存/未保存到数据库()*/handleDelete(parentIndex, item, index, flag) {if (item.id != null) {this.$baseConfirm('您确定要删除当前项吗?', null, async () => {const { msg } = await remove(item.id)this.$baseMessage(msg, 'success')await this.fetchData()})} else {if (flag == 'del') {this.catelogUserForm.catelogSysList.map((e) => {if (e.id == item.parentId) {this.catelogUserForm.catelogSysList[parentIndex].children.splice(index, 1)}})} else {this.catelogUserForm.catelogSysList.map((e) => {e.children.map((r) => {if (r.id == item.parentId) {this.catelogUserForm.catelogSysList[parentIndex].children[index].children.splice(flag, 1)}})})}}},}}
</script>

数据格式如下
在这里插入图片描述

二. 引入文件

  1. 保留两位小数并且整数部分三位一个逗号分隔符的数字金钱标准表示法
export function parseFormatNum(number) {let n = 2;if (n != 0) {n = n > 0 && n <= 20 ? n : 2;}if (number == null) number = 0;number = parseFloat((number + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";const sub_val = number.split(".")[0].split("").reverse();const sub_xs = number.split(".")[1];let show_html = "";for (let m = 0; m < sub_val.length; m++) {show_html +=sub_val[m] + ((m + 1) % 3 == 0 && m + 1 != sub_val.length ? "," : "");}if (n == 0) {return show_html.split("").reverse().join("");} else {return (show_html.split("").reverse().join("") +"." +sub_xs);}
}
  1. 阿拉伯数字转为汉字
export const numberToChinese = (num) => {const changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] // changeNum[0] = "零"const unit = ['', '十', '百']num = parseInt(num)const getWan = (temp) => {const strArr = temp.toString().split('').reverse()let newNum = ''for (var i = 0; i < strArr.length; i++) {newNum =(i == 0 && strArr[i] == 0? '': i > 0 && strArr[i] == 0 && strArr[i - 1] == 0? '': changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) +newNum}return newNum}const overWan = Math.floor(num / 100)let noWan = num % 100if (noWan.toString().length < 2) {noWan = '0' + noWan}let strr = overWan ? getWan(overWan) + '百' + getWan(noWan) : getWan(num)if (strr.split('')[0] == '一') {if (num < 10) {return strr.substring(0)} else {return strr.substring(1)}} else {return overWan ? getWan(overWan) + '百' + getWan(noWan) : getWan(num)}
}

三. 参考

  1. element+vue表格点击变成输入框并获取焦点(可编辑状态)
  2. el-table内表单校验

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python pycharm编辑器修改代码字体

在pycharm编辑器下修改代码字体&#xff0c;可以按照以下步骤&#xff1a; 点开上图所示的菜单&#xff0c; 再点击File->Settings&#xff0c;进入设置页面。 我们找到Editor下的Font并点选&#xff0c;然后我们就可以在右侧修改字体相关配置了。 这里建议使用等宽字体&…

SparkStreaming与Kafka整合

1.3 SparkStreaming与Kafka整合 1.3.1 整合简述 kafka是做消息的缓存&#xff0c;数据和业务隔离操作的消息队列&#xff0c;而sparkstreaming是一款准实时流式计算框架&#xff0c;所以二者的整合&#xff0c;是大势所趋。 ​ 二者的整合&#xff0c;有主要的两大版本。 kaf…

webpack的深入学习与实战(持续更新)

一、何为Webpack Webpack是 一个开源的JavaScript模块打包工具&#xff0c;其最核心的功能是解决模块之间的依赖&#xff0c;把各个模块按照特定的规则和顺序组织在一起&#xff0c;最终合并为一个JS文件或多个。 二、带宽的换算 目前我们的云服务器带宽为5M 三 、bundle 体…

二叉树题目:根到叶路径上的不足结点

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;根到叶路径上的不足结点 出处&#xff1a;1080. 根到叶路径上的不足结点 难度 6 级 题目描述 要求 给定二叉树的根结点 root \texttt{root} root…

maven中dependencyManagement标签

简介 dependencyManagement正如其名&#xff0c;用于项目依赖的统一管理。 在父项目中的pom.xml文件中加入dependencyManagement标签即可完成依赖版本的声明。在声明完成后&#xff0c;子项目&#xff08;module&#xff09;中引用相同的依赖时可以不指定version标签自动引入…

【python报错】UserWarning: train_labels has been renamed targets

UserWarning: train_labels has been renamed targetswarnings.warn(“train_labels has been renamed targets”) 这是一条 Python 警告信息&#xff0c;它表示 train_labels 这个变量已经被重命名为 targets&#xff0c;在将来的版本中可能会移除 train_labels。因此&#x…

51蛋骗鸡595级联1616点阵

缘由如何用单片机独立按键控制16*16LED点阵模块点亮和熄灭?求指导 - 24小时必答区 #include "reg52.h" unsigned char code DuLiAnJian[]{1,2,4,8,16,32,64,128,254,253,251,247,239,223,191,127}; unsigned char code CHARCODE[12][8]{ //{0xFD,0xFD,0x0D,0xED,0x…

如何开发一个google插件(二)

前言 在上一篇文章如何开发一个google插件(一)里主要介绍了google插件的基本结构。 在这篇文章中主要结合reactwebpack进行一个代码演示&#xff0c;源码地址&#xff1a;源码地址 下载源码后打开浏览器的扩展程序管理->加载已解压的扩展程序&#xff0c;即可调试插件 此…

在 Spring 中操作 Redis

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc;redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿 目录 1、引入依赖 2、对 Redis 的配置文件进行书写 3、S…

Python机器学习原理与算法实现中绘制散点图和线图的操作

作为对数据进行预处理的重要工具之一&#xff0c;散点图&#xff08;Scatter Diagram&#xff09;深受专家、学者们的喜爱。散点图的简要定义就是点在直角坐标系平面上的分布图。研究者对数据制作散点图的主要出发点是通过绘制该图来观察某变量随另一变量变化的大致趋势&#x…

小米SU7汽车发布会; 齐碳科技C+轮融资;网易 1 月 3 日发布子曰教育大模型;百度文心一言用户数已突破 1 亿

投融资 • 3200 家 VC 投资的创业公司破产&#xff0c;那个投 PLG 的 VC 宣布暂停投资了• 云天励飞参与 AI 技术与解决方案提供商智慧互通 Pre-IPO 轮融资• 百度投资 AIGC 公司必优科技• MicroLED量测公司点莘技术获数千万级融资• 智慧互通获AI上市公司云天励飞Pre-IPO轮战…

门控循环单元(GRU)-多输入回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、全部代码数据分享&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译…

十大排序算法归纳

目录 排序算法的分类 插入排序算法模板 选择排序算法模板 冒泡排序算法模板 希尔排序算法模板 快速排序算法模板 归并排序算法模板 堆排序算法模板 基数排序算法模板 计算排序算法模板 桶排序算法模板 排序算法的分类 插入&#xff1a;插入&#xff0c;折半插入&am…

网站显示不安全警告怎么办?消除网站不安全警告超全指南

网站显示不安全警告怎么办&#xff1f;当用户访问你的网站&#xff0c;而您的网站没有部署SSL证书实现HTTPS加密时&#xff0c;网站就会显示不安全警告&#xff0c;这种警告&#xff0c;不仅有可能阻止用户继续浏览网站&#xff0c;影响网站声誉&#xff0c;还有可能影响网站在…

基于蜉蝣算法优化的Elman神经网络数据预测 - 附代码

基于蜉蝣算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于蜉蝣算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于蜉蝣优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针…

操作系统(Operator System)

这里写目录标题 1. 什么是操作系统2. 主要功能3. 计算机的层状结构4. 什么叫做管理5. 总结6. 为什么要有操作系统7. 最后 1. 什么是操作系统 操作系统&#xff08;英语&#xff1a;Operating System&#xff0c;缩写&#xff1a;OS&#xff09;是一组主管并控制计算机操作、运…

彭涛:2023年终复盘,工作,团队,个人!

眨眼2023即将结束&#xff0c;2024即将开启&#xff0c;每年这个时候&#xff0c;都会简单总结下自己这一年&#xff0c;既是对今年的一个复盘和回顾&#xff0c;也是对新一年的向往和期待。 我的2023年&#xff0c;大概分为 「个人」&#xff0c;「家庭」&#xff0c;「团队」…

C语言实现RSA算法加解密

使用c语言实现了RSA加解密算法&#xff0c;可以加解密文件和字符串。 rsa算法原理 选择两个大素数p和q&#xff1b;计算n p * q;计算φ(n)(p-1)(q-1)&#xff1b;选择与φ(n)互素的整数d&#xff1b;由de1 mod φ(n)计算得到e&#xff1b;公钥是(e, n), 私钥是(d, n);假设明…

设计模式(4)--对象行为(11)--访问者

1. 意图 表示一个作用于某对象结构中的各元素的操作。 使你可以在不改变各元素的类的前提下定义于作用于这些元素的新操作。 2. 五种角色 抽象访问者(Visitor)、具体访问者(Concrete Visitor)、抽象元素(Element)、 具体元素(Concrete Element)、对象结构(ObjectStructure) 3…

12 HAL库的硬件SPI驱动数码管

引言&#xff1a; 本文将为大家介绍一下SPI&#xff0c; 数码管的知识&#xff0c; 以及HAL库驱动SPI接口的数码的代码示例。 一、SPI的基础知识 1. SPI简介 01 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写 02 是美国摩托罗拉公司&#xff08…