Vue3 + TS + Element-Plus —— 项目系统中封装表格+搜索表单 十分钟写五个UI不在是问题

9a69fede8b2044a79dd834e3e48f20b4.png前期回顾f8e3cc1a0f694ac2b665ca2ad14c49d7.png

纯前端 —— 200行JS代码、实现导出Excel、支持DIY样式,纵横合并-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_57904695/article/details/135537511?spm=1001.2014.3001.5501 

目录

一、🛠️  newTable.vue 封装Table

二、🚩 newForm.vue 封装搜索表单 

三、📝 TS类型 src\types\global.d.ts

四、♻️ 页面使用功能 - 静态 

 五、♻️ 页面使用功能 - 动态 

 六、🤖 仓库地址、演示地址

七、📝 结语 


 

在平时开发中,系统中写的最多的 表格+搜索表单排名No.1,每一次都在Element-Plus中 拷贝一遍 <template> ,显然是个大活,我们将其html封装,每一只写Data数据让其动态渲染,编写速度达达滴!

一、🛠️  newTable.vue 封装Table

<template><div class="container"><div class="container-main"><!-- 表单搜索区域 --><el-scrollbar v-if="isShowSearchRegion" max-height="300px" class="scrollbar-height"><slot name="search"></slot></el-scrollbar><!-- 表格上方搜索向下方按钮区域 --><slot name="btn"></slot><!-- 列表区域 --><el-tableref="multipleTableRef"v-bind="$attrs"stripestyle="width: 100%":data="filterTableData":border="tableBorder":height="tableHeight || excludeSearchAreaAfterTableHeight":row-key="getRowKeys"@selection-change="onSelectionChange"><template #empty><el-empty :image-size="emptyImgSize" description="暂无数据" /></template><el-table-columntype="selection"width="30"v-if="isSelection":reserve-selection="true":selectable="selectableCallback"/><el-table-columntype="index"label="序号"min-width="60":index="orderHandler"align="center"/><el-table-columnv-for="item in tableHeader"v-bind="item":key="item.prop"header-align="center"align="center"><template #header v-if="item.slotKey?.includes('tableHeaderSearch')"><el-inputv-model.trim="search"size="small":placeholder="getSearchInfo.label"/></template><template #default="{ row }" v-if="item.slotKey"><slotv-for="slot in item.slotKey.split(',')":name="slot":row="row"></slot><template v-if="item.slotKey.includes('default')"><el-link type="primary" :underline="false" @click="handleEdit(row)">编辑</el-link><el-popconfirm title="确定删除吗?" @confirm="handleDelete(row.id)"><template #reference><el-link type="danger" :underline="false">删除</el-link></template></el-popconfirm></template></template></el-table-column></el-table><!-- 分页区域--><el-paginationv-if="paginationFlag"background:page-sizes="pageSizesArr":current-page="pageNum":page-size="pageSize":layout="layout":total="total"popper-class="pagination-popper"@size-change="handleSizeChange"@current-change="handleCurrentChange"></el-pagination></div></div>
</template><script setup lang="ts">
import { onMounted, ref, watch, toRaw, nextTick, computed } from 'vue';
import { ElTable } from 'element-plus';
const multipleTableRef = ref<InstanceType<typeof ElTable>>();import myEmits from './newTableConfig/emits';
import myProps from './newTableConfig/props';
const emits = defineEmits(myEmits);
const props = defineProps(myProps);
const search = ref('');// 搜索过滤
const filterTableData = computed(() =>props.tableData?.filter((data) =>!search.value ||String(data[getSearchInfo.value.prop]).toLowerCase().includes(search.value.toLowerCase()))
);
// 计算那列用于展示搜索
const getSearchInfo = computed(() => {let searchInfo = { label: '', prop: '' };props.tableHeader?.find((v) => {if (v.searchFields) {searchInfo = { label: v.label, prop: v.prop };return true;}});return searchInfo;
});// 序号根据数据长度计算
const orderHandler = (index: number) => {const { pageNum, pageSize } = props;// 第0条 * 每页条数 + 当前索引+1return (pageNum - 1) * pageSize + index + 1;
};//  页数改变
const handleSizeChange = (val: number | string) => emits('handleSizeChange', val);
// 当前页改变
const handleCurrentChange = (val: number | string) => emits('handleCurrentChange', val);// 编辑、删除
const handleEdit = (row: object) => emits('handleEdit', row);
const handleDelete = (id: number) => emits('handleDelete', id);
// 复选框
const onSelectionChange = (val: any) => emits('selection-table-change', val);//记录每行的key值
const getRowKeys = (row: any) => row.id;// 根据父组件传递的id字符串,默认选中对应行
const toggleSelection = (rows?: any) => {if (props.isSelection) {if (rows) {rows.forEach((row: any) => {const idsArr = props.selectionIds?.split(',');if (idsArr?.includes(row.id.toString())) {//重要nextTick(() => multipleTableRef.value?.toggleRowSelection(row, true));}});} else {multipleTableRef.value!.clearSelection();}}
};const selectableCallback = (row: any) => {const idsArr = props.selectionIds?.split(',');if (props.isDisableSelection && idsArr?.includes(row.id.toString())) {return false;}return true;
};
watch(() => props.tableData,(newV) => {if (!!props.selectionIds) {// console.log('🤺🤺  selectionIds🚀 ==>:', props.selectionIds);// console.log('🤺🤺  newV ==>:', newV);toggleSelection(toRaw(newV));}}
);// 搜索区域高度及默认值
const Height = ref();
// 减去搜索区域高度后的table,不能有默认值不然会出现滚动条
const excludeSearchAreaAfterTableHeight = ref();// 获取表格高度-动态计算搜索框高度(onMounted、resize,208是已知的面包屑tebView高度)
const updateHeight = () => {let wrapEl = document.querySelector('.scrollbar-height') as HTMLElement | null;if (!wrapEl) return;Height.value = wrapEl.getBoundingClientRect().height;// console.log('🤺🤺  🚀 ==>:', wrapEl.getBoundingClientRect());if (props.isShowSearchRegion) {excludeSearchAreaAfterTableHeight.value = `calc(100vh - ${200 + Height.value}px)`;}
};onMounted(() => {// 表格下拉动画const tableContainer = <HTMLElement>document.querySelector('.container');setTimeout(() => {if (tableContainer) tableContainer.style.transform = 'translateY(0)';updateHeight();}, 800);
});window.addEventListener('resize', updateHeight);
defineExpose({toggleSelection,
});
</script><style scoped lang="scss">
.container {overflow: hidden;width: 100%;height: 100%;padding: 15px;transform: translateY(-100%);transition: transform 0.4s ease-in-out;background-color: #f8f8f8;// background-color: #870404;&-main {overflow: hidden;position: relative;padding: 15px;width: 100%;// height: 100%; el-scrollbar有默认高度100%,当页面列表渲前会继承这里高度,导致搜索区域铺满全屏background-color: #fff;border: 1px solid #e6e6e6;border-radius: 5px;&:hover {box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);}transition: box-shadow 0.3s ease-in-out;.scrollbar-height {min-height: 100px;}.el-pagination {display: flex;align-items: center;justify-content: center;margin-top: 20px;}}
}
// 穿透父组件
:deep(.el-link) {padding-left: 10px;
}
</style>

二、🚩 newForm.vue 封装搜索表单 

<template><el-form ref="searchFormRef" :model="searchForm" size="default"><!-- 使用了不稳定的 key,可能会导致一些不可预期的行为,比如输入框失去焦点。 --><el-row><el-col:xs="24":sm="24":md="24":lg="12":xl="6"v-for="item in formOptions":key="item.vm"><el-form-item :label="item.props.label" :prop="item.vm"><el-inputv-if="item.type === FormOptionsType.INPUT"v-model.lazy.trim="searchForm[item.vm]"v-bind="item.props"class="ml10 w100"></el-input><el-selectv-if="item.type === FormOptionsType.SELECT"v-model.lazy="searchForm[item.vm]"v-bind="item.props"class="ml10 w100"fit-input-width><el-optionv-for="option in item.selectOptions":key="option.value":label="option.label":value="option.value"><zw-tooltip-omit :content="option.label"></zw-tooltip-omit></el-option></el-select><el-cascaderv-if="item.type === FormOptionsType.CASCADER"v-model.lazy="searchForm[item.vm]":options="item.cascaderOptions"v-bind="item.props"class="ml10 w100"/><el-date-pickerv-if="item.type === FormOptionsType.DATE_PICKER"v-model.lazy="searchForm[item.vm]"v-bind="item.props"class="ml10 w100"/></el-form-item></el-col><el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="6" class="xs-mt"><el-form-item style="margin-left: 10px"><el-button @click="onSearch('reset')"><SvgIcon name="ant-ReloadOutlined"></SvgIcon>重置</el-button><el-button type="primary" @click="onSearch()"><SvgIcon name="ant-SearchOutlined"></SvgIcon>查询</el-button></el-form-item></el-col></el-row></el-form>
</template><script setup lang="ts" name="newForm">
import { toRefs, onBeforeUnmount, ref } from 'vue';
import type { PropType } from 'vue';
import { type FormInstance } from 'element-plus';
import { debounce } from '/@/utils/debounce';
const searchFormRef = ref<FormInstance>();enum FormOptionsType {INPUT = 'input', // 输入框SELECT = 'select', // 下拉框CASCADER = 'cascader', // 级联选择器DATE_PICKER = 'date-picker', // 日期选择器
}const props = defineProps({formOptions: {type: Array as PropType<FormOptions[]>,required: true,},searchForm: {type: Object as PropType<SearchFormType>,required: true,},
});
const { formOptions, searchForm } = toRefs(props);const emit = defineEmits(['search']);
const debouncedEmitSearch = debounce((type) => emit('search', type));
const onSearch = (type: string) => {if (type) searchFormRef.value?.resetFields();debouncedEmitSearch(type);
};onBeforeUnmount(() => searchFormRef.value?.resetFields());
defineExpose({ searchFormRef });
</script><style scoped lang="scss">
:deep(.el-form-item__label) {margin-left: 10px;
}
</style><style scoped lang="scss">
:deep(.el-form-item__label) {margin-left: 10px;
}
</style>

三、📝 TS类型 src\types\global.d.ts


// new-table
//表头数据类型定义
declare interface TableHeader<T = any> {label: string;prop: string;align?: string;overHidden?: boolean;minWidth?: string;sortable?: boolean;type?: string;fixed?: string;width?: string | number;// isActionColumn?: boolean; // 是否是操作列// isCustomizeColumn?: boolean; // 是否是自定义列slotKey?: string; // 自定义列的插槽名称searchFields?: boolean; // 是否是搜索字段
}/*newForm允许任何字符串作为索引不然会报错, 使用动态属性名,需要使用索引签名
*/
declare type SearchFormType = {[key: string]: string;
};declare type FormOptions = {type: string;props: {label: string;placeholder: string;type: string;clearable: boolean;};vm: string;selectOptions?: {value: string | number;label: string;}[];cascaderOptions?: any;
};

四、♻️ 页面使用功能 - 静态 

<template><new-table:tableHeader="tableHeader":tableData="tableData":total="100"@handleSizeChange="onHandleSizeChange"@handleCurrentChange="onHandleCurrentChange"@handleDelete="onHandleDelete"@handleEdit="onHandleEdit"><template #search><el-row><el-col:xs="24":sm="24":md="24":lg="12":xl="6"v-for="item in Math.ceil(Math.random() * 10)":key="item"class="scrollbar-demo-item">56546</el-col><el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="6" class="xs-mt"><el-form-item><el-button> 重置 </el-button><el-button type="primary"> 查询 </el-button></el-form-item></el-col></el-row></template><template #switch="slotProps"><el-switchv-model="slotProps.row.status"active-text="开"inactive-text="关"active-color="#13ce66"inactive-color="#ff4949"@change="changeSwitchStatus(slotProps.row.id, slotProps.row.status)"/></template></new-table>
</template><script setup lang="ts" name="algorithmRegistrationQuery">
import { reactive, toRefs } from "vue";
const state = reactive({//表头数据tableHeader: <TableHeader[]>[{ label: "姓名", prop: "uname", width: "100px" },{ label: "年龄", prop: "age", slotKey: "switch" },{ label: "性别", prop: "sex" },{ label: "操作", width: "240px", fixed: "right", slotKey: "default" },],//表数据,从接口获取tableData: [{ uname: "小帅", age: "18", sex: "男", status: false, id: 1 },{ uname: "小美", age: "148", sex: "女", status: false, id: 2 },{ uname: "小明", age: "12", sex: "男", status: true, id: 3 },{ uname: "小红", age: "12", sex: "女", status: false, id: 4 },{ uname: "小黑", age: "12", sex: "男", status: true, id: 5 },{ uname: "小白", age: "12", sex: "女", status: false, id: 6 },{ uname: "小黑", age: "12", sex: "男", status: true, id: 7 },{ uname: "小白", age: "12", sex: "女", status: false, id: 8 },{ uname: "小黑", age: "12", sex: "男", status: true, id: 9 },{ uname: "小白", age: "12", sex: "女", status: false, id: 10 },{ uname: "小黑", age: "12", sex: "男", status: true, id: 11 },],
});
const { tableHeader, tableData } = toRefs(state);// 修改
const onHandleEdit = (row: object) => {console.log(row);
};// 删除
const onHandleDelete = (row: object) => {console.log(row);
};// switch
const changeSwitchStatus = (id: number, status: boolean) => {console.log(id, status);
};//分页改变
const onHandleSizeChange = (val: number) => {console.log("!这里输出 🚀 ==>:", val);
};
//分页改变
const onHandleCurrentChange = (val: number) => {console.log("!这里输出 🚀 ==>:", val);
};// //页容量改变
// const onHandleSizeChange = (val: number) => {
// 	// console.log('页容量 ==>:', val);
// 	pageSize.value = val;
// 	getTableList(pageNum.value, pageSize.value, tableId.value);
// };
// //当前分页改变
// const onHandleCurrentChange = (val: number) => {
// 	// console.log('当前页 🚀 ==>:', val);
// 	pageNum.value = val;
// 	getTableList(pageNum.value, pageSize.value, tableId.value);
// };
</script><style lang="scss" scoped>
.scrollbar-demo-item {display: flex;align-items: center;justify-content: center;height: 50px;margin: 10px;text-align: center;border-radius: 4px;background: var(--el-color-primary-light-9);color: var(--el-color-primary);
}
.xs-mt {display: flex;align-items: flex-end;
}
</style>

 五、♻️ 页面使用功能 - 动态 

<template><div class="container-wrapper"><!-- 动态 page --><new-tablev-bind="state":total="pageTotal"@handleSizeChange="onHandleSizeChange"@handleCurrentChange="onHandleCurrentChange"@handleEdit="onHandleEdit"@handleDelete="onHandleDelete"><template #search><new-form:formOptions="formOptions":searchForm="searchForm"					@search="onSearch"/></template><template #btn><el-button type="primary" size="default" class="btn-add"><SvgIcon name="ant-PlusOutlined"></SvgIcon>新建题目</el-button></template><template #switch="{ row }"><el-switchv-model="row.fileStatus"active-text="开"inactive-text="关":active-value="1":inactive-value="2"active-color="#13ce66"inactive-color="#ff4949"@change="changeSwitchStatus(row.id, row.fileStatus)"/></template></new-table></div>
</template><script setup lang="ts" name="algorithmRegistrationQuery">
import { onMounted, reactive, toRefs } from 'vue';
import { getTestList } from '/@/api/encryptionAlgorithm/templateDefinition';
import { STATUS_CODE } from '/@/enum/global';
const state = reactive({//表头数据// el-table-column有的属性都可以在这传/* searchFields:true 搜索字段slotKey: 'xxx' 自定义插槽 包含tableHeaderSearch则展示表格搜索框。包含default则展示 编辑删除其他值可以在父组件中使用插槽 template自定义内容#search 表单搜索#btn 列表上方的按钮*/tableHeader: <TableHeader[]>[{ label: '合规规则', prop: 'knowledgeName', searchFields: true },{ label: '文件数量', prop: 'documentNumber', width: '200px' },{ label: '文件状态', prop: 'fileStatus', slotKey: 'switch' },{ label: '操作', fixed: 'right', slotKey: 'default,tableHeaderSearch' , width: 200 },],//表项数据tableData: [],formOptions: <FormOptions[]>[{type: 'input',props: {label: '合规规则',placeholder: '请输入合规规则',type: 'text',clearable: true,},vm: 'knowledgeName',},{type: 'input',props: {label: '文件数量',placeholder: '请输入文件数量',type: 'text',clearable: true,},vm: 'documentNumber',},// 下拉选择器{type: 'select',props: {label: '所属部门',placeholder: '请选择',clearable: true,},vm: 'department',selectOptions: [{label: '数据安全',value: 1,},{label: '研发',value: 2,},{label: '事业',value: 3,},],},// 时间范围选择器{type: 'date-picker',props: {label: '时间范围',type: 'datetimerange', // datetimerange范围 datetime日期clearable: true,'range-separator': '-','start-placeholder': '开始日期','end-placeholder': '结束日期','value-format': 'YYYY-MM-DD HH:mm:ss',},vm: 'createTime',},// 级联选择器{type: 'cascader',props: {label: '所属部门',placeholder: '请选择',clearable: true,},vm: 'cascader',cascaderOptions: [{value: 'guide',label: 'Guide',children: [{value: 'disciplines',label: 'Disciplines',children: [{value: 'consistency',label: 'Consistency',},],},{value: 'navigation',label: 'Navigation',children: [{value: 'side nav',label: 'Side Navigation',},{value: 'top nav',label: 'Top Navigation',},],},],},{value: 'component',label: 'Component',children: [{value: 'basic',label: 'Basic',children: [{value: 'button',label: 'Button',},],},{value: 'form',label: 'Form',children: [{value: 'radio',label: 'Radio',},{value: 'checkbox',label: 'Checkbox',},],},{value: 'data',label: 'Data',children: [{value: 'table',label: 'Table',},],},{value: 'notice',label: 'Notice',children: [{value: 'alert',label: 'Alert',},],},{value: 'navigation',label: 'Navigation',children: [{value: 'menu',label: 'Menu',},],},{value: 'others',label: 'Others',children: [{value: 'dialog',label: 'Dialog',},],},],},{value: 'resource',label: 'Resource',children: [{value: 'axure',label: 'Axure Components',},],},],},],//这里允许动态属性所以可为空searchForm: <SearchFormType>{},pageNum: 1,pageSize: 10,pageTotal: 0,tableHeight: 'calc(100vh - 375px)', //如果开启#btn占位符需要手动设置表格高度
});
const { tableData, formOptions, searchForm, pageNum, pageSize, pageTotal } = toRefs(state);// 修改
const onHandleEdit = (row: object) => {console.log(row);
};// 删除
const onHandleDelete = (row: object) => {console.log(row);
};// switch
const changeSwitchStatus = (id: number, status: boolean) => {console.log(id, status);
};//页容量改变
const onHandleSizeChange = (val: number) => {// console.log('页容量 ==>:', val);pageSize.value = val;getTableList(pageNum.value, pageSize.value);
};
//当前分页改变
const onHandleCurrentChange = (val: number) => {// console.log('当前页 🚀 ==>:', val);pageNum.value = val;getTableList(pageNum.value, pageSize.value);
};// 获取表项数据
const getTableList = (pageNum: number, pageSize: number) => {// 处理searchForm.value createTime// if (searchForm.value.createTime) {// 	searchForm.value.startTime = searchForm.value.createTime[0];// 	searchForm.value.createTimeEnd = searchForm.value.createTime[1];// 	// delete searchForm.value.createTime;// }getTestList({pageNum,pageSize,...searchForm.value,}).then((res) => {if (res.code !== STATUS_CODE.SUCCESS) return;const { list, total } = res.data;tableData.value = list;// console.log('🤺🤺 表项 🚀 ==>:', list);pageTotal.value = total;});
};const onSearch = (isReset?: string) => {pageNum.value = isReset ? 1 : pageNum.value;getTableList(pageNum.value, pageSize.value);
};onMounted(() => getTableList(pageNum.value, pageSize.value));
</script><style scoped lang="scss">
.btn-add {float: right;margin-bottom: 20px;
}
</style>

 六、🤖 仓库地址、演示地址

仓库地址:

Vite + Ts + Vue3 - template -- 模板: 🎉🎉🔥 Vite + Vue3 + Ts + router + Vuex + axios + eslint 、prettier、stylelint、husky、gitCommit --- 集成多种组件、Hooks支持开封即用,严格的代码质量检验、祝您轻松上大分😷🤺🤺🤺 【动态路由、特效、N个组件、N个自定义指令...】 (gitee.com)

在线演示:

Vite + Vue + TS (gitee.io)

  

七、📝 结语 

封装其他组件在其余博文中也有详细描写,快来抱走把!

7730e2bd39d64179909767e1967da702.jpeg

 _______________________________  期待再见  _______________________________

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

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

相关文章

RK3399平台入门到精通系列讲解(基础篇)__LITTLE_ENDIAN_BITFIELD 宏的使用

🚀返回总目录 文章目录 一、什么是字节序二、小端模式(Little-Endian)三、大端模式(Big-Endian)四、__LITTLE_ENDIAN_BITFIELD 使用案例一、什么是字节序 在计算机中,数据是以最原始的二进制 0 和 1 的方式被存储的。在大多数现代计算机体系架构中,计算机的最小可寻址数…

UE5.1_UMG序列帧动画制作

UE5.1_UMG序列帧动画制作 UMG序列帧动画制作相对比较简单&#xff0c;不像视频帧需要创建媒体播放器那么复杂&#xff0c;以下简要说明&#xff1a; 1. 事件函数 2. 准备序列帧装入数组 3. 构造调用事件函数 4. 预览 序列帧UMG0105 5. 完成&#xff01;按需配置即可。

【elastic search】JAVA操作elastic search

目录 1.环境准备 2.ES JAVA API 3.Spring Boot操作ES 1.环境准备 本文是作者ES系列的第三篇文章&#xff0c;关于ES的核心概念移步&#xff1a; https://bugman.blog.csdn.net/article/details/135342256?spm1001.2014.3001.5502 关于ES的下载安装教程以及基本使用&…

2024年1月1日孙溟㠭篆刻艺术展开幕式于北京大学北大书店成功举办

“印记青春——会说话的石头” 主题文化展盛大开幕 2024年1月1日正值新年伊始&#xff0c;由北京大学出版社、北大书店、不黑文化艺术学社、中国诗书画研究会三才书画院联合举办的“印记 青春——会说话的石头”主题篆刻艺术展&#xff0c;在北京大学新太阳学生中心拉开帷幕。 …

C语言可变参数输入

本博文源于笔者正在学习的可变参数输入&#xff0c;可变参数是c语言函数中的一部分&#xff0c;下面本文就以一个很小的demo演示可变参数的编写 问题来源 想要用可变参数进行多个整数相加 方法源码 #include<stdio.h> #include<stdlib.h> #include<stdarg.h…

git 的安装

git 的安装 在我们开始使用 Git 前&#xff0c;需要将它安装在我们的电脑上。即便已经安装&#xff0c;最好将它升级到最新的版本。 我们可以通过软件包或者其它安装程序来安装&#xff0c;或者下载源码编译安装。 本文只介绍通过在 windows 上安装软件包的方式&#xff0c;其…

docker run 命令详解

一、前言 Docker容器是一个开源的应用容器引擎&#xff0c;让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何安装了Docker引擎的服务器上&#xff08;包括流行的Linux机器、Windows机器&#xff09;&#xff0c;也可以实现虚拟…

鸿蒙Harmony--状态管理器--@Prop详解

纵横千里独行客&#xff0c;何惧前路雨潇潇。夜半浊酒慰寂寞&#xff0c;天明走马入红尘。且将新火试新茶&#xff0c;诗酒趁年华。青春以末&#xff0c;壮志照旧&#xff0c;生活以悟&#xff0c;前路未明。时间善变&#xff0c;可执着翻不了篇。时光磨我少年心&#xff0c;却…

江科大STM32

参考&#xff1a; https://blog.csdn.net/weixin_54742551/article/details/132409170?spm1001.2014.3001.5502 https://blog.csdn.net/m0_61712829/article/details/132434192 https://blog.csdn.net/Johnor/article/details/128539267?spm1001.2014.3001.5502 SPI&#xff…

R语言下载安装及VScode配置

文章目录 1. R 下载和安装1.1 下载1.2 安装 2. VSCODE 配置2.1 安装R拓展2.2 安装R语言辅助功能包2.3 DEBUG 1. R 下载和安装 1.1 下载 网址&#xff1a;https://www.r-project.org/ 选择一个镜像地址下载 选择对应的版本 一般选择base即可 1.2 安装 下载安装包后按提示安装…

灵魂三连问:是5G卡吗?支持5G吗?是5G套餐吗

关于5G的问题&#xff0c;小伙伴们的疑问是不是很多&#xff0c;它和4G到底有什么区别呢&#xff1f;什么是5G卡&#xff1f;什么是5G套餐&#xff1f;支持5G吗&#xff1f;什么是5G基站&#xff1f;我想大家现在一定是晕的&#xff0c;下面小编来给大家解惑&#xff01; 1&…

图片双线性插值原理解析与代码 Python

一、原理解析 图片插值是图片操作中最常用的操作之一。为了详细解析其原理&#xff0c;本文以 33 图片插值到 55 图片为例进行解析。如上图左边蓝色方框是 55 的目标图片&#xff0c;右边红色方框是 33 的源图片。上图中&#xff0c;蓝/红色方框是图片&#xff0c;图片中的蓝/红…

Unity编辑器扩展(外挂)

每日一句:未来的样子藏在现在的努力里 目录 什么是编译器开发 C#特性[System.Serializable] 特殊目录 命名空间 /*检视器属性控制*/ //添加变量悬浮提示文字 //给数值设定范围&#xff08;最小0&#xff0c;最大150&#xff09; //指定输入框&#xff0c;拥有5行 //默认…

@JsonFormat与@DateTimeFormat

JsonFormat注解很好的解决了后端传给前端的格式&#xff0c;我们通过使用 JsonFormat可以很好的解决&#xff1a;后台到前台时间格式保持一致的问题 其次&#xff0c;另一个问题是&#xff0c;我们在使用WEB服务的时&#xff0c;可 能会需要用到&#xff0c;传入时间给后台&am…

在Gitee上维护Erpnext源

在Gitee上维护Erpnext源 官方的frappe和erpnext地址: GitHub - frappe/frappe: Low code web framework for real world applications, in Python and Javascript GitHub - frappe/erpnext: Free and Open Source Enterprise Resource Planning (ERP) 1, 仓库地址输入frappe的官…

Java中异常处理-详解

异常&#xff08;Exception&#xff09; JVM 默认处理方案 把异常的名称&#xff0c;异常的原因&#xff0c;及异常出错的位置等信息输出在控制台程序停止执行 异常类型 编译时异常必须显示处理&#xff0c;否则程序会发生错误&#xff0c;无法通过编译运行时异常无需显示处理…

华为鸿蒙凉了?谣言还是

华为鸿蒙系统凉了吗&#xff1f;我们从目前的一系列新闻来看。鸿蒙并没有凉&#xff0c;反而愈发强大。从下面的一些新闻事实可以看出华为鸿蒙已经和Android、ios形成竞争对手了。 1、华为宣布鸿蒙4.0的发布 2023年7月&#xff0c;华为开发者大会上正式宣布。华为发布了备受期…

算法第4版 第2章排序

综述&#xff1a;5个小节&#xff0c;四种排序应用&#xff0c;初级排序、归并排序、快速排序、优先队列 2.1.初级排序 排序算法模板&#xff0c;less(), exch(), 排序代码在sort()方法中&#xff1b; 选择排序&#xff1a;如升序排列&#xff0c;1.找到数组中最小的元素&am…

一种DevOpts的实现方式:基于gitlab的CICD(一)

写在之前 笔者最近准备开始入坑CNCF毕业的开源项目&#xff0c;看到其中有一组开源项目的分类就是DevOpts。这个领域内比较出名的项目是Argocd&#xff0c;Argo CD 是一个用于 Kubernetes 的持续交付 (Continuous Delivery) 工具&#xff0c;它以声明式的方式实现了应用程序的…

【Docker】配置阿里云镜像加速器

默认情况下&#xff0c;将来从docker hub &#xff08;https://hub.docker.com )上下载镜像太慢&#xff0c;所以一般配置镜像加速器。 没有账号的注册一个账号并登录 登录之后点击控制台 查看 cat /etc/docker/daemon.json