首页 > 其他分享 >关于Vue的就地更新策略的解析

关于Vue的就地更新策略的解析

时间:2023-08-14 22:36:56浏览次数:38  
标签:count index Vue text app 更新 解析 id

在这里插入图片描述

在Vue中使用v-for渲染列表时,默认使用就地更新策略。该策略默认是基于索引的,规定在列表绑定的数据元素顺序变化时,不会重新创建整个列表,而只是更新对应DOM元素上的数据。以下代码实现了一个TODO列表的勾选、添加和删除功能:

<!DOCTYPE html>
<html>

<head>
    <title>In-Place Update Example</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <ul>
            <li v-for="(todo, index) in todos" :key="index">
                <input type="checkbox" v-model="todo.completed">
                {{ todo.text }}
                <button @click="removeTodo(index)">Remove</button>
            </li>
        </ul>
        <button @click="addTodo">Add Todo</button>
    </div>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                todos: [
                    { text: 'Learn Vue.js', completed: false },
                    { text: 'Build an app', completed: true },
                    { text: 'Deploy to production', completed: false }
                ]
            },
            methods: {
                removeTodo(index) {
                    this.todos.splice(index, 1);
                },
                addTodo() {
                    this.todos.push({ text: 'New Todo', completed: false });
                }
            }
        });
    </script>
</body>

</html>

该策略模式是高效的,避免了大量的DOM重排重绘。

然而,该策略基于一个前提:列表项内部的内容不依赖于子组件的状态或临时的DOM状态。如违背该前提,就可能导致意外,因为Vue不会重新创建子组件或恢复临时DOM状态。

下面代码实现了v-for列表项内容依赖于子组件的状态而导致意外的情况:

<!DOCTYPE html>
<html>

<head>
    <title>In-Place Update with Child Component</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用 v-for 渲染子组件列表 -->
        <child-component v-for="(item, index) in itemList" :key="index"
         @remove="removeItem(index)"></child-component>
    </div>

    <script>
        Vue.component('child-component', {
            template: `
        <div>
            <!-- 子组件的内容和状态 -->
            <button @click="increment">{{ count }}</button>
            <!-- 删除 -->
            <button @click="$emit('remove')">删除</button>
        </div>
      `,
            methods: {
                increment() {
                    this.count++;
                }
            },
            data(){
                return{
                    count:0
                }
            }
        });

        const app = new Vue({
            el: '#app',
            data: {
                itemList: new Array(5).fill(null)
            },
            methods: {
                removeItem(index) {
                    this.itemList.splice(index, 1);
                }
            }
        });
    </script>
</body>

</html>

我们先点击某项计数器,再删除该项:

在这里插入图片描述

为了解决该问题,我们为每一项绑定一个唯一的key属性:

<!DOCTYPE html>
<html>

<head>
    <title>In-Place Update with Child Component</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用 v-for 渲染子组件列表 -->
        <child-component v-for="(item, index) in itemList" :key="item.id"
         @remove="removeItem(index)"></child-component>
    </div>

    <script>
        Vue.component('child-component', {
            template: `
        <div>
            <!-- 子组件的内容和状态 -->
            <button @click="increment">{{ count }}</button>
            <!-- 删除 -->
            <button @click="$emit('remove')">删除</button>
        </div>
      `,
            methods: {
                increment() {
                    this.count++;
                }
            },
            data(){
                return{
                    count:0
                }
            }
        });

        const app = new Vue({
            el: '#app',
            data: {
                // 为每一项添加一个id
                itemList: [
                    { id: 0 },
                    { id: 1 },
                    { id: 2 }
                ]
            },
            methods: {
                removeItem(index) {
                    this.itemList.splice(index, 1);
                }
            }
        });
    </script>
</body>

</html>

效果如下:

在这里插入图片描述

那么就有疑问了:为什么前面代码中的key属性绑定了index没有用呢,index难道不是唯一的吗?很简单,这是由于我们删除的是数据项,而不是数组索引,使用id就不会有这个问题,删除一项连带着删除了该唯一id。

标签:count,index,Vue,text,app,更新,解析,id
From: https://www.cnblogs.com/LiJunLin1231/p/17629952.html

相关文章

  • 2019考研英语(一)小作文真题解析与参考 Aiding Rural Primary Schools 答复信
    2019考研英语(一)小作文真题解析与参考Directions:Supposeyouareworkingforthe“AidingRuralPrimarySchools” projectofyouruniversity.Writeanemailtoanswertheinquiryfromaninternationalschoolvolunteer,specifyingthedetailsoftheproject.Yous......
  • Step-by-step to LSTM: 解析LSTM神经网络设计原理
    Ps:喂喂喂,你萌不要光收藏不点赞呀_(:з」∠)_emmmm...搞清楚LSTM中的每个公式的每个细节为什么是这样子设计吗?想知道simpleRNN是如何一步步的走向了LSTM吗?觉得LSTM的工作机制看不透?恭喜你打开了正确的文章!零、前置知识1:在上一篇文章《前馈到反馈:解析RNN》中,小夕从最简单的无......
  • Vue computed 计算属性语法
    1.不传参import{ref,computed}from"vue";letcarnoColor=computed(()=>{returnformatterCarnoColor(model.value.carnoColor)}) 2.传参<divv-for="iteminlist"><divv-if='isShow(item)'>是否显示</div......
  • 2-04-Nacos配置管理-配置热更新-not practice
    所谓的热更新共有两种实现方式1.@Value+@Refresh针对单一类的配置热更新2.@ConfigurationProperties+@Autowired,针对所有类的配置热更新......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——机器学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点关......
  • 高德解析城市的分析,根据高德的经纬度获取城市cityCode
    高德解析城市的分析,根据高德的经纬度获取城市cityCodehttp://restapi.amap.com/v3/geocode/regeo?output=json&location=110.517039,18.817948&key=替换成自己的高德KEY&extensions=base1.高德返回城市(正常情况)江苏省南京市玄武区"city":"南京市","province":"江苏省",&qu......
  • React和Vue的区别,大家怎么看?
    Vue更适合小项目,React更适合大公司大项目;Vue的学习成本较低,很容易上手,但项目质量不能保证......真的是这样吗?借助本篇文章,我们来从一些方面的比较来客观的去看这个问题。 论文档的丰富性从两个方面来看这个问题:社区的支持力度及文档的完善性。 对于任何编程语......
  • vue3 使用 vue-i18n 配置多语言环境
    1.插件地址:VueI18n官方文档GitHub地址2.安装:在Vue之后引入vue-i18n,它会自动安装:<scriptsrc="https://unpkg.com/vue/dist/vue.js"></script><scriptsrc="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script>NPM:npminstallv......
  • Vuejs装饰器风格开发教程(前言、模板项目、类属性、类方法)
    教程前言AOP切面编程是面向对象开发中的一种经典的编程范式,旨在将横切关注点与核心业务逻辑分离来提高代码的模块性和可维护性。如:日志记录、事务管理等就属于横切关注点。在为H5提供Android原生支持时,曾将插件模块改造为AOP模式,实现插件的自动注册。Java领域的SpringBoo......
  • 【产品人卫朋】专栏及配套资料更新:华为流程体系、产品经理、IPD与BLM模型
    目录前言01华为流程体系专栏02产品经理进阶专栏03华为战略方法论专栏04IPD进阶100例专栏作者介绍前言截止目前,本号已上线四大干货专栏,内容涉及:01华为流程体系(图文+视频);02硬件产品经理(图文+视频);03BLM战略方法论(图文+视频);04集成产品开发IPD体系(图文)。四大专栏具体内容......