vue3 + element-plus + ts el-table封装

news2024/9/28 19:24:03

vue3 + element-plus + ts el-table封装

博客参考https://blog.csdn.net/weixin_45291937/article/details/125523244
1. 文件位置(根据自己的需求)
在这里插入图片描述

2. 在 custom 文件夹下面 创建 mytable 文件夹
3. 直接上代码

// index.vue

<template>
	<div class="el-table-box">
		<el-table ref="tableRef" check-strictly :class="[_options.showPagination ? 'isActive' : 'active']" :data="tableData" v-loading="fullLoading" v-bind="_options" default-expand-all highlight-current-row @selection-change="handleSelectionChange" @row-click="handleRowClick" @cell-click="handleCellClick" @sort-change="handleSortChange">
			<el-table-column v-if="_options.showCheckout" :index="indexMethod" v-bind="{ type: 'selection', width: '50' }"></el-table-column>
			<template v-for="(col, index) in  columns " :key="index">
				<!---复选框, 序号 (START)-->
				<el-table-column v-if="col.type === 'expand' || col.type === 'customCell'" :index="indexMethod" v-bind="col">
					<!-- 当type等于expand时, 配置通过h函数渲染、tsx语法或者插槽自定义内容 -->
					<template #default="{ row, $index }">
						<!-- render函数 (START) : 使用内置的component组件可以支持h函数渲染和txs语法 -->
						<component v-if="col.render" :is="col.render" :row="row" :index="$index" />
						<!-- 自定义slot (START) -->
						<slot v-else-if="col.slot" name="expand" :row="row" :index="$index"></slot>
					</template>
				</el-table-column>
				<el-table-column v-else-if="col.type === 'index' && (col.hideFlag || col.hideFlag == null)" :index="indexMethod" v-bind="{ type: 'index', width: '50', label: $t(col.label + '') }" width="65">
					<!-- 当type等于expand时, 配置通过h函数渲染、txs语法或者插槽自定义内容 -->
					<template #default="{ row, $index }">
						<!-- render函数 (START) : 使用内置的component组件可以支持h函数渲染和txs语法 -->
						<component v-if="col.render" :is="col.render" :row="row" :index="$index" />
						<!-- 自定义slot (START) -->
						<slot v-else-if="col.slot" name="expand" :row="row" :index="$index"></slot>
					</template>
				</el-table-column>
				<!-- 渲染插槽 START -->
				<TableColumn :col="col" v-else-if="col.hideFlag || col.hideFlag == null" @command="handleAction">
					<template v-for="slot in  Object.keys($slots) " #[slot]="scope: Record<string, any>">
						<slot :name=" slot " v-bind=" scope " />
					</template>
				</TableColumn>
				<!-- 渲染插槽 END -->
			</template>
			<template #empty>
				<div class="mp_tatble_nodata">
					<img class="active-daek" :src=" ImageUrl " alt="">
					<div>{{$t('message.application.btn.currently')}}</div>
				</div>
			</template>
		</el-table>
		<!-- 分页器 -->
		<div v-if=" _options.showPagination " class="mt20">
			<el-pagination v-bind=" _paginationConfig " @size-change=" pageSizeChange " @current-change=" currentPageChange " />
		</div>
	</div>
</template>
<script lang="ts" setup>
	import { ComputedRef, computed, ref, onMounted, defineAsyncComponent, withDefaults } from 'vue';
	import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults';
	import { ElTable } from 'element-plus';
	import ImageUrl from '/@/assets/nodata.png'
	
	const TableColumn = defineAsyncComponent(() => import('./TableColumn.vue'));
	export type SortParams<T> = {
		column: TableColumnCtx<T | any>;
		prop: string;
		order: Table.Order;
	};
	interface TableProps {
		tableData: Array<object>; // table的数据
		columns: Table.Column[]; // 每列的配置项
		options?: Table.Options;
		fullLoading?: boolean;
	}
	
	
	const props = withDefaults(defineProps<TableProps>(), {
		fullLoading: false,
	});
	const tableRef = ref<InstanceType<typeof ElTable>>();
	// 设置option默认值,如果传入自定义的配置则合并option配置项
	const _options: ComputedRef<Table.Options> = computed(() => {
		const option = {
			stripe: false,
			tooltipEffect: 'dark',
			showHeader: true,
			showPagination: false,
			rowStyle: () => 'cursor:pointer', // 行样式
		};
		return Object.assign(option, props?.options);
	});
	
	// 合并分页配置
	const _paginationConfig = computed(() => {
		const config = {
			total: 0,
			currentPage: 1,
			pageSize: 10,
			pageSizes: [10, 20, 50],
			layout: 'total, sizes, prev, pager, next, jumper'
		}
		return Object.assign(config, _options.value.paginationConfig)
	})
	const emit = defineEmits([
		'selection-change', // 当选择项发生变化时会触发该事件
		'row-click', // 当某一行被点击时会触发该事件
		'cell-click', // 当某个单元格被点击时会触发该事件
		'command', // 按钮组事件
		'size-change', // pageSize事件
		'current-change', // currentPage按钮组事件
		'pagination-change', // currentPage或者pageSize改变触发
		'sort-change', // 列排序发生改变触发
		'row-radio', // 单选
	]);
	// 自定义索引
	const indexMethod = (index: number) => {
		const tabIndex = index + (_paginationConfig.value.currentPage - 1) * _paginationConfig.value.pageSize + 1;
		return tabIndex;
	};
	// 切换pageSize
	const pageSizeChange = (pageSize: number) => {
		emit('size-change', pageSize);
		emit('pagination-change', 1, pageSize);
	};
	// 切换currentPage
	const currentPageChange = (currentPage: number) => {
		emit('current-change', currentPage);
		emit('pagination-change', currentPage, _paginationConfig.value.pageSize);
	};
	// 按钮组事件
	const handleAction = (command: Table.Command, row: any, index: number) => {
		emit('command', command, row, index);
	};
	
	// 多选事件
	const handleSelectionChange = (val: any) => {
		emit('selection-change', val);
	};
	//返回当前选中的行
	const getSelectionRows = () => {
		return tableRef.value?.getSelectionRows();
	};
	// 当某一行被点击时会触发该事件
	const handleRowClick = (row: any, column: any, event: MouseEvent) => {
		emit('row-click', row, column, event);
	};
	// 当某个单元格被点击时会触发该事件
	const handleCellClick = (row: any, column: any, cell: any, event: MouseEvent) => {
		if (column && column.className) {
			if (column.className == 'mp-highlight') {
				emit('cell-click', row, column, cell, event);
			}
		}
		if (_options.value.showRadio) {
			if (tableRef.value && tableRef.value) tableRef.value.setCurrentRow(row)
			emit('row-radio', row, column, cell, event);
		}
	};
	/**
	 *  当表格的排序条件发生变化的时候会触发该事件
	 * 在列中设置 sortable 属性即可实现以该列为基准的排序, 接受一个 Boolean,默认为 false。
	 * 可以通过 Table 的 default-sort 属性设置默认的排序列和排序顺序。
	 * 如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件,
	 * 在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。
	 */
	const handleSortChange = ({ column, prop, order }: SortParams<any>) => {
		emit('sort-change', { column, prop, order });
	};
	// 暴露给父组件参数和方法,如果外部需要更多的参数或者方法,都可以从这里暴露出去。
	defineExpose({ element: tableRef, fn: getSelectionRows });
</script>
<style lang="scss" scoped>
:deep(.el-image__inner) {
	transition: all 0.3s;
	cursor: pointer;

	&:hover {
		transform: scale(1.2);
	}
}

.el-table-box {
	height: 100%;

	.isActive {
		height: calc(100% - 45px) !important;
	}

	.active {
		height: 100%;
	}

	.mt20 {
		display: flex;
		justify-content: end;
	}
}

</style>

4. 安装 cnpm i -S dayjs (可以不安装 ,如果不安装就删除下面的标记部分)

 // TableColumn.vue

<script lang="ts" setup>
	import dayjs from 'dayjs'
	defineProps<{ col: Table.Column }>()
	const emit = defineEmits(['command', 'handleClickRow'])
	// 按钮组事件
	const handleAction = (command: Table.Command, { row, $index }: { row: any; $index: number }) => {
	    emit('command', command, row, $index)
	}
</script>
<template>
    <!-- 如果有配置多级表头的数据,则递归该组件 -->
    <template v-if="col.children?.length">
        <el-table-column :label="col.label" :width="col.width" :align="col.align">
            <TableColumn v-for="item in     col.children    " :col="item" :key="item.prop">
                <template v-for="slot in     Object.keys($slots)    " #[slot]="scope: Record<string, any>">
                    <slot :name=" slot " v-bind=" scope " />
                </template>
            </TableColumn>
            <template #header=" { column, $index } ">
                <component v-if=" col.headerRender " :is="col.headerRender" :column=" column " :index=" $index " />
                <slot v-else-if=" col.headerSlot " :name=" col.headerSlot " :column=" column " :index=" $index "></slot>
                <span v-else>{{ $t(column.label) }}</span>
            </template>
        </el-table-column>
    </template>
    <el-table-column v-else-if=" col.highlight " v-bind=" col " class-name='mp-highlight'>
        <template #header=" { column, $index } ">
            <component v-if=" col.headerRender " :is="col.headerRender" :column=" column " :index=" $index " />
            <slot v-else-if=" col.headerSlot " :name=" col.headerSlot " :column=" column " :index=" $index "></slot>
            <span v-else>{{ $t(column.label)}}</span>
        </template>
        <template #default=" { row, $index } ">
            <span>{{ row[col.prop!] }}</span>
        </template>
    </el-table-column>
    <!-- 其他正常列 -->
    <el-table-column v-else v-bind=" col ">
        <!-- 自定义表头 -->
        <template #header=" { column, $index } ">
            <component v-if=" col.headerRender " :is="col.headerRender" :column=" column " :index=" $index " />
            <slot v-else-if=" col.headerSlot " :name=" col.headerSlot " :column=" column " :index=" $index "></slot>
            <span v-else>{{ $t(column.label)}}</span>
        </template>
        <template #default=" { row, $index } ">

            <!-- 如需更改图片size,可自行配置参数 -->
            <el-image v-if=" col.type === 'image' " preview-teleported :hide-on-click-modal=" true " :preview-src-list=" [row[col.prop!]] " :src=" row[col.prop!] " fit="cover" class="w-9 h-9 rounded-lg" />
             
             <!-- day.js开始  (不安装可删除该部分)  -->
            <!--- 格式化日期 (本项目日期是时间戳,这里日期格式化可根据你的项目来更改) (START)-->
            <template v-else-if=" col.type === 'date' ">
                <!---十位数时间戳-->
                <span v-if=" String(row[col.prop!])?.length <= 10 ">
                    {{ dayjs.unix(row[col.prop!]).format(col.dateFormat ?? 'YYYY-MM-DD') }}
                </span>
                <!---十三位数时间戳-->
                <span v-else>{{ dayjs(row[col.prop!]).format(col.dateFormat ?? 'YYYY-MM-DD') }}</span>
            </template>
            <!-- day.js结束  -->
            
            <!-- 如果传递按钮数组,就展示按钮组 START-->
            <el-button-group v-else-if=" col.buttons?.length ">
                <el-button v-for="(    btn, index    ) in     col.buttons    " :key=" index " :size=" btn.size " :type=" btn.type " @click="handleAction(btn.command, { row, $index })">{{ btn.name }}</el-button>
            </el-button-group>

            <!-- render函数 (START) 使用内置的component组件可以支持h函数渲染和txs语法-->
            <component v-else-if=" col.render " :is="col.render" :row=" row " :index=" $index " />

            <!-- 自定义slot (START) -->
            <slot v-else-if=" col.slot " :name=" col.slot " :row=" row " :index=" $index "></slot>

            <!-- 默认渲染 (START)  -->
            
            <span v-else>{{ row[col.prop!] }}</span>

        </template>
    </el-table-column>
</template>

5. table.d.ts (表格全局接口文件)

// table.d.ts
declare namespace Table {
	type VNodeChild = import('vue').VNodeChild
	type Type = 'selection' | 'index' | 'expand' | 'image' | 'date'
    type Size = 'large' | 'default' | 'small'
    type Align = 'center' | 'left' | 'right'
    type Command = string | number
    type DateFormat = 'YYYY-MM-DD' | 'YYYY-MM-DD HH:mm:ss' | 'YYYY-MM-DD HH:mm' | 'YYYY-MM'
    type Order = 'ascending' | 'descending'
    interface ButtonItem {
        name: string,
        command: Command,
        size?: Size
        type?: 'primary' | 'success' | 'warning' | 'danger' | 'info',
    }
    interface Sort {
        prop: string
        order: Order
        init?: any
        silent?: any
    }
    interface Column {
   		// 对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮
        type?: Type | 'customCell',
        label?: string,
        prop?: string,
        slot?: string
        width?: string,
        align?: Align,
        hideFlag?:boolean,
        hide?:boolean,
        fixed?:string|boolean,
        highlight?:boolean,//字段高亮
        dateFormat?: DateFormat // 显示在页面中的日期格式,简单列举了几种格式, 可自行配置
        showOverflowTooltip?: boolean,
        buttons?: ButtonItem[],
        render?: (row?: any, index?: number) => VNodeChild // 渲染函数,渲染这一列的每一行的单元格
        sortable?: boolean | 'custom', // 对应列是否可以排序, 如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件
        headerRender?: ({ column, index }) => VNodeChild, // 渲染函数,渲染列表头
        headerSlot?: string, // 自定义表头插槽名字
        children?: Column[] // 配置多级表头的数据集合, 具体用法可参考多级表头使用示例。
    }
    interface Options {
        height?: string | number,
        // Table 的高度, 默认为自动高度。 如果 height 为 number 类型,单位 px;如果 height 为 string 类型,则这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。
        stripe?: boolean, // 是否为斑马纹 table
        maxHeight?: string | number, // Table 的最大高度。 合法的值为数字或者单位为 px 的高度。
        size?: Size // Table 的尺寸
        showHeader?: boolean // 是否显示表头,
        showRadio?:boolean, //单选
        showCheckout?:boolean, //多选
        defaultExpandAll?:boolean
        tooltipEffect?: 'dark' | 'light' // tooltip effect 属性
        showPagination?: boolean, // 是否展示分页器
        paginationConfig?: Pagination, // 分页器配置项,详情见下方 paginationConfig 属性,
   	 	rowStyle?: ({ row, rowIndex }) => stirng | object // 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。
   	 	headerCellStyle?: import('vue').CSSProperties, // 表头单元格的style样式,是一个object为所有表头单元格设置一样的 Style。注:CSSProperties类型就是一个对象,像正常在style中写css一样 {color: #f00}
 	 	defaultSort?: Sort // 默认的排序列的 prop 和顺序。 它的 prop 属性指定默认的排序的列,order 指定默认排序的顺序。
 	 	"row-key"?: string // 行数据的 Key,用来优化 Table 的渲染。
        treeProps?:{}
    }
    interface Pagination {
        total?: number, // 总条目数
        currentPage: number, // 当前页数,支持 v-model 双向绑定
        pageSize: number, // 每页显示条目个数,支持 v-model 双向绑定
        pageSizes?: number[], // 每页显示个数选择器的选项设置
        layout?: string, // 组件布局,子组件名用逗号分隔
        background?: boolean // 是否为分页按钮添加背景色
    }
    interface pagination_type {
        currentPage: number,
        limit: number,
    }
}



6. 简单使用 具体的使用方法可以在 table.d.ts (表格全局接口文件) 中查看配置

<template>
  <div class="mp-box-container layout-pd user-news-center">
    <Table :columns="tableColumn" v-loading="state.fullLoading" :options="state.options"
        :table-data="state.tableData" @pagination-change="paginationChange"
        @sort-change="handleSortChange">
        <!-- 操作 -->
        <template #action="{ row, index }">
          <div class="user-news-center__btns">
              <el-button type="primary" link @click="editNewsHandler(row)">
                {{ $t('编辑') }}
              </el-button>

              <el-button type="primary" link @click="deleteNewsHander(row)">
                {{ $t('删除') }}
              </el-button>

          </div>
        </template>
      </Table>
  </div>
</template>

<script setup lang="ts">
import { defineAsyncComponent, ref, reactive, onMounted, h, watch } from 'vue' // vue实例
const Table = defineAsyncComponent(() => import('/@/custom/myTable/index.vue')) // 引入组件

// 分页
const paginationConfig = reactive({
  total: 0,
  currentPage: 1,
  pageSize: 10,
})

// 排序
const orderConfig = reactive({
  prop: '',
  order: '',
})

let state = reactive({
  options: { 
    showPagination: true,
     paginationConfig,
  },
  tableData: [],
  tableColumn: [],
  fullLoading: false
})

const tableColumn = ref<Table.Column[]>([
	// 公司编码
	{
		prop: 'F_EnCode',
		hideFlag: true,
		label: '公司编码',
		width: '150px',
		showOverflowTooltip: true
	},
	// 公司名称
	{
		prop: 'F_FullName',
		label: '公司名称',
		// highlight: true,  //字段高亮
		hideFlag: true, //显隐
	},
	// 上级公司
	{
		prop: 'F_ParentName',
		label: '上级公司',
		// highlight: true,  //字段高亮
		hideFlag: true, //显隐
	},
	// 备注
	{
		prop: 'F_Description',
		label: '备注',
		// highlight: true,  //字段高亮
		hideFlag: true, //显隐
	},
	// 按钮使用render函数渲染(操作)
	{
		width: '120',
		label: 'message.publicTable.Operation',
		prop: 'action',
		slot: 'action',  // 方法一  插槽
		fixed: "right",
		// 方法二 按钮组
		// buttons:[
		// 	{
		// 		name:"编辑",
		// 		command:"edit",
		// 		type:"danger"
		// 	},
		// 	{
		// 		name:"删除",
		// 		command:"delete",
		// 		type:"danger"
		// 	}
		// ]
		/**    
		 * 
		 * 方法三 render 函数
		 * 
		 */
		// render: (row: User, index: number) =>
		// 	// 渲染单个元素
		// 	h('div', null, [
		// 		h(
		// 			ElButton,
		// 			{
		// 				type: 'primary',
		// 				link: true,
		// 				onClick: () => handleRenderEdit(row, index)
		// 			},
		// { default: () => '编辑' }
		// 		),
		// 		h(
		// 			ElButton,
		// 			{
		// 				type: 'primary',
		// 				link: true,
		// 				onClick: () => handleRenderDelete(row, index)
		// 			},
		// 			{ default: () => '删除' }
		// 		)
		// 	])
	}
])

/**
 * 删除
 */
const deleteNewsHander = (row: any) => {
 
}

/**
 * 编辑
 */
const editNewsHandler = (row: any) => {

}

/**
 * 分页改变
 */
const paginationChange = (currentPage: number, pageSize: number) => {
  paginationConfig.currentPage = currentPage;
  paginationConfig.pageSize = pageSize;

}

/**
 * 排序
 */
const handleSortChange = ({ prop, order }: any) => {
  orderConfig.order = order === 'ascending' ? 'asc' : 'desc'
  orderConfig.prop = prop
 
}



</script>


7. 效果
在这里插入图片描述

8. 以上为全部代码! 欢迎各位同学指导!

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

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

相关文章

centos7搭建 PXE 服务安装 window10/11 系统

最近想搭建之前基于 window server 的 window 批量安装&#xff0c;但想想装 window server 真的太麻烦了&#xff0c;我只是为了 PXE 安装系统而已&#xff0c;这些装一个极度消耗资源的系统真是相当麻烦呀&#xff0c;之前装的 server 不维护的话&#xff0c;不是被挖矿盯上就…

Linux新加磁盘的完整步骤

目录 新加磁盘的完整步骤磁盘分区磁盘文件命名经典分区方案fdiskparted 分区格式化挂载分区 新加磁盘的完整步骤 物理连接 --> 分区 --> 格式化 --> 挂载 --> 更新/etc/fstab文件实现永久挂载 磁盘分区 主分区primary用来安装操作系统、存放数据&#xff0c;可以…

历时三个月,我发布了一款领取外卖红包小程序

近几年&#xff0c;推广外卖红包爆火&#xff0c;各种推广外卖红包的公众号层出不穷。于是&#xff0c;我就在想外卖红包究竟是怎么一回事。就这样&#xff0c;我带着问题开始了关于外卖红包的研究。 在研究的过程中&#xff0c;我开始了解隐藏优惠券、cps等一系列相关的术语。…

UCP通信

一&#xff0c;概括 二 &#xff0c;常用方法 三&#xff0c;实现步骤&#xff08;一发一收&#xff09; 四&#xff0c;案例&#xff08;一发一收&#xff09; &#xff08;1&#xff09;&#xff1a;客户端 &#xff08;2&#xff09;&#xff1a;服务端 &#xff08;3&…

解决:ModuleNotFoundError: No module named ‘PyQt5‘

解决&#xff1a;ModuleNotFoundError: No module named ‘PyQt5’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named PyQt5背景报错问题报错翻译报错位置代码报错原因解决方法安装PyQt5在PyCharm中配置PyQt5对于新项目对于已有项目 今天的分享就到此结束了 背景…

NX二次开发UF_CURVE_convert_conic_to_gen 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_convert_conic_to_gen Defined in: uf_curve.h int UF_CURVE_convert_conic_to_gen(UF_CURVE_conic_p_t conic_data, UF_CURVE_genconic_t * gen_conic_data ) overview 概…

309.最佳卖股票的时机包含冷冻期

一、题目分析 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 卖出股票后&#xff0c;你无法在第二…

NX二次开发UF_CURVE_convert_conic_to_std 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_convert_conic_to_std Defined in: uf_curve.h int UF_CURVE_convert_conic_to_std(UF_CURVE_genconic_p_t gen_conic_data, UF_CURVE_conic_t * conic_data, logical * se…

python炒股自动化(1),量化交易接口区别

要实现股票量化程序化自动化&#xff0c;就需要券商提供的API接口&#xff0c;重点是个人账户小散户可以申请开通&#xff0c;上手要简单&#xff0c;接口要足够全面&#xff0c;功能完善&#xff0c;首先&#xff0c;第一步就是要找对渠道和方法&#xff0c;这里我们不讨论量化…

关于Unity中字典在Inspector的显示

字典在Inspector的显示 方法一&#xff1a;实现ISerializationCallbackReceiver接口 《unity3D游戏开发第二版》记录 在编辑面板中可以利用序列化监听接口特性对字典进行序列化。 主要继承ISerializationCallbackReceiver接口 实现OnAfterDeserialize() OnBeforeSerialize() …

二十章 多线程

线程简介 在 Java 中&#xff0c;并发机制非常重要。在以往的程序设计中&#xff0c;我们都是一个任务完成后再进行下一个任务&#xff0c;这样下一个任务的开始必须等待前一个任务的结束。Java 语言提供了并发机制&#xff0c;程序员可以在程序中执行多个线程&#xff0c;每一…

上门预约互联网干洗店洗鞋店小程序开发

很多时候可能大家的衣服鞋子需要干洗&#xff0c;但又不想出门送去店里&#xff0c;大家就可以使用手机线上下单预约取货&#xff0c;会有专门的人上门来取衣服&#xff0c;让你能够轻松的进行洗护。 闪站侠洗衣洗鞋小程序&#xff0c;提供了足不出户就能预约人员上门去 衣送洗…

【刷题笔记】匹配字符串||KMP||动图解析||符合思维方式

找出字符串中第一个匹配项的下标 1 题目描述 https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/ 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开…

Swift下如何使用#if条件编译

一、OC使用条件编译 OC中可以使用宏定义&#xff0c;再使用条件编译 #define USER_CUSTOM使用 #if USER_CUSTOM //其他代码 #endif二、Swift使用条件编译 Swift 不像ObjectC一样&#xff0c;通过定义一个变量&#xff0c;然后使用**#if #endif** 方法。swift需要设置一下才能…

SpringBoot错误处理机制(ControllerAdvice+ExceptionHandler自定义错误处理、默认机制源码分析、错误处理实战)

目录 1. SpringBoot自己对错误进行处理1.1 给一个Controller进行错误处理1.2 使用ControllerAdvice统一处理错误 2. 默认机制源码解析3. 错误处理机制实战 1. SpringBoot自己对错误进行处理 1.1 给一个Controller进行错误处理 使用ExceptionHandler&#xff0c;处理一个Conto…

【电源芯片】ZTP7193

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大…

销售流程中如何有效开发客户

在销售的海洋中&#xff0c;如何游刃有余地开发客户是一大关键。这需要深入了解你的目标客户&#xff0c;制定一份精细的销售计划&#xff0c;选择最合适的沟通方式&#xff0c;建立信任和信誉&#xff0c;并持续不断地跟进。 每一个潜在的客户都是一颗璀璨的星辰&#xff0c;…

地理坐标系转换

1.EPSG代码 搜索地理坐标系对应的EPSG代码 https://epsg.io/ 常用的地理坐标系EPSG代码&#xff1a; 2. 坐标系转换 转换网址&#xff1a; https://epsg.io/transform &#xff08;1&#xff09;修改 input coordinate system 和 output coordinate system&#xff0c; 可以…

【开源】基于Vue.js的农村物流配送系统的设计和实现

项目编号&#xff1a; S 024 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S024&#xff0c;文末获取源码。} 项目编号&#xff1a;S024&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2…

人工智能学习2(python数据清洗)

编译工具&#xff1a;PyCharm 一.数据清洗 转化数据类型、处理重复数据、处理缺失数据 import pandas as pddf pd.read_csv("/data.csv") df.sample(10) # 用于随机获取数据并返回结果 df.head(10) # 查看前十条数据 df.tail(10) # 查看后十条数据 df.shape …