vue-for(注意点)

简介: vue-for(注意点)

vue-for注意点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" @click.prevent="add">
    </form>
    <ul>
        <li v-for="(person,index) in persons">
            <input type="checkbox">
            <span>{{index}}--{{person.name}}</span>
        </li>
    </ul>
</div>
<script>
    let vue=new Vue({
        el:"#app",
        data:{
            name:"",
            persons:[{
                name:"zs"
            },{
                name:"ls"
            },{
                name:"ww"
            }],
        },
        methods:{
            add() {
                let newPerson={name:this.name};
                this.persons.push(newPerson);
                this.name='';
            }
        }
    });
</script>
</body>
</html>

10.png


push.png

add() {
                let newPerson={name:this.name};
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name='';
            }


12.png

13.png

为什么会出现这个问题?

因为v-for是采用“就地复用”的原则提高渲染性能的

  • v-for在渲染元素的时候会先查看有没有需要渲染的元素
  • 如果缓存中没有渲染的元素,就会创建一个新的放到缓存中进行渲染;如果缓存中有需要渲染的元素,则不会创建新的,直接复用原来的数据
    注意点:在vue中只要数据发生了变化,则会自动重新渲染,“数据驱动界面”

怎样解决这个问题?

给每一个渲染的元素加上一个key,key的取值必须为独一无二的

<li v-for="(person,index) in persons" :key="person.id">

同时创建元素时给每个persons里的对象添加一个独一无二的ID,实现代码如下:

<script>
    let vue=new Vue({
        el:"#app",
        data:{
            name:"",
            persons:[{
                name:"zs",id:1
            },{
                name:"ls",id:2
            },{
                name:"ww",id:3
            }],
        },
        methods:{
            add() {
                let lastPerson=this.persons[this.persons.length-1];
                console.log(lastPerson.id);
                let newPerson={name:this.name,id:lastPerson.id+1};
                console.log(newPerson);
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name='';
            }
        }
    });
</script>


14.png



注意点:不能用index作为:key,因为index虽然是以独一无二的,但是可以是同步变化的

具有动画的添加和删除案例(列表动画

  • 引出transition-group

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .v-enter{
            opacity: 0;
        }
        .v-enter-active{
            transition: all 3s;
        }
        .v-enter-to{
            opacity: 1;
        }
        .v-leave{
            opacity: 1;
        }
        .v-leave-active{
            transition: all 3s;
        }
        .v-leave-to{
            opacity: 0;
        }
    </style>
</head>
<body>
<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" @click.prevent="add">
    </form>
    <ul>
        <transition-group appear>
            <li v-for="(person,index) in persons" :key="person.id" @click.prevent="del(index)">
                <input type="checkbox">
                <span>{{index}}--{{person.name}}</span>
            </li>
        </transition-group>
    </ul>
</div>
<script>
    let vue=new Vue({
        el:"#app",
        data:{
            name:"",
            persons:[{
                name:"zs",id:1
            },{
                name:"ls",id:2
            },{
                name:"ww",id:3
            }],
        },
        methods:{
            add() {
                let lastPerson=this.persons[this.persons.length-1];
                console.log(lastPerson.id);
                let newPerson={name:this.name,id:lastPerson.id+1};
                console.log(newPerson);
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name='';
            },
            del(index){
                this.persons.splice(index, 1);
            }
        }
    });
</script>
</body>
</html>

列表动画的注意点

  1. <transition-group>标签会自动给需要做动画的元素添加一个<span></span>将其包起来,但是这样是不合理的,我们可以通过在transition-group标签上添加tag属性来指定添加什么元素作为需要执行动画的父元素16.png


我们删除原有的ul标签,给transition标签添加tag="ul"则可达到一样的效果

<!--    <ul>-->
        <transition-group appear tag="ul">
            <li v-for="(person,index) in persons" :key="person.id" @click.prevent="del(index)">
                <input type="checkbox">
                <span>{{index}}--{{person.name}}</span>
            </li>
        </transition-group>
<!--    </ul>-->


18.png


  1. 列表动画引起的key混乱
    添加了tag之后新增元素就没有动画了,反而第一次添加的那个数据发生动画,这个现象叫做“动画混乱”
    为什么会发生这种想现象呢?因为最后一个元素的ID一直没有变,所以新添加的元素的key都是一样的,又由于v-for“就地复用”的原则,就发生了动画混乱
    解决方案,代码如下:

将最后一个元素的ID直接设置给data中的add,在执行add方法时,首先将this.id自增,然后直接将自增后的id赋值给新增的person的id,就可以解决动画混乱的问题了

<script>
    let vue=new Vue({
        el:"#app",
        data:{
            name:"",
            persons:[{
                name:"zs",id:1
            },{
                name:"ls",id:2
            },{
                name:"ww",id:3
            }],
            id:3
        },
        methods:{
            add() {
                this.id++;
                // let lastPerson=this.persons[this.persons.length-1];
                console.log(id);
                let newPerson={name:this.name,id:id};
                console.log(newPerson);
                // this.persons.push(newPerson);
                this.persons.unshift(newPerson);
                this.name='';
            },
            del(index){
                this.persons.splice(index, 1);
            }
        }
    });
</script>




目录
相关文章
|
3月前
|
JavaScript
Vue——initInjections【九】
Vue——initInjections【九】
32 1
|
3月前
|
JavaScript
Vue——mergeOptions【四】
Vue——mergeOptions【四】
26 4
|
3月前
|
JavaScript
mojs——在Vue中使用mojs
mojs——在Vue中使用mojs
41 0
|
6月前
|
缓存 JavaScript 前端开发
hello Vue
hello Vue
53 6
|
6月前
|
JavaScript 前端开发 编译器
Vue2跟Vue3的对比
Vue2跟Vue3的对比
96 0
|
设计模式 缓存 JavaScript
|
12月前
|
资源调度 JavaScript Linux
VUE使用总结
VUE使用总结
49 0
|
移动开发 前端开发 JavaScript
认识并了解Vue
认识并了解Vue
101 0
认识并了解Vue
|
存储 数据处理
Vue3中shallowRef和shallowReactive的使用?
Vue3中shallowRef和shallowReactive的使用?
132 0
|
JavaScript 前端开发 API
详解——Vue小总结
详解——Vue小总结
94 0