ElementPlus Combogrid 组件

效果图: 

1.声明 Props类型

export type comboGridPropType = {

  modelValue: any; 

  url: string;

  keyField?: string;

  labelField?: string;

  filterOptions?: Array<ISearchOption>;

  tableColumns?: Array<TableColumns>;

  enableField?: string;

  multiple?: boolean;

  width?: number | string;

  panelWidth?: number;

  defaultPageSize?: number;

  autoSelectFirst?: boolean; //自动选择第一项

  sort?: string;

  order?: "desc" | "asc";

  queryOp: "Contains" | "BeginsWith" | "Equal";

  disabled?: boolean; //禁用

  searchable?: boolean; // 搜索

  isTreeData?: boolean; // 树结构数据

  treeProps?: { hasChildren?: string; children?: string };

};

2.后端数据结构

后端返回的数据结构:

using System;
using System.Collections.Generic;
using System.Text;namespace WebiMes.Models.ViewModels
{/// <summary>/// 翻页返回集合/// </summary>public sealed class PagenationResult{public PagenationResult(){}/// <summary>/// 当前页/// </summary>public int pageIndex { get; set; }/// <summary>/// 每页显示/// </summary>public int pageSize { get; set; }/// <summary>/// 页码token(弃用)/// </summary>public string PageNationToken { get; set; }/// <summary>/// 数据集/// </summary>public IEnumerable<Object> List { get; set; }/// <summary>/// 行数/// </summary>public long Total { get; set; }/// <summary>/// 额外数据/// </summary>public Object? ExtenalData { get; set; }}
}

3.注意事项

1.如果不指定 keyfield和labelfield,默认将返回数据的第一列作为 keyfield和labelfield

2.filterOptions搜索字段类型 

id: number;
label: string;
value: string;
type: "string" | "boolean" | "date" | "number";

3.tableColumns表格列数据

{/** 是否隐藏 */hide?: boolean | CallableFunction;/** 自定义列的内容插槽 */slot?: string;/** 自定义表头的内容插槽 */headerSlot?: string;/** 多级表头,内部实现原理:嵌套 `el-table-column` */children?: Array<TableColumns>;/** 自定义单元格渲染器(`jsx`语法) */cellRenderer?: (data: TableColumnRenderer) => VNode;/** 自定义头部渲染器(`jsx`语法) */headerRenderer?: (data: TableColumnRenderer) => VNode;/** 显示的标题 */label?: string;/** 字段名称,对应列内容的字段名,也可以使用 `property` 属性 */prop?: string | ((index: number) => string);/** 对应列的类型,如果设置了 `selection` 则显示多选框;如果设置了 `index` 则显示该行的索引(从 `1` 开始计算);如果设置了 `expand` 则显示为一个可展开的按钮 */type?: TableColumnType;/** 如果设置了 `type=index`,可以通过传递 `index` 属性来自定义索引 */index?: number | ((index: number) => number);/** `column` 的 `key`, 如果需要使用 `filter-change` 事件,则需要此属性标识是哪个 `column` 的筛选条件 */columnKey?: string;/** 对应列的宽度 */width?: string | number;/** 对应列的最小宽度,对应列的最小宽度,与 `width` 的区别是 `width` 是固定的,`min-width` 会把剩余宽度按比例分配给设置了 `min-width` 的列 */minWidth?: string | number;/** 列是否固定在左侧或者右侧。`true` 表示固定在左侧 */fixed?: TableColumnFixed;/** 列标题 `Label` 区域渲染使用的 `Function` */renderHeader?: (data: RH) => VNode;/** 对应列是否可以排序, 如果设置为 `'custom'`,则代表用户希望远程排序,需要监听 `Table` 的 `sort-change `事件,默认值为 `false` */sortable?: TableColumnSortable;/** 指定数据按照哪个属性进行排序,仅当 `sortable` 设置为 `true` 的时候有效。应该如同 `Array.sort` 那样返回一个 `Number` */sortMethod?: (a: any, b: any) => number;/** 指定数据按照哪个属性进行排序,仅当 `sortable` 设置为 `true` 且没有设置 `sort-method` 的时候有效。如果 `sort-by` 为数组,则先按照第 `1` 个属性排序,如果第 `1` 个相等,再按照第 `2` 个排序,以此类推 */sortBy?: string | ((row: any, index: number) => string) | string[];/** 数据在排序时所使用排序策略的轮转顺序,仅当 `sortable` 为 `true` 时有效。需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序,默认值为 `['ascending', 'descending', null]` */sortOrders?: Array<TableColumnSortOrders>;/** 对应列是否可以通过拖动改变宽度(需要在 `el-table` 上设置 `border` 属性为真),默认值为 `true`  */resizable?: boolean;/** 用来格式化内容 */formatter?: (row: any, column: TableColumnCtx<any>, cellValue: any, index: number) => VNode | string;/** 当内容过长被隐藏时显示 `tooltip`,默认值为 `false` */showOverflowTooltip?: boolean;/** 对齐方式,默认值为 `left` */align?: Align;/** 表头对齐方式,若不设置该项,则使用表格的对齐方式 */headerAlign?: Align;/** 列的 `className` */className?: string;/** 当前列标题的自定义类名 */labelClassName?: string;/** 仅对 `type=selection` 的列有效,类型为 `Function`,`Function` 的返回值用来决定这一行的 `CheckBox` 是否可以勾选 */selectable?: (row: any, index: number) => boolean;/** 仅对 `type=selection` 的列有效,请注意,需指定 `row-key` 来让这个功能生效,默认值为 `false` */reserveSelection?: boolean;/** 数据过滤的选项,数组格式,数组中的元素需要有 `text` 和 `value` 属性。数组中的每个元素都需要有 `text` 和 `value` 属性 */filters?: Array<{text: string;value: string;}>;/** 过滤弹出框的定位 */filterPlacement?: TableColumnFilterPlacement;/** 数据过滤的选项是否多选,默认值为 `true` */filterMultiple?: boolean;/** 数据过滤使用的方法,如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 `true` 就会显示 */filterMethod?: FilterMethods;/** 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性 */filteredValue?: Array<any>;
}

4.完整代码

 combogrid.vue

<script setup lang="ts">
import { ref, onMounted, watch, toRefs } from "vue";
import iSearch from "@iconify-icons/ep/search";
import dayjs from "dayjs";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import _ from "lodash";
import { http } from "@/utils/http";
import {IResultTable,IFilterRule,FilterOp,FilterValueType
} from "@/api/baseTypes";
import { message } from "@/utils/message";
import { comboGridPropType, ISearchOption } from "./types";
// import { useUserStoreHook } from "@/store/modules/user";defineOptions({name: "ComboGrid"
});
// statting in Vue 3.4
// const modelValue = defineModel<any>({ default: "" });
/** 配置默认值 */
const props = withDefaults(defineProps<comboGridPropType>(), {keyField: "", //主键IdlabelField: "", //主键IdtableColumns: () => [],filterOptions: () => [],defaultPageSize: 10, //默认每页展示数量multiple: false, //多选width: 180, //宽度panelWidth: 700, //高度autoSelectFirst: false, //自动选中第一条sort: "",order: "asc",queryOp: "Contains",disabled: false,searchable: true,isTreeData: false,treeProps: () => ({ hasChildren: "hasChildren", children: "children" })
});
/** emits */
const emits = defineEmits<{(e: "update:modelValue", value: any): void;(e: "change", value: any): void;
}>();
/** 已初始化 */
const inited = ref(false);
//解构出来 ref
const {url, //搜索数据链接keyField: _keyField, //主键IdlabelField: _labelField, //选中展示LabelenableField,tableColumns,defaultPageSize, //默认每页展示数量filterOptions: _filterOptions, //搜索字段 数据集queryOp,disabled
} = toRefs(props);const keyField = ref(""); //主键Id2
keyField.value = _keyField.value;
const labelField = ref(""); //选中展示Label
labelField.value = _labelField.value;
const filterOptions = ref<ISearchOption[]>([]); //搜索字段 数据集
filterOptions.value = _filterOptions.value;/**初始化字段 */
const isInitColumn = ref(false);
isInitColumn.value = tableColumns.value?.length <= 0;
if (!tableColumns.value?.some(x => x.type === "index")) {tableColumns.value.splice(0, 0, {type: "index",label: "#",align: "center",index: (index: number) => {return (currentPage.value - 1) * defaultPageSize.value + index + 1;}});
}const loadingList = ref(false); //加载数据列表
const tableData = ref([]); //表格数据
const selectRef = ref(); //选择框Ref
const tabRef = ref(); //数据展示Ref
const fieldSelectRef = ref(); //筛选字段Ref
//搜索字段
const filterField = ref<ISearchOption>();
/**初始化搜索字段 */
const isInitfilterOptions = ref(false);
//搜索字段 数组
if (_.isArray(filterOptions.value) && filterOptions.value.length > 0) {filterField.value = filterOptions.value[0];
} else isInitfilterOptions.value = true;
// 当前账户
// const useUserStore = useUserStoreHook();
// 已选数据的Label
const selectLabel = ref<string[]>([]);
// 搜索值
const searchQuery = ref();
/** 搜索 */
function onSearch() {let searchKey;let op: FilterOp = FilterOp.BeginsWith;if (queryOp.value === "Contains" || queryOp.value === "Equal") {const FilterOpStr: keyof typeof FilterOp = queryOp.value;op = FilterOp[FilterOpStr];}let valType: FilterValueType = FilterValueType.String;if (filterField.value?.type === "boolean") {const lowerVal = searchQuery.value.toLowerCase();if (lowerVal === "true") searchKey = true;if (lowerVal === "false") searchKey = false;if (_.isNumber(lowerVal)) searchKey = Number(lowerVal) > 0;if (_.isEmpty(searchKey)) {message("搜索数据类型不匹配" + filterField.value.type, {type: "warning",showClose: true,duration: 3000});return false;}op = FilterOp.Equal;valType = FilterValueType.Boolean;} else if (filterField.value?.type === "date") {const dateVal = new Date(searchQuery.value);if (!_.isDate(dateVal)) {message("搜索数据类型不匹配" + filterField.value.type, {type: "warning",showClose: true,duration: 3000});return false;} else {searchKey = dateVal;op = FilterOp.GreaterThanOrEqual;valType = FilterValueType.Datetime;}} else {searchKey = searchQuery.value;}if (_searhFilters.length > 1)_searhFilters.splice(1, _searhFilters.length - 1);if (_.isEmpty(searchKey) || _.isEmpty(filterField.value)) {// message(`搜索 类型或值,为空,将搜索所有数据`, {//   type: "warning",//   showClose: true,//   duration: 3000// });const sfilter = _searhFilters.find(x => x.field == filterField.value?.value);if (_.isEmpty(sfilter)) {_searhFilters.push({field: filterField.value?.value, // 字段op: op, // 比较符号value: searchKey, // 值valType: valType // 值类型});} else {_searhFilters[0].op = op;_searhFilters[0].valType = valType;_searhFilters[0].value = "";}} else {const sfilter = _searhFilters.find(x => x.field == filterField.value.value);if (_.isEmpty(sfilter)) {_searhFilters.push({field: filterField.value.value, // 字段op: op, // 比较符号value: searchKey, // 值valType: valType // 值类型});} else {_searhFilters[0].op = op;_searhFilters[0].valType = valType;_searhFilters[0].value = searchKey;}}currentPage.value = 1;getTabelData();
}
/** 选中的 行 */
const selectedRows = ref([]);
/** 更新v-Model */
function updateVModel() {if (!props.multiple) {if (!_.isEmpty(selectedRows.value)) {const newValue = selectedRows.value[0][keyField.value];emits("update:modelValue", newValue);emits("change", selectedRows.value[0]);} else {emits("update:modelValue", null);emits("change", null);}} else {const newValues = selectedRows.value.map(x => x[keyField.value]);emits("update:modelValue", newValues);emits("change", selectedRows.value);}
}
/** 行选中 */
function handleRowClick(currentRow, _column, _event) {if (!_.isEmpty(currentRow)) {if (!_.isEmpty(enableField.value) &&!_.isEmpty(currentRow.value) &&_.isBoolean(currentRow[enableField.value]) &&!currentRow[enableField.value]) {message("没有权限选择本条数据", { type: "warning" });return false;}let removeIndex = -1;let some = false;selectedRows.value.forEach((x, index) => {if (x[keyField.value] === currentRow[keyField.value]) {some = true;removeIndex = index;return false;}});const _label = currentRow[labelField.value];if (!props.multiple && selectedRows.value.length > 0) {//清空selectedRows.value.splice(0, selectedRows.value.length);selectLabel.value.splice(0, selectLabel.value.length);}if (!some) {selectedRows.value.push(currentRow);} else {if (removeIndex >= 0) selectedRows.value.splice(removeIndex, 1);}selectLabel.value.forEach((x, index) => {if (x === _label) {some = true;removeIndex = index;return false;}});if (!some) {selectLabel.value.push(_label);} else {if (removeIndex >= 0) selectLabel.value.splice(removeIndex, 1);}/** 更新v-Model */updateVModel();//单选自动关闭if (!props.multiple) selectRef.value.blur();set_ElSelectTagsText();}
}
/** 暂存搜索数据 */
const _searhFilters: IFilterRule[] = [];
if (!_.isEmpty(filterField.value?.value)) {_searhFilters.push({field: filterField.value?.value, // 字段op: FilterOp.Equal, // 比较符号value: "", // 值valType: FilterValueType.String // 值类型});
}
/**翻页配置 */
const currentPage = ref(1);
// const defaultPageSize = ref(10);
const totalRecord = ref(0);
/** 翻页 */
async function handlePageChange(_currentPage) {currentPage.value = _currentPage;await getTabelData();
}
/** 获取数据信息 */
async function getTabelData(init = false) {try {loadingList.value = true;// // 数据为空时,强制设定头// if (!init) init = !_.isEmpty(tableData.value);let res: IResultTable;if (!_.isEmpty(url.value)) {res = await http.request<IResultTable>("get", url.value, {params: {searhFilters: JSON.stringify(_searhFilters.filter(x => !_.isEmpty(x))),page: currentPage.value,limit: defaultPageSize.value,sort: props.sort,order: props.order}});}if (res && res.isSuccess) {tableData.value = res.data.list;totalRecord.value = res.data.total;if (init || !inited.value) {if (!_.isEmpty(tableData.value)) {const top = tableData.value[0];const arrEntry = Object.entries(top);let i = 0;// tableColumns没有配置的字段,新增进去for (const [key, val] of arrEntry) {i++;if (i == 1) {// 配置值字段,和显示字段if (_.isEmpty(keyField.value)) {keyField.value = _.cloneDeep(key);}if (_.isEmpty(labelField.value)) {labelField.value = keyField.value;}}if (isInitColumn.value) {if (!tableColumns.value.some(x => x.prop == key))tableColumns.value.push({ label: key, prop: key });}if (isInitfilterOptions.value) {if (!filterOptions.value?.some(x => x.label == key)) {let _type: "date" | "boolean" | "string" = "string";const dateObj = dayjs(val?.toString());if (dateObj.isValid() && dateObj > dayjs("2020-01-01")) {_type = "date";}if (_.isBoolean(val)) {_type = "boolean";}const filterOption: ISearchOption = {id: i,label: key,value: key,type: _type};filterOptions.value.push(filterOption);}}}//选中第一行if (props.autoSelectFirst && _.isEmpty(props.modelValue)) {const firstRow = tableData.value[0];selectLabel.value.push(firstRow[labelField.value]);selectedRows.value.push(firstRow);} else {if (!_.isEmpty(props.modelValue)) {// 首次加载选中项if (!props.multiple) {// if (!_.isArray(props.modelValue)) {//   const seltRows = tableData.value.filter(//     x => x[keyField.value] == props.modelValue//   );//   if (!_.isEmpty(seltRows)) selectedRows.value = [seltRows[0]];// }} else {selectedRows.value = tableData.value.filter(x =>props.modelValue.some(n => n == x[keyField.value]));}selectedRows.value.forEach(item => {selectLabel.value.push(item[labelField.value]);});}}// 已初始化inited.value = true;}} else {//清空_searhFilters.splice(0, _searhFilters.length);}} else {if (!_.isEmpty(url.value))message(`获取数据出错:${res.errMessage}`, { type: "error" });}} catch (error) {message(`获取数据出错:${error.message}`, { type: "error" });} finally {loadingList.value = false;}
}
/**行class */
const tableRowClassName = ({row,_rowIndex
}: {row: any;_rowIndex: number;
}) => {if (selectedRows.value.some(x => x[keyField.value] === row[keyField.value])) {return "success-row";}if (_.isBoolean(row?._Enable) && !row._Enable) return "warning-row";return "";
};
/** 设置el-select_Tags-text Title */
function set_ElSelectTagsText() {if (!_.isEmpty(selectedRows.value)) {const maxTimes = 100;let timeNUm = 0;const _$el = selectRef.value.$el;const len = selectedRows.value.length;const interval = setInterval(() => {timeNUm++;if (timeNUm > maxTimes) {clearInterval(interval);}const elems = _$el.querySelectorAll("span.el-select__tags-text");if (elems.length === len) {console.log("selectRef",selectRef.value,_$el.querySelectorAll("span.el-select__tags-text"));elems.forEach(elem => {if (elem.innerText.indexOf("+ ") < 0) {elem.setAttribute("title", elem.innerText);}});clearInterval(interval);}}, 300);}
}
/**设置主Select-panel不关闭 */
function visibleChange(_visible) {if (!_visible) {selectRef.value.visible = true;selectRef.value.expanded = true;// selectRef.value.focus();// setTimeout(() => {// }, 100);console.log("_visible, selectRef.value");}console.log(_visible, selectRef.value);
}
/**设置主Select-panel不关闭 */
function mainVisibleChange(_visible) {selectRef.value.visible = !_visible;console.log(selectRef.value);
}
/** 监听 选中数据的修改 */
watch(selectLabel, (newval, oldval) => {if (newval.length > 0) {//清除未选择的数据oldval.forEach((x, removeIndex) => {if (!newval.some(n => n === x)) {selectedRows.value.splice(removeIndex, 1);}});} else {//清空选择的数据selectedRows.value.splice(0, selectedRows.value.length);}/** 更新v-Model */updateVModel();// if (!props.multiple) {//   if (!_.isEmpty(selectedRows.value)) {//     const newValue = selectedRows.value[0][keyField.value];//     emits("update:modelValue", newValue);//     emits("change", selectedRows.value[0]);//   } else {//     emits("update:modelValue", null);//     emits("change", null);//   }// } else {//   const newValues = selectedRows.value.map(x => x[keyField.value]);//   emits("update:modelValue", newValues);//   emits("change", selectedRows.value);// }
});
watch(() => props.modelValue,newval => {console.log("watch-props", newval, typeof newval);/** _.isEmpty 如果是int boolean,将返回true */if ((_.isNumber(newval) && (_.isNaN(newval) || newval <= 0)) ||(!_.isNumber(newval) && _.isEmpty(newval))) {selectLabel.value = [];}}
);
watch(url, (newval, oldval) => {//清空_searhFilters.splice(0, _searhFilters.length);if (_.isEmpty(newval)) {tableData.value = [];emits("update:modelValue", null);// modelValue.value = null;emits("change", null);} else if (newval != oldval) {tableData.value = [];emits("update:modelValue", null);// modelValue.value = null;emits("change", null);//链接修改重新初始化getTabelData(true).then(() => {set_ElSelectTagsText();});}
});
onMounted(async () => {await getTabelData(true);if (!_.isEmpty(props.modelValue)) {let filter = _searhFilters.find(x => x.field == keyField.value);let isNew = false;if (_.isEmpty(filter)) {isNew = true;filter = {field: keyField.value, // 字段op: props.multiple ? FilterOp.In : FilterOp.BeginsWith, // 比较符号value: "", // 值valType: FilterValueType.String // 值类型};}let filterValStr = props.modelValue;if (_.isArray(props.modelValue)) filterValStr = props.modelValue.join(",");Object.assign(filter, {field: keyField.value, // 字段op: props.multiple ? FilterOp.In : FilterOp.BeginsWith, // 比较符号value: filterValStr, // 值valType: FilterValueType.String // 值类型});if (isNew) _searhFilters.push(filter);// 没有filter 无需重新搜索if (!_.isEmpty(_searhFilters)) {// getTabelData().then(() => {//   if (_.isEmpty(selectedRows.value)) {//     const seletData = tableData.value.find(//       x => x[keyField.value] == filterValStr//     );//     if (!_.isEmpty(seletData)) {//       selectedRows.value.push(seletData);//       selectLabel.value.push(seletData[labelField.value]);//     }//   }//   set_ElSelectTagsText();// });await getTabelData();if (_.isEmpty(selectedRows.value)) {const seletData = tableData.value.find(x => x[keyField.value] == filterValStr);if (!_.isEmpty(seletData)) {selectedRows.value.push(seletData);selectLabel.value.push(seletData[labelField.value]);emits("change", selectedRows.value[0]);}}}}console.log("ComboGrid - onMounted", keyField, labelField);set_ElSelectTagsText();
});
</script>
<template><el-selectref="selectRef"clearablecollapse-tagscollapse-tags-tooltipplaceholder="Please select Data"value-key="_Id"v-model="selectLabel":multiple="true":loading="loadingList":style="{width: _.isNumber(props.width || 180)? parseInt(props.width || 180) > 1000? '100%': `${props.width || 180}px`: props.width}"@visible-change="mainVisibleChange":disabled="disabled"class="combo-grid"><template #empty><div :class="`w-[${props.panelWidth}px] m-4`"><el-card height="500px"><template #header v-if="props.searchable"><el-row :gutter="1"><el-col :span="9" :sm="7" :md="8" :lg="9" :xl="10"><el-selectref="fieldSelectRef"filterablev-model="filterField"placeholder="Select"style="width: 100%"value-key="id"@visibleChange="visibleChange"><el-optionv-for="item in filterOptions":key="item.id":label="item.label":value="item"/></el-select></el-col><el-col :span="15" :sm="17" :md="16" :lg="15" :xl="14"><el-inputv-model="searchQuery"clearable@keyup.enter="onSearch"><template #append><el-buttontype="primary":icon="useRenderIcon(iSearch)":loading="loadingList"v-auth="'view'"@click="onSearch"/></template></el-input></el-col></el-row></template><el-row><el-col :span="24"><pure-tableref="tabRef"style="width: 100%"size="small"borderfitshow-overflow-tooltip:max-height="350":data="tableData":row-key="keyField":columns="tableColumns":loading="loadingList":row-class-name="tableRowClassName"@row-click="handleRowClick":tree-props="(props.isTreeData ? props.treeProps : {}) as any":default-expand-all="props.isTreeData"/><el-paginationv-if="!props.isTreeData"size="small"layout="prev, pager, next, jumper":default-page-size="defaultPageSize":total="totalRecord"@current-change="handlePageChange"/></el-col></el-row></el-card></div></template></el-select>
</template>
<style lang="scss" scoped>
:deep(.el-card) {--el-card-padding: 6px;
}
:deep(.el-table__row) {cursor: pointer;
}
</style>
<style>
.el-table .warning-row {--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
.el-table .success-row {--el-table-tr-bg-color: var(--el-color-success-light-9);
}
</style>

types.ts

import { TableColumns } from "@pureadmin/table";export type comboGridPropType = {modelValue: any;url: string;keyField?: string;labelField?: string;filterOptions?: Array<ISearchOption>;tableColumns?: Array<TableColumns>;enableField?: string;multiple?: boolean;width?: number | string;panelWidth?: number;defaultPageSize?: number;autoSelectFirst?: boolean; //自动选择第一项sort?: string;order?: "desc" | "asc";queryOp: "Contains" | "BeginsWith" | "Equal";disabled?: boolean; //禁用searchable?: boolean; // 搜索isTreeData?: boolean; // 树结构数据treeProps?: { hasChildren?: string; children?: string };
};export interface ISearchOption {id: number;label: string;value: string;type: "string" | "boolean" | "date" | "number";
}

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

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

相关文章

Psychtoolbox 脑电实验范式之mp4视频绘制

1. 读取 首先需要使用到Screen(‘OpenMovie’)函数&#xff0c;该函数可以读取mp4、gif格式的数据&#xff0c;具体方式如下&#xff1a; clear; clc; Screen(Preference, SkipSyncTests, 1); screens Screen(Screens); screenNum max(screens); [window, screenRect] Scr…

C++语法20 一维数组及其相关问题详解

这是《C算法宝典》语法入门篇的第20节文章啦~ 如果你之前没有太多C基础&#xff0c;请点击&#x1f449;专栏&#xff1a;C语法入门&#xff0c;如果你C语法基础已经炉火纯青&#xff0c;则可以进阶算法&#x1f449;专栏&#xff1a;算法知识和数据结构&#x1f449;专栏&…

串口通信中字符和16进制显示的区别分析,串口发送数据

分析的原因 在对串口传送数值时&#xff0c;不想再进行一步字符转化&#xff0c;想要直接传送数值。但查看时就需要以16进制的数值形式查看数据&#xff0c;否则将不能看到正确的数据显示 下图是对串口寄存器发送一个16bit位的数据 void uart0Senduint16(UINT16 dat){SBUFdat…

element-plus 日期选择添加确定按钮

需求&#xff1a;选择日期后&#xff0c;点击确定按钮关闭面板 思路&#xff1a; 使用shortcuts自定义确定和取消按钮选择日期后使用handleOpen()强制开启面板点击确定后使用handleClose()关闭面板 <template><el-date-pickerref"pickerRef"v-model"…

【Android11】开机启动日志捕捉服务

一、前言 制作这个功能的原因是客户想要自动的记录日志中的报错和警告到设备的内存卡里面。虽然开发者模式中有一个“bug report” 会在/data/user_de/0/com.android.shell/files/bugreports/目录下生成一个zip包记录了日志。但是客户觉得这个日志很难获取到他们需要的信息&am…

基于盲信号处理的声音分离——基于自然梯度的ICA算法

基于自然梯度的ICA算法主要利用相互独立的随机信号的联合概率密度是各自概率密度的乘积这一特性&#xff0c;建立了等独立性度量原则&#xff0c;具体实现如下。 首先&#xff0c;输出信号 相互独立&#xff0c;则其概率密度满足 上式中 表示 的概率密度函数&#xff0c;可以…

怎么扫描图片变成pdf格式?办公人士值得收藏的宝藏工具

将图片扫描并转换为PDF格式可以通过多种途径实现&#xff0c;无论是使用专业的扫描仪还是智能手机&#xff0c;都有相应的方法。 PDF 是什么&#xff1f; PDF&#xff0c;全称为 Portable Document Format&#xff08;便携式文档格式&#xff09;&#xff0c;是由Adobe System…

12,SPI

Flash芯片&#xff1a;W25Q64&#xff0c;可以看成一个储存器 W25Q64芯片和单片机之间的通信方式是SPI SPI:串行同步全双工&#xff0c;主从通信 判断一个设备是不是SPI通信&#xff0c;看是否有这几个线&#xff1a;SCK&#xff0c;CS&#xff0c;MISO&#xff0c;MOSI SCK…

Altium Designer软件下载安装「PCB设计软件」安装包资源获取

Altium Designer作为一款集成化的电子产品开发系统&#xff0c;它主要适用于Windows操作系统&#xff0c;为电子设计工程师们提供了一个高效、便捷的工作平台。 在Altium Designer中&#xff0c;原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出…

vuex的学习

vuex vuex是个插件&#xff0c;用于多个组件操作共享变量 引入&#xff1a;数字操作案例 基于组件自定义事件而实现的操作数字案例如下&#xff1a; App.vue <template><div id"app"><input class"num_input" type"text" v…

LeeCode 994. 腐烂的橘子

原题链接994. 腐烂的橘子 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;采用bfs遍历图&#xff0c;将烂橘子加入队列&#xff0c;然后将被烂橘子感染的橘子也加入队列&#xff0c;bfs的具体细节就不多说了&#xff0c;可以自己去搜&#xff0c;很简单&#xff0c;…

560.滑动窗口最大值

滑动窗口最大值 239. 滑动窗口最大值 - 力扣&#xff08;LeetCode&#xff09; 题目大意&#xff0c;返回每个窗口内的最大值。 思路-优先队列 优先队列&#xff08;堆&#xff09;&#xff0c;其中的大根堆可以实时维护一系列元素中的最大值。 每当我们向右移动窗口时&#…

地形沉降测量仪器静力水准仪应用全攻略

在地形监测和地质勘探的领域中&#xff0c;地形沉降测量是一项至关重要的工作。它不仅能够及时揭示地质结构的变化&#xff0c;还能为城市规划和基础工程建设提供宝贵的数据支持。在众多测量工具中&#xff0c;静力水准仪以其高精度、高效率的特点&#xff0c;成为地形沉降测量…

AI绘画生成人物的关键词怎么写?手把手教你学会

AI绘画生成人物的关键词怎么写&#xff1f;随着人工智能技术的不断发展&#xff0c;AI绘画已成为艺术领域的一股新势力。特别是在生成人物绘画方面&#xff0c;AI技术以其独特的优势和无限的可能性&#xff0c;为我们带来了全新的创作体验。下面&#xff0c;本文将分享AI绘画生…

svn怎么新建分支,切换分支

在当前分支下&#xff0c;点svn右键&#xff0c;选择分支/标记 在选择远端地址时&#xff0c;点右边更多选项&#xff0c;打开远端版本库。找到对应的分支上级位置&#xff0c;点击确定 填写新分支名称&#xff0c;我这儿是将分支建在了branches下&#xff0c;分支名称为V1.1 填…

【MLP-BEV(7)】深度的计算。针孔相机和鱼眼相机对于深度depth的采样一个是均匀采样,一个是最大深度均匀采样

文章目录 1.1 问题提出1.1 看看DD3D 的深度是怎么处理的给出代码示例 1.2 我们看看BEVDepth的代码 1.1 问题提出 针孔相机和鱼眼相机的投影模型和畸变模型不一样&#xff0c;如果对鱼眼的模型不太了解可以到我的这篇博客【鱼眼镜头11】Kannala-Brandt模型和Scaramuzza多项式模…

vscode刷LeetCode算法题环境配置

首先&#xff0c;下载nodejs 在vscode中安装LeetCode插件 安装好进行配置 选择leetcode-cn 填上刚才下载node.exe的路径 完成之后重启一下vscode 重启之后登陆LeetCode 完成之后就可以看到题目了 点击 code now 就可以开始刷题了

【Linux】进程优先级 | 环境变量

目录 Ⅰ. 进程优先级&#xff08;Process Priority&#xff09; 1. 什么是进程优先级&#xff1f; 2. 查看系统进程 3. 修改进程优先级 4.优先级调度原理 Ⅱ. 进程的切换&#xff08;Process Switch&#xff09; 1. 竞争与独立 2. 并行与并发 3. 进程抢占 4.实现切换…

鸿蒙期末项目(完结)

两天仅睡3个小时的努力奋斗之下&#xff0c;终于写完了这个无比拉跨的项目&#xff0c;最后一篇博客总体展示一下本项目运行效果兼测试&#xff0c;随后就是答辩被同学乱沙&#xff08;悲 刚打开软件&#xff0c;会看到如下欢迎界面&#xff0c;介绍本app的功能和优点 随后我们…

在线开发、实时交互 | 三维天地低代码开发平台助力提高项目交付速度

1.什么是低代码开发平台? 低代码开发平台基于北京三维天地科技股份有限公司自研原生技术架构研发。三维天地作为国内知名的检验检测信息化领域软件开发服务商,拥有多项自主知识产权及自主研发核心技术,致力于为客户提供信息化整体解决方案及相关软件产品与服务。 三维天地低…