Vue基础(13)_key的作用和原理

key的作用和原理

1、虚拟DOM中key的作用:

key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

2.对比规则(diff算法):

        1.旧虚拟DOM中找到了与新虚拟DOM相同的key:
                ①.若虚拟DOM中内容没变,直接使用之前的真实DOM!
                ②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

        2.旧虚拟DOM中未找到与新虚拟DOM相同的key:
                  创建新的真实DOM,随后渲染到页面。

3.用index作为key可能会引发的问题:

       1.若对数据进行:逆序添加逆序删除等破坏顺序操作;
          会产生没有必要的真实DOM更新 ==>   界面效果没问题,但效率低。

       2.如果结构中还包含输入类的DOM
             会产生错误DOM更新 ==> 界面有问题。

4.开发中如何选择key?

       1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
       2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。

举例:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <title>key的作用和原理</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h3>遍历人员列表</h3>
        <ul>
            <li v-for="(p,index) in persons" :key="index">
                {{p.name}}-{{p.age}}
                <input type="text">
            </li>
        </ul>
        <button @click.once = "addPerson">添加人员信息</button>
    </div>

    <script>
        new Vue({
            el: '#root',
            data: {
                persons: [
                    { id: '001', name: '张三', age: 18 },
                    { id: '002', name: '李四', age: 19 },
                    { id: '003', name: '王五', age: 20 }
                ]
            },
            methods: {
                addPerson() {
                    var p = { id: '004', name: '老刘', age: 30 };
                    this.persons.unshift(p);
                }
            }
        })
    </script>
</body>

</html>

把人员信息放入对应文本框后,点击添加人员信息

以上代码key的值为index或者没有key,默认都是index,虚拟DOM对比算法示意图如下:

如果key的值是p.id呢?示意图如下:

### Vue3与Vue2核心原理比较 #### 一、Vue2的核心原理 Vue2采用的是基于`patch`策略的虚拟DOM对比算法。当组件的状态发生变化时,Vue会重新构建一个新的虚拟DOM树,并将其与之前的虚拟DOM树进行比较。这种比较过程被称为`diff`算法[^1]。 在Vue2中,`diff`算法主要关注同级节点之间的差异检测。它采用了双端遍历的方式(即从头尾两端同时开始),尽可能减少不必要的节点移动操作,从而提升性能。然而,在处理大规模动态列表时,该方法可能会遇到一些瓶颈,因为它的复杂度接近O()[^2]。 #### 二、Vue3的核心改进 Vue3引入了许多新的特性以进一步优化性能表现,其中最重要的就是对`diff`算法进行了重构。相比于Vue2简单的双端匹配逻辑,Vue3实现了更加复杂的多维度优化方案: 1. **静态标记** Vue3新增了一个叫做“静态树”的概念——如果某些模板片段被识别为完全静止不变,则它们会被缓存起来并跳过后续所有的更新流程[^4]。 2. **更高效的Key索引机制** 在Vue3里,开发者可以利用唯一的key值来辅助框架快速定位特定位置上的元素实例。这不仅有助于保持状态一致性,还极大地简化了跨层间的父子关系维护工作量[^5]。 3. **最长递增子序列(LIS)** 针对手动指定keys场景下的重排问题,Vue3创造性地运用到了数学领域内的经典理论之一:“求解最长上升子序列”。具体做法是先找到当前排列中最长的那个有序部分作为基础保留下来;然后再针对剩余未命中区域单独执行局部调整动作即可完成整个任务目标。这种方法理论上时间消耗仅为线性级别(O(n log n)),远低于传统暴力枚举方式所需成本[^3]。 #### 三、Diff算法的作用 无论是Vue2还是升级后的版本,其内部都离不开这样一个重要环节—-dom patching或者说叫增量式视图同步技术。简单来说就是每当模型层面的数据发生改变之后,都需要及时反映到UI界面上让用户感知得到。但由于浏览器原生api本身存在诸多局限之处(比如频繁触发动态布局计算),因此单纯依靠直接操控真实dom往往难以满足高效需求。于是乎就有了借助中间件形式存在的virtual dom结构设计模式诞生出来解决上述难题。通过预先模拟好预期效果再统一提交给底层引擎去批量处理最终呈现出来的样子,这样既能保证准确性又能兼顾速度优势。 ```python def diff_algorithm(vnode_old, vnode_new): if not isinstance(vnode_old, dict) or not isinstance(vnode_new, dict): raise TypeError('Both nodes must be virtual DOM objects') # Compare node types and keys first. if vnode_old['type'] != vnode_new['type']: return {'replace': True} updated_props = {} old_children = vnode_old.get('children', []) new_children = vnode_new.get('children', []) # Perform a simplified version of the actual algorithm here... patches = [] min_length = min(len(old_children), len(new_children)) for i in range(min_length): child_patch = diff_algorithm(old_children[i], new_children[i]) if child_patch: patches.append((i, child_patch)) extra_additions = [{'add_at': idx} for idx in range(min_length, len(new_children))] deletions = [{'remove_idx': idx} for idx in range(min_length, len(old_children))] return { 'props': updated_props, 'patches': patches + extra_additions + deletions } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值