使用 Vue3 实现锚点组件

article/2025/9/7 3:39:54

目录

1. 需求介绍

2. 实现过程

2.1 表单结构介绍

2.2 确定锚点组件接收的参数及使用方法

2.2.1 form-dom:需要被锚点组件控制的表单实例

2.2.2 active-anchor:默认激活的锚点

2.2.3 title-class:表单标题特有的类名

2.2.4 将 锚点组件 挂载到 body 上

2.2.5 锚点组件使用示例

2.3 实现锚点组件基本结构

2.4 锚点组件 onMounted() 时,要执行的操作

2.4.1 从表单实例中,获取锚点列表 getAnchorList()

2.4.2 激活默认锚点,滚动到指定位置

2.4.3 添加滚动事件监听

2.4.4 给滚动事件添加防抖

2.5 滚动事件实现逻辑

2.5.1 阻止事件向上传播

2.5.2 根据表单已经滚动的高度,判断激活哪个锚点

2.6 添加锚点项点击事件

2.7 实现返回顶部按钮功能

2.8 最终代码


1. 需求介绍

 

如图所示,锚点组件实现了以下功能:

  • 锚点组件显示表单所有的标题
  • 锚点组件存在 “返回顶部” 钮
  • 当表单滚动时,锚点组件对应目录自动高亮
  • 点击锚点组件列表项时,表单滚顶到指定章节处
  • 当前激活的锚点索引应该高亮

2. 实现过程

2.1 表单结构介绍

此项目表单需要每个模块可以折叠,所以采用 ElementPlus 中的折叠面板,如下所示:

  • 使用 div 包裹所有表单内容,并定义 ref="useAnchorFormRef" 用于获取表单实例
  • 使用 el-collapse-item 包裹每一项表单内容
  • 使用 .details-container__submenu 包裹标题,该类名后面会作为锚点内部寻找标题的依据
<div ref="useAnchorFormRef" class="details-container--scroll"><el-collapse v-model="activeNames" @change="handleCollapseChange"><!-- 任务审核意见 --><el-collapse-itemv-if="type === TaskViewPageTypeEnum.check":title="TaskViewCollapseNameEnum.taskReviewComments":name="TaskViewCollapseNameEnum.taskReviewComments"><!-- 标题 --><template #title><div class="details-container__submenu">{{ TaskViewCollapseNameEnum.taskReviewComments }}</div></template><!-- 多行文本 --><el-input v-model="reviewComments" type="textarea" :disabled="true" :rows="4"></el-input></el-collapse-item></el-collapse>
</div>

2.2 确定锚点组件接收的参数及使用方法

2.2.1 form-dom:需要被锚点组件控制的表单实例

为了让表单页面中的逻辑尽量精简,只关心表单业务本身;与业务无关的逻辑(关于表单滚动监听的事件),都考虑在锚点组件中实现,因此锚点组件需要接收表单组件实例;

2.2.2 active-anchor:默认激活的锚点

有些表单,要求一进来就定位到指定的模块,激活指定的锚点

2.2.3 title-class:表单标题特有的类名

用于判断元素的 offsetTop,此处使用 .details-container__submenu 作为标题类名,可以自己定义;简单来说,我需要获取每个标题距离可视区域顶部的范围,通过类名,获取表单标题 DOM实例,进而获取 DOM 实例的 scrollTop 属性实现

综上所述,最终接收的 props 长这个样子:

props: {// 使用锚点的表单实例formDom: {type: Object,default: () => ({}),required: true,},// 默认激活哪个锚点activeAnchor: {type: Number,default: 0,},// 章节特有的类名titleClass: {type: String,default: '.details-container__submenu',},
},

 

2.2.4 将 锚点组件 挂载到 body 上

锚点组件涉及到了定位,如果直接挂载到元素内部,会被父元素的 position 影响到,而导致定位位置不可控因素变多,因此使用 teleport 将他挂载到 body 上,确保位置固定

由于锚点列表依据于表单数据,因此需要在表单实例加载完成后,才能渲染锚点组件

2.2.5 锚点组件使用示例

<!-- 锚点组件 -->
<teleport :disabled="false" to="body"><!-- form-dom:需要被锚点组件控制的表单实例 --><!-- active-anchor:默认激活的锚点,设置此项后,进入表单会自动定位锚点,并滚动到相应位置 --><!-- v-if="useAnchorFormRef" 此判断必须存在,防止传入 表单实例DOM 为空的问题 --><anchor-point v-if="useAnchorFormRef" :form-dom="useAnchorFormRef" :active-anchor="0"></anchor-point>
</teleport>

2.3 实现锚点组件基本结构

如下所示,除了需要展示锚点列表,还需要展示 返回顶部 的按钮

<div class="anchor__container"><template v-if="anchorList.length"><divv-for="node in anchorList":key="node.index"class="anchor__item":label="node.label":class="{ active: currentAnchor === node.index }"@click="handleAnchorClick(node)">{{ node.label }}</div></template><div class="anchor__return-top" @click="handleReturnTop">返回顶部</div>
</div>

2.4 锚点组件 onMounted() 时,要执行的操作

2.4.1 从表单实例中,获取锚点列表 getAnchorList()

先定义三个变量:

  • 锚点列表
  • 当前激活的锚点索引
  • 表单实例中,标题的 DOM 实例列表

响应式变量如下所示:

// 响应式变量
const state = reactive({// 锚点列表anchorList: [] as any[],// 当前激活的锚点索引currentAnchor: 0,// 表单实例中,章节 DOM 列表(锚点列表的内容就是通过这个变量填充的)titleListInForm: [] as any[],
});

 

接下来要执行这些操作:

  • 清空锚点列表
  • 根据 props.title-class 以及 querySelectorAll() 获取全部表单标题 DOM 实例,为了让 DOM 实例列表变成数组,使用 Array.form 处理他们
  • 遍历标题 DOM 列表,填充锚点列表;需要注意:要实现点击锚点,滚动到表单指定区域,就要在每一项锚点数据中,填充上当前锚点需要让表单滚动多大距离,也就是此处的 top;
/*** 从表单实例中,获取章节列表,并填充锚点列表*/
const getAnchorList = () => {// 清空锚点列表state.anchorList = [];// 获取表单实例中的章节 DOM 列表state.titleListInForm = Array.from(props.formDom.querySelectorAll(props.titleClass));// console.log('获取表单实例中的章节 DOM 列表 titleListInForm ===', titleListInForm);// 遍历章节 DOM 列表,填充锚点列表state.titleListInForm.forEach((item: any, index) => {// console.log('当前遍历的 章节 DOM item ===', item);state.anchorList.push({index, // 章节索引label: item.innerHTML || '--', // 章节内容top: item.offsetTop,titleDOM: item, // 章节完整 DOM 信息});});// console.log('填充锚点列表 state.anchorList ===', state.anchorList);
};

2.4.2 激活默认锚点,滚动到指定位置

实现思路:

  • 如果不是默认激活第一项,则要手动激活锚点项,并滚动到指定位置
  • 遍历锚点列表,寻找和当前表单所处位置(第几个)一致的锚点索引,将该锚点对应的标题组件存到临时变量中
  • 如果找到了对应的标题 DOM,则使用 el.scrollIntoView() 方法,平滑的滚动到对应位置

注意:此处应该使用定时器,否则会导致滚动不生效

// 如果默认激活的锚点,不是第一个,则要先进行一次滚动
if (props.activeAnchor !== 0) {state.currentAnchor = props.activeAnchor;// 即将滚动到的目标章节 DOMlet showTitleDomStart: any;state.anchorList.forEach((item: any) => {const indexTemp = item.index;if (props.activeAnchor === indexTemp) {showTitleDomStart = item.titleDOM;console.log('默认滚动到的 章节DOM', item.titleDOM);}});// 如果找到了符合条件的章节 DOMif (showTitleDomStart) {setTimeout(() => {// 平滑滚动showTitleDomStart.scrollIntoView({behavior: 'smooth',block: 'start',});}, 500);}
}

2.4.3 添加滚动事件监听

这里需要注意:props 传进来的 表单 DOM 实例,可以直接使用,不要添加 .value

挂载时,需要添加滚动事件监听,卸载时,要记得取消滚动事件监听

onMounted(() => {// 给表单添加滚动监听props.formDom.addEventListener('scroll', handleDebounceScroll);
});onUnmounted(() => {// 移除表单滚动监听props.formDom.removeEventListener('scroll', handleDebounceScroll);
});

2.4.4 给滚动事件添加防抖

只要页面发生变化,就会触发滚动事件;因此,一定要添加防抖事件,避免影响性能

/*** 防抖 在事件被触发一定时间后再执行回调,如果在这段事件内又被触发,则重新计时* 使用场景:* 1、搜索框中,用户在不断输入值时,用防抖来节约请求资源* 2、点击按钮时,用户误点击多次,用防抖来让其只触发一次* 3、window 触发 resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次* @param fn 回调* @param duration 时间间隔的阈值(单位:ms) 默认1000ms*/
export function useDebounce<F extends(...args: unknown[]) => unknown> (fn: F, duration = 1000):
() => void {let timeoutId: ReturnType<typeof setTimeout> | undefined;const debounce = (...args: Parameters<F>) => {if (timeoutId) {clearTimeout(timeoutId);}timeoutId = setTimeout(() => {fn(...args);timeoutId = undefined;}, duration);};return debounce;
}/*** 对滚动事件进行防抖处理,节约性能*/
const handleDebounceScroll = useDebounce(handleScroll, 200);

2.5 滚动事件实现逻辑

2.5.1 阻止事件向上传播

/*** 处理滚动事件*/
const handleScroll = (e: any) => {// console.log('处理滚动事件', e);e.stopPropagation();// 根据表单已经滚动的高度,判断激活哪个锚点activeFixedAnchor();
};

2.5.2 根据表单已经滚动的高度,判断激活哪个锚点

遍历锚点列表,如果符合以下条件,则修改激活的锚点项

  • 如果 表单滚动的高度 等于 表单标题的 offsetTop
  • 如果 表单滚动的高度 介于 当前标题节点的 offsetTop 和 下一个标题节点的 offsetTop 之间(也就是当前标题看不到了,但下一个标题还没滚动到头部)

注意:由第二条可知,我们要对比下一个节点和当前节点的 offsetTop,所以最后一个节点不可以用上述方法判断是否激活

如何判断最后一个节点呢?

如果当前表单滚动的高度 大于 最后一个标题节点的 offsetTop,则直接激活

注意:这个判断方法存在 bug,如果最后的表单内容没有那么厂,就永远不会激活最后一个节点,但是目前没找到好的解决方案

/*** 根据表单已经滚动的高度,判断激活哪个锚点*/
const activeFixedAnchor = () => {// 这里需要注意一个问题,表单实例的 scrollTop 是相对于编辑页面头部的下方开始的,而标题的 offsetTop 是相对于 微应用容器 计算的,因此要加上 65const formScrollTop = props.formDom.scrollTop + 65; // 表单的 scrollTop,默认为 0for (let k = 0; k < state.anchorList.length; k++) {if (// 如果 scrollTop 正好和标题节点的 offsetTop 相等formScrollTop === state.anchorList[k].top// 由于需要和下一个标题节点作比较,所以当前标题节点不能是最后一个|| (k < state.anchorList.length - 1// scrollTop 介于当前判断的标题节点和下一个标题节点之间&& formScrollTop > state.anchorList[k].top&& formScrollTop < state.anchorList[k + 1].top)) {// console.log('表单的 scrollTop,激活标题的 offsetTop,激活id ===', formScrollTop, state.anchorList[k].top, k);state.currentAnchor = k;break;// 如果是最后一个标题节点,只要 scrollTop 大于节点的 offsetTop 即可} else if (k === state.anchorList.length - 1) {if (formScrollTop > state.anchorList[k - 1].top) {state.currentAnchor = k;break;}}}
};

2.6 添加锚点项点击事件

参考 2.4.2 逻辑,基本一致

/*** 点击锚点列表项*/
const handleAnchorClick = (anchorInfo: any) => {// console.log('当前点击的锚点列表项 ===', anchorInfo);// 修改当前选中的锚点state.currentAnchor = anchorInfo.index;// 即将滚动到的目标章节 DOMlet showTitleDom: any;state.titleListInForm.forEach((item: any, index) => {const labelTemp = item.innerHTML;if (anchorInfo.label === labelTemp) {showTitleDom = item;}});// 如果找到了符合条件的章节 DOMif (showTitleDom) {// 平滑滚动showTitleDom.scrollIntoView({behavior: 'smooth',block: 'start',});}
};

2.7 实现返回顶部按钮功能

修改表单的 scrollTop 即可

/*** 返回顶部*/
const handleReturnTop = () => {// eslint-disable-next-line no-param-reassign, vue/no-mutating-propsprops.formDom.scrollTop = 0;
};

2.8 最终代码

<template><div class="anchor__container"><template v-if="anchorList.length"><divv-for="node in anchorList":key="node.index"class="anchor__item":label="node.label":class="{ active: currentAnchor === node.index }"@click="handleAnchorClick(node)">{{ node.label }}</div></template><div class="anchor__return-top" @click="handleReturnTop">返回顶部</div></div>
</template><script lang="ts">
import { reactive, toRefs, defineComponent, onMounted, onUnmounted } from 'vue';
// hooks 防抖
import { useDebounce } from '../hooks/common/use-debounce';export default defineComponent({name: 'AnchorPoint',props: {// 使用锚点的表单实例formDom: {type: Object,default: () => ({}),required: true,},// 默认激活哪个锚点(项目中有要求一进入某个表单时,就定位到指定锚点的需求,默认激活第一个节点)activeAnchor: {type: Number,default: 0,},// 章节特有的类名(用于判断元素的 offsetTop,5.0 里使用 .details-container__submenu 作为章节类名,也可以自己定义)titleClass: {type: String,default: '.details-container__submenu',},},setup(props, { emit }) {// 响应式变量const state = reactive({// 锚点列表anchorList: [] as any[],// 当前激活的锚点索引currentAnchor: 0,// 表单实例中,章节 DOM 列表(锚点列表的内容就是通过这个变量填充的)titleListInForm: [] as any[],});/*** 返回顶部*/const handleReturnTop = () => {// eslint-disable-next-line no-param-reassign, vue/no-mutating-propsprops.formDom.scrollTop = 0;};/*** 从表单实例中,获取章节列表,并填充锚点列表*/const getAnchorList = () => {// 清空锚点列表state.anchorList = [];// 获取表单实例中的章节 DOM 列表state.titleListInForm = Array.from(props.formDom.querySelectorAll(props.titleClass));// console.log('获取表单实例中的章节 DOM 列表 titleListInForm ===', titleListInForm);// 遍历章节 DOM 列表,填充锚点列表state.titleListInForm.forEach((item: any, index) => {// console.log('当前遍历的 章节 DOM item ===', item);state.anchorList.push({index, // 章节索引label: item.innerHTML || '--', // 章节内容top: item.offsetTop,titleDOM: item, // 章节完整 DOM 信息});});// console.log('填充锚点列表 state.anchorList ===', state.anchorList);};/*** 点击锚点列表项*/const handleAnchorClick = (anchorInfo: any) => {// console.log('当前点击的锚点列表项 ===', anchorInfo);// 修改当前选中的锚点state.currentAnchor = anchorInfo.index;// 即将滚动到的目标章节 DOMlet showTitleDom: any;state.titleListInForm.forEach((item: any, index) => {const labelTemp = item.innerHTML;if (anchorInfo.label === labelTemp) {showTitleDom = item;}});// 如果找到了符合条件的章节 DOMif (showTitleDom) {// 平滑滚动showTitleDom.scrollIntoView({behavior: 'smooth',block: 'start',});}};/*** 根据表单已经滚动的高度,判断激活哪个锚点*/const activeFixedAnchor = () => {// 这里需要注意一个问题,表单实例的 scrollTop 是相对于编辑页面头部的下方开始的,而标题的 offsetTop 是相对于 微应用容器 计算的,因此要加上 65const formScrollTop = props.formDom.scrollTop + 65; // 表单的 scrollTop,默认为 0for (let k = 0; k < state.anchorList.length; k++) {if (// 如果 scrollTop 正好和标题节点的 offsetTop 相等formScrollTop === state.anchorList[k].top// 由于需要和下一个标题节点作比较,所以当前标题节点不能是最后一个|| (k < state.anchorList.length - 1// scrollTop 介于当前判断的标题节点和下一个标题节点之间&& formScrollTop > state.anchorList[k].top&& formScrollTop < state.anchorList[k + 1].top)) {// console.log('表单的 scrollTop,激活标题的 offsetTop,激活id ===', formScrollTop, state.anchorList[k].top, k);state.currentAnchor = k;break;// 如果是最后一个标题节点,只要 scrollTop 大于节点的 offsetTop 即可} else if (k === state.anchorList.length - 1) {if (formScrollTop > state.anchorList[k - 1].top) {state.currentAnchor = k;break;}}}};/*** 处理滚动事件*/const handleScroll = (e: any) => {// console.log('处理滚动事件', e);e.stopPropagation();// 根据表单已经滚动的高度,判断激活哪个锚点activeFixedAnchor();};/*** 对滚动事件进行防抖处理,节约性能*/const handleDebounceScroll = useDebounce(handleScroll, 200);onMounted(() => {// console.log('锚点组件内,获取滚动表单实例 ===', props.formDom);// 从表单实例中,获取章节列表,并填充锚点列表getAnchorList();// 如果默认激活的锚点,不是第一个,则要先进行一次滚动if (props.activeAnchor !== 0) {state.currentAnchor = props.activeAnchor;// 即将滚动到的目标章节 DOMlet showTitleDomStart: any;state.anchorList.forEach((item: any) => {const indexTemp = item.index;if (props.activeAnchor === indexTemp) {showTitleDomStart = item.titleDOM;console.log('默认滚动到的 章节DOM', item.titleDOM);}});// 如果找到了符合条件的章节 DOMif (showTitleDomStart) {setTimeout(() => {// 平滑滚动showTitleDomStart.scrollIntoView({behavior: 'smooth',block: 'start',});}, 500);}}// 给表单添加滚动监听props.formDom.addEventListener('scroll', handleDebounceScroll);});onUnmounted(() => {// 移除表单滚动监听props.formDom.removeEventListener('scroll', handleDebounceScroll);});return {...toRefs(state),handleReturnTop,handleAnchorClick,};},
});
</script><style lang="scss" scoped>
.anchor__container {position: fixed;top: 50%;right: 46px;overflow: auto;box-sizing: border-box;width: 300px;height: 180px;padding: 12px;background: rgba(255, 0, 0, 0.4);transform: translate(0, -50%);
}.anchor__item {overflow: hidden;box-sizing: border-box;width: 100%;margin: 4px 0;padding: 4px;background: rgba(255, 255, 0, 0.2);text-overflow: ellipsis;white-space: nowrap;cursor: pointer;
}.anchor__return-top {position: absolute;bottom: 0;padding: 4px 0;background: rgba(0, 0, 255, 0.2);color: blue;cursor: pointer;
}.active {color: yellow;
}
</style>


http://chatgpt.dhexx.cn/article/TU2iPu3W.shtml

相关文章

快速了解什么是锚点

一、什么锚点 锚点是网页制作中超级链接的一种&#xff0c;又叫命名锚记&#xff0c;像一个迅速定位器一样&#xff0c;是一种页面内的超级链接。 二、身边的锚点案例 1、我们可以在百度百科中搜索【薛之谦】 薛之谦&#xff08;中国内地男歌手、音乐制作人、演员&#xff09…

KNN的数据插补方法总结

sklearn中的KNN在缺失值填补中的用法 参考链接&#xff1a;K近邻填补缺失值 如果缺失值是离散的&#xff0c;使用K近邻分类器&#xff0c;投票选出K个邻居中最多的类别进行填补&#xff1b;如果为连续变量&#xff0c;则用K近邻回归器&#xff0c;拿K个邻居中该变量的平均值填…

KNN算法优缺点总结,以及机器学习流程的总结

KNN算法作为一个最简单&#xff0c;也是一个很实用的机器学习的算法&#xff0c;日常的使用中也能处理很多问题&#xff0c;这里做一下总结记录 优点 1、KNN可以处理分类问题&#xff0c;同时天然可以处理多分类问题&#xff0c;比如鸢尾花的分类 2、简单&#xff0c;易懂&a…

(理论+代码)KNN算法

KNN&#xff1a; 一种非参数、惰性学习方法&#xff0c;导致预测时速度慢当训练样本集较大时&#xff0c;会导致其计算开销高样本不平衡时&#xff0c;对稀有类别的预测准确率低KNN模型的可解释性不强 文章目录 KNN&#xff08;思想&#xff1a;物以类聚&#xff09;一、 距离度…

Knn算法实例(代码来自机器学习实战,我加了详细的注释,仅供学习)

knn算法代码 Knn算法—识别手写数字&#xff08;机器学习实战&#xff09; 一、Knn算法原理&#xff1f; 1.通俗的说就是&#xff1a;对于给定的输入向量在训练集中找到与该输入实例最近的k个实例&#xff0c;统计这k个实例中每个实例&#xff08;按照标签分类&#xff09;所…

KNN数据库检索(简读):A Fast Partial Video Copy Detection Using KNN and Global Feature Database

与之前的大部分部分视频拷贝检测&#xff08;PVCD&#xff09;算法不同&#xff0c;该算法会逐个扫描参考视频&#xff0c;我们将PVCD视为视频搜索/检索问题。 本文提出了一种快速的部分视频拷贝检测框架。在这个框架中&#xff0c;参考视频的所有帧CNN-feature都组织在…

KNN的优化算法2:KD-tree

传统KNN缺点&#xff1a;数据量特别大时&#xff0c;需要计算参考点和每个样本点的距离&#xff0c;计算量非常大&#xff0c;所以提出一种优化算法-----kd-tree. 为了提高kNN搜索的效率&#xff0c;可以考虑使用特殊的结构存储训练数据&#xff0c;以减小计算距离的次数。 kd…

KNN算法及其MATLAB代码

一、KNN算法原理 1.算法概述 k近邻(k-Nearest Neighbor&#xff0c;简称kNN)学习是一种常用的监督学习方法&#xff0c;其工作机制非常简单&#xff1a;给定测试样本&#xff0c;基于某种距离度量找出训练集中与其最靠近的k个训练样本&#xff0c;然后基于这k个"邻居&qu…

kNN算法解析及应用【内附详细代码和数据集】

首先&#xff0c;我们需要了解什么是“kNN” kNN英文全称k Nearest Neighbor&#xff0c;即k近邻算法。 用途&#xff1a;分类问题kNN的工作原理&#xff1a;事先有一个有标签的样本数据集&#xff0c;然后输入没有标签的新数据后&#xff0c;将新数据的每个特征和样本集里的数…

KNN算法介绍及代码实现

k-近邻法简介 k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法。它的工作原理是&#xff1a;存在一个样本数据集合&#xff0c;也称作为训练样本集&#xff0c;并且样本集中每个数据都存在标签&#xff0c;即我们知道样本集中每一个数…

机器学习——KNN及代码实现

KNN KNN即k-nearest neighbor(k近邻法)&#xff0c;多应用于分类问题。 k近邻法的输入为实例的特征向量&#xff0c;对应于特征空间中的点。输出为实例的类别。 K近邻法原理 给定一个训练数据集&#xff0c;对新的输入数据&#xff0c;在训练数据集中找到与该实例最邻近的k个…

KNN算法及其改进

KNN算法优缺点 优点 (1) 精度高 (2) 对异常值不敏感&#xff1a;某个异常值对整个结果不造成影响&#xff1b; (3) 无数据输入假定&#xff1a;无数据的独立性等假设&#xff1b;缺点 (1) 计算复杂度高&#xff1a;因为要计算的点需要与所有点计算距离&#xff0c;所以复杂度很…

机器学习算法-KNN代码实现

机器学习算法-KNN代码实现 一、KNN算法初步理解二、代码实现1.数据集处理2.创建model3.可视化 总结 一、KNN算法初步理解 统计学习方法书上的解释&#xff1a;给定一个训练数据集&#xff0c;对于新的输入实例&#xff0c;在训练数据集中找到与该实例最邻近的k个实例&#xff…

【数据挖掘基础】——KNN算法+sklearn代码实现(6)

🤵‍♂️ 个人主页:@Lingxw_w的个人主页 ✍🏻作者简介:计算机科学与技术研究生在读 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 介绍算法的例子 KNN算法原理

KNN的优化算法1:距离加权

参考文章&#xff1a;https://www.cnblogs.com/bigmonkey/p/7387943.html 对参考文章中最后一部分说的有问题的地方进行了修改。 权值加权&#xff1a;为每个点的距离增加一个权重&#xff0c;使得距离近的点可以得到更大的权重&#xff0c;在此描述如何加权。 反函数 该方法最…

机器学习之深入理解K-means、与KNN算法区别及其代码实现

K-means方法是一种非监督学习的算法&#xff0c;它解决的是聚类问题。 1、算法简介&#xff1a;K-means方法是聚类中的经典算法&#xff0c;数据挖掘十大经典算法之一&#xff1b;算法接受参数k,然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足聚类中的对象…

KNN算法代码实现

原理&#xff1a; KNN 算法也叫K近邻算法。假设给定一个训练数据集&#xff0c;其中的实例类别已定。它是通过找到一个数据集中与目标数据最近的K个邻居&#xff0c;然后通过多数表决等方式来预测目标数据的分类结果进行预测。 三要素&#xff1a; 距离度量、K值、分类决策规…

KNN中的优化算法KD-tree

我们知道KNN是基于距离的一个简单分类算法&#xff0c;熟悉KNN的都知道&#xff0c;我们要不断计算两个样本点之间的距离&#xff0c;但是&#xff0c;试想一下&#xff0c;如果数据量特别大的时候&#xff0c;我们要每个都计算一下&#xff0c;那样计算量是非常大的&#xff0…

KNN算法代码

一、K近邻算法 KNN是一种监督学习类别的算法&#xff0c;全称&#xff08;K-NearestNeighbor&#xff09;直译为K个最近的邻居&#xff0c;是一种聚类算法。该算法认为我们在判断一个物体的类别可以根据与他非常相似的K个物体的类别&#xff08;这K个物体的类别是已知的&#x…

KNN数据缺失值填充(附源码和数据)不调用包

KNN估计 数据缺失值填充—KNN估计一、基本思想二、步骤1.导入数据2.查看空缺值3.取出要分析的数据4.计算平均值5.计算标准差6.规范化7.计算欧几里得距离8.最优解9.画图 总结 数据缺失值填充—KNN估计 运行环境 python3.6 jupyter notebook 一、基本思想 先将数据标准化&…