Vue3 + TS + Element-Plus —— 项目系统中封装表格+搜索表单 十分钟写五个UI不在是问题
前期回顾
纯前端 —— 200行JS代码、实现导出Excel、支持DIY样式,纵横合并-CSDN博客https://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)
七、📝 结语
封装其他组件在其余博文中也有详细描写,快来抱走把!
_______________________________ 期待再见 _______________________________
相关文章:

Vue3 + TS + Element-Plus —— 项目系统中封装表格+搜索表单 十分钟写五个UI不在是问题
前期回顾 纯前端 —— 200行JS代码、实现导出Excel、支持DIY样式,纵横合并-CSDN博客https://blog.csdn.net/m0_57904695/article/details/135537511?spm1001.2014.3001.5501 目录 一、🛠️ newTable.vue 封装Table 二、🚩 newForm.vue …...

Linux系统——测试端口连通性方法
目录 一、TCP端口连通性测试 1、ssh 2、telnet(可能需要安装) 3、curl 4、tcping(需要安装) 5、nc(需要安装) 6、nmap(需要安装) 二、UDP端口连通性测试 1、nc(…...

Python虚拟环境轻松配置:Jupyter Notebook中的内核管理指南
问题 在Python开发中,一些人在服务器上使用Jupyter Notebook中进行开发。一般是创建虚拟环境后,向Jupyter notebook中添加虚拟环境中的Kernel,后续新建Notebook中在该Kernel中进行开发,这里记录一下如何创建Python虚拟环境以及添…...

大数据-hive函数与mysql函数的辨析及练习-将多行聚合成一行
目录 1. 🥙collect_list: 聚合-不去重 2. 🥙collect_set(col): 聚合-去重 3. 🥙mysql的聚合函数-group_concat 4. leetcode练习题 1. 🥙collect_list: 聚合-不去重 将组内的元素收集成数组 不会去重 2. 🥙collec…...

【AI视野·今日NLP 自然语言处理论文速览 第七十三期】Tue, 9 Jan 2024
AI视野今日CS.NLP 自然语言处理论文速览 Tue, 9 Jan 2024 Totally 80 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers FFSplit: Split Feed-Forward Network For Optimizing Accuracy-Efficiency Trade-off in Language Model Infe…...

vue知识-03
购物车案例 要实现的功能: 1、计算商品总价格 2、全选框和取消全选框 3、商品数量的增加和减少 <body> <div id"app"><div class"row"><div class"col-md-6 col-md-offset-3"><h1 class"text-center…...

关于httpClient 使用的注意事项
关于httpClient 使用的注意事项 用例 PoolingHttpClientConnectionManager connectionManager new PoolingHttpClientConnectionManager();// 最大连接数-不设置默认20connectionManager.setMaxTotal(200);// 每个路由最大连接数-不设置默认2connectionManager.setDefaultMax…...

Docker 发布自定义镜像到公共仓库
Docker 发布自定义镜像到公共仓库 引言 Docker 是一种轻量级、便携式的容器化技术,可以使应用程序在不同环境中更加可移植。在本文中,我们将学习如何使用 Docker 从公共仓库拉取 Nginx 镜像,定制该镜像,添加自定义配置文件&…...

程序员有哪些接单的渠道?
这题我会!程序员接单的渠道那可太多了,想要接到合适的单子,筛选一个合适的平台很重要。如果你也在寻找一个合适的接单渠道,可以参考以下这些方向。 首先,程序员要对接单有一个基本的概念:接单渠道可以先粗略…...

服务容错-熔断策略之断路器hystrix-go
文章目录 概要一、服务熔断二、断路器模式三、hystrix-go3.1、使用3.2、源码 四、参考 概要 微服务先行者Martin Fowler与James Lewis在文章microservices中指出了微服务的九大特征,其中一个便是容错性设计(Design for failure)。正如文章中提到的,微服…...

C++进阶(三)多态
📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、多态的概念1、概念 二、多态的定义及实现1、多态的构成条件2、虚函数3、虚函数的重写4、C…...

大众汽车宣布将ChatGPT,批量集成在多种汽车中!
1月9日,大众汽车在官网宣布,将ChatGPT批量集成到电动、内燃机汽车中。 大众表示,将ChatGPT与其IDA语音助手相结合,用户通过自然语言就能与ChatGPT进行互动,例如,帮我看看最近的三星米其林饭店在哪里&#…...
React----函数组件和类组件
函数组件与类组件:React 中的两种组件风格 React 是一个用于构建用户界面的流行 JavaScript 库,其中组件是构建块的基本单元。在 React 中,有两种主要的组件风格:函数组件和类组件。本文将使用TypeScript介绍它们的用法、区别以及…...

Kafka集群部署 (KRaft模式集群)
KRaft 模式是 Kafka 在 3.0 版本中引入的新模式。KRaft 模式使用了 Raft 共识算法来管理 Kafka 集群元数据。Raft 算法是一种分布式共识算法,具有高可用性、可扩展性和安全性等优势。 在 KRaft 模式下,Kafka 集群中的每个 Broker 都具有和 Zookeeper 类…...

Vue 自定义仿word表单录入之日期输入组件
因项目需要,要实现仿word方式录入数据,要实现鼠标经过时才显示编辑组件,预览及离开后则显示具体的文字。 鼠标经过时显示 正常显示及离开时显示 组件代码 <template ><div class"paper-input flex flex-col border-box "…...
Oracle与Java JDBC数据类型对照
Oracle Database JDBC开发人员指南和参考 SQL Data TypesJDBC Type CodesStandard Java TypesOracle Extension Java Types CHAR java.sql.Types.CHAR java.lang.String oracle.sql.CHAR VARCHAR2 java.sql.Types.VARCHAR java.lang.String oracle.sql.CHAR LONG jav…...

C++力扣题目226--翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出:[2,3,1]示例 3&#x…...
Gorm 数据库表迁移与表模型定义
文章目录 一、Docker快速创建MySQL实例1.1 创建1.3 创建数据库 二、AutoMigrate介绍与使用2.1 AutoMigrate介绍2.2 AutoMigrate 基本使用 三、模型定义3.1 模型定义3.2 快速增删改查3.3 约定3.4 gorm.Model 四、表模型主键、表名、列名的约定4.1 主键(Primary Key&a…...
系列三、Spring Security中自定义用户名/密码
一、Spring Security中自定义用户名/密码 1.1、自定义用户名/密码 1.1.1、配置文件中配置 spring.security.user.nameroot spring.security.user.password123456 1.1.2、定义基于内存的用户 /*** Author : 一叶浮萍归大海* Date: 2024/1/11 21:50* Description:*/ Configu…...

如何顺滑使用华为云编译构建平台?
这两年平台构建服务需求越来越大,却一直苦于找不到一些指南, 这里特意写了一篇, 对在学习代码阶段和新手程序员朋友也蛮友好, 配置真的也不难, 也特别适合想尝试从0到1做个APP的朋友了。 以华为云的CodeArts Build为例…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...