工具代码(持续更新)
1.去除后端返回的html标签
// 去除后端返回的html标签
stripHtml(html) {
const tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
return tempDiv.innerText || tempDiv.textContent || "";
}
使用:
<el-table-column prop="demandDescribe" :label="$t('project.public.remarks')" show-overflow-tooltip>
<template slot-scope="scope">
<div v-text="stripHtml(scope.row.demandDescribe)"></div>
<!-- <span v-html="scope.row.demandDescribe"></span> -->
</template>
</el-table-column>
2.存储数据及取用数据
最好写在utils下边,命名local.js
export default {
// 获取本地存储的数据
get(key) {
return JSON.parse(localStorage.getItem(key));
},
// 设置本地存储中的数据
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
// 清除本地存储
clear() {
localStorage.clear();
}
};
存储:
godownClick(row) {
if (row.headerIds.includes(String(this.nickID))) {
local.set("GodownInfo", row); //存储
this.$router.push({
path: "/material/materials/goods-shelves" //跳转到货架管理
});
} else {
this.$message.warning("你不是此仓库的负责人,无法查看该仓库 !");
return;
}
},
使用:
mounted() {
this.infoRow = local.get("GodownInfo"); //取用
},
3.防抖
/**
* 防抖
* @param {*} fn //一个需要进行防抖处理的原函数fn
* @param {*} delay //延迟执行的时间delay(单位为毫秒)
* @returns
* import { debounce, throttle } from "@/utils/yuUtils.js";
* debounce_sureDialogTransferClick: debounce(function (val) {
this.sureDialogTransferClick(val);
}, 800),
*/
export function debounce(fn, delay) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
}
使用:
// 防抖(判断调用)
debounce_onConfirm: debounce(function (type) {
if (type === "save") {
this.changeInfo();
} else {
this.onConfirm();
}
//this.onConfirm();
}, 500),
debounce_getComfirm: debounce(function () {
this.getComfirm();
}, 500),
4.节流
/**
* 节流
* @param {*} fn //一个需要进行防抖处理的原函数fn
* @param {*} delay //延迟执行的时间delay(单位为毫秒)
* @returns
*/
export function throttle(fn, delay) {
let canRun = true;
return function (...args) {
if (!canRun) return;
canRun = false;
setTimeout(() => {
fn.apply(this, args);
canRun = true;
}, delay);
};
}
5.el-input需要数值时不能为负数
防止手输入负数
<el-form-item label="数量" prop="amount">
<el-input v-model.number="Addform.amount" type="number" :min="1">
<!-- <template slot="append">{{ $t('project.task.hour') }}</template> -->
</el-input>
</el-form-item>
<el-form-item label="单价" prop="unitPrice">
<el-input v-model="Addform.unitPrice"></el-input>
</el-form-item>
rules: {
amount: [
{ required: true, message: "请选择数量", trigger: "change" },
{ pattern: /^[0-9|^\\.]/, message: "数量不能为负数" }
],
unitPrice: [{ pattern: /^[0-9|^\\.]/, message: "单价不能为负数" }]
},
6.根据后端返回标签内的字段高亮并且在渲染是去除html标签
// 处理 HTML 内容,先保留 <em> 标签内容背景色,再去除其他标签
const stripHtml = (html) => {
// 创建一个临时容器
const tempDiv = document.createElement('div');
tempDiv.innerHTML = html;
// 找到所有 <em> 标签并设置其样式
const emTags = tempDiv.getElementsByTagName('em');
Array.from(emTags).forEach((em) => {
// 用 span 替代 <em> 标签并设置背景色
const span = document.createElement('span');
span.style.backgroundColor = '#eff4ff';
span.style.padding = '2px';
span.style.borderRadius = '4px';
span.style.color = '#6698ff';
// span.style.fontWeight = 'bold';
span.innerHTML = em.innerHTML; // 将 <em> 标签中的内容放入 <span> 中
em.replaceWith(span); // 替换 <em> 标签为 <span>
});
// 返回处理过的 HTML 内容(将其他标签移除,只保留纯文本和带样式的 <span>)
return tempDiv.innerHTML;
};
7.table滚动加载(vue3)
<el-table
v-loading="tableLoading"
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
:highlight-current-row="true"
:height="tableHeight"
class="tableClass scrollTable"
:class="[isTableTopMoreText ? 'table_top_more' : '']"
:row-style="{ height: '50px' }"
:header-row-style="{ height: '50px' }"
:row-class-name="tableRowClassName"
@selection-change="handleSelectionChange"
@row-dblclick="handleRowDblClick"
@row-click="handleRowClick"
@row-contextmenu="rowContextmenuClick"
@sort-change="changeTableSort"
>
</el-table>
const tableHeight = ref(0);
onMounted(() => {
apiFilesTreeQuery();
tableHeight.value = window.innerHeight - 98;
window.onresize = () => {
//浏览器窗口变动的时候
tableHeight.value = window.innerHeight - 98;
};
});
const scrollTableDom: any = ref('');
onMounted(() => {
// 查找表格滚动区域的 DOM 元素,并将其赋值给 scrollTableDom
scrollTableDom.value = document.querySelector('.scrollTable .el-table__body-wrapper .el-scrollbar__wrap');
// 为该元素添加 'scroll' 事件监听器,滚动时调用 handleTableScroll 函数
scrollTableDom.value.addEventListener('scroll', handleTableScroll);
});
onUnmounted(() => {
// 在组件销毁时清除存储的 'expandedKeys' 数据
sessionStorage.removeItem('expandedKeys');
// 移除滚动事件监听器,避免内存泄漏
scrollTableDom.value.removeEventListener('scroll', handleTableScroll);
});
//计算到最低端的滚动条位置(debounce 防抖方法)
const handleTableScroll = debounce((event) => {
// 获取触发事件的目标 DOM 元素,即滚动容器
const table = event.target;
// 计算滚动条距离底部的距离
const scrollPosition = table.scrollHeight - table.scrollTop - table.clientHeight;
// console.log('🚀 ~ handleTableScroll ~ scrollPosition:', scrollPosition);
// 如果滚动条距离底部小于等于 5 像素,表示用户已接近底部
if (scrollPosition <= 5) {
apiTreeFileSelectTreePage('');
// console.log(1234);
}
}, 300);
7.el-autocomplete下拉加载更多(vue3)
<div class="page_vue1" v-else>
<div class="slotClass">
<!-- v-scrollLoad="querySearchLoad" -->
<!-- 搜索 -->
<div class="searchBox">
<el-autocomplete
ref="autocompleteRefs"
v-model="searchInput"
:fetch-suggestions="querySearch"
placeholder="请输入搜索内容"
class="searchInput"
@select="handleSelectSearch"
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
<template #default="{ item }">
<div class="content_box" v-infinite-scroll="querySearchLoad">
<div class="searchInput_name">
<svg-icon :icon-class="selectSvgIcons(item)" style="font-size: 20px; vertical-align: middle; margin-right: 6px"></svg-icon>
<div>{{ item.realName }}{{ item.suffix ? `.${item.suffix}` : '' }}</div>
</div>
<div v-if="item.docContent" class="search_docContent" v-html="esSearchFunc(item.docContent)"></div>
<div class="superiorsPath">
<span>路径:{{ item.superiorsPath }}</span>
</div>
</div>
</template>
</el-autocomplete>
</div>
</div>
<el-button link @click="closeClick">取消</el-button>
</div>
.page_vue1 {
display: flex;
justify-content: space-between;
align-items: center;
height: 48px;
padding: 6px;
border-bottom: 1px solid #eee;
}
.searchInput {
height: 300px;
border: none;
width: 100%;
}
.content_box {
width: 170px !important;
border-bottom: 1px solid #efefef;
}
.searchInput_name {
width: 100%;
display: flex;
align-items: center;
div {
// width: 10px;
overflow: hidden;
/*内容超出后隐藏*/
text-overflow: ellipsis;
/*超出内容显示为省略号*/
white-space: nowrap;
/*文本不进行换行*/
}
}
.search_docContent {
font-size: 12px;
color: #939292;
line-height: 22px;
}
.superiorsPath {
font-size: 12px;
color: #d6d6d6;
line-height: 22px;
text-align: right;
overflow: hidden;
/*内容超出后隐藏*/
text-overflow: ellipsis;
/*超出内容显示为省略号*/
white-space: nowrap;
/*文本不进行换行*/
}
/**搜索----start */
const autocompleteRefs = ref();
const searchInput = ref('');
const searchStr = ref({
page: 0,
pageCount: null,
list: []
});
const suggestions = ref([]); // 用来存储 suggestions 数据
const searchLoading = ref(false); //用于搜索的滚动加载
const selectedItem = ref(null);
const isSearchMore = ref(true);
/**搜索----end */
//搜索
const querySearch = (queryString, cb) => {
if (searchInput.value == '' && searchInput.value != undefined) {
cb([]);
return;
}
searchStr.value.page = 0;
let oParam = {
type: props.pageType,
size: 20,
realName: searchInput.value,
page: searchStr.value.page
};
ApiPerselectPersonalTreePage(oParam).then((res: any) => {
searchStr.value.page += 1;
searchStr.value.pageCount = res.data.pageCount;
searchStr.value.list = res.data.children;
if (res.data.totalCount == 0) {
ElMessage.warning('未匹配到数据,请重新输入!');
}
// 调用 callback 返回建议列表的数据
cb(res.data.children);
});
};
// 滚动加载
const querySearchLoad = debounce(() => {
if (searchStr.value.page > searchStr.value.pageCount) {
// this.divider = true;
return;
}
if (!searchLoading.value) {
searchLoading.value = true;
let oParam = {
type: props.pageType,
size: 20,
realName: searchInput.value,
page: searchStr.value.page
};
ApiPerselectPersonalTreePage(oParam).then((res: any) => {
searchLoading.value = false;
searchStr.value.page += 1;
searchStr.value.pageCount = res.data.pageCount;
autocompleteRefs.value.suggestions = autocompleteRefs.value.suggestions.concat(res.data.children); //加载出来的数据放到suggestions中
});
}
}, 300);
推荐阅读:
扫描二维码,在手机上阅读