Vue--列表

Vue--列表,第1张

列表目录 列表渲染key的原理列表过滤watch实现computed实现


列表渲染

v-for事实上跟for循环的逻辑类似,遍历数组、对象、字符串、固定数值,遍历所给的参数也是不一样的
数组=(obj, index)
对象=(value, key)
字符串=(char, index)
固定数值(number, index)
这里面的:key原则上是必须要设置的,一般设置为index(key),如果不设置vue不会报错,但是在react会报错。

<div id="testBox">
    <ul>
        <!--这里in变成of也可以-->
        <!--遍历数组-->
        <li v-for="(p,index) in persons" :key="index">
            {{p.name}}:{{p.age}}-{{index}}
        </li><br />
        <!--遍历对象-->
        <li v-for="(value,key_index) in person" :key="key_index">
            {{value}}-{{key_index}}
        </li><br />
        <!--遍历字符串-->
        <li v-for="(char,index) in str" :key="index">
            {{char}}-{{index}}
        </li><br />
        <!--遍历数字-->
        <li v-for="(number,index) in 5" :key="index">
            {{number}}-{{index}}
        </li>
    </ul>
</div>
<script type="text/javascript">
    new Vue({
        el:'#testBox',
        data:{
            persons:[
                {name:'野原新之助', age: '6岁'},
                {name:'野原广志', age: '35岁'},
                {name:'野原美伢', age: '29岁'}
            ],
            person: {
                name: '野原新之助',
                age: '6岁',
                hobby: '喜欢漂亮的大姐姐'
            },
            str: '野原新之助'
        }
    })
</script>


key的原理

简单来说,key的作用就是在虚拟DOM对比算法的时候对比的关键字段。
实际上当用index作为key的情况,只要不打乱index,就不会出现问题,一旦打乱:
1.有输入类表单元素,每个元素的index发生改变,key从而发生改变,就形成了一连串的错位对比。
2.没有输入类表单元素。会造成不必要的真实Dom更新,影响效率(当key对应上的时候,事实上会直接用之前的真实Dom进行使用)。
所以当要打乱index顺序的时候,直接用事先设置好的id(后端数据库会有)
3.因此用id不会出错的原因是,id与数据是绑定在一起的,不管怎么样都不会形成错位对比。
4.如果只是展示作用的,用index也没问题(就是不会有类似按钮之类的添加元素)。

以用index为key做例子(用唯一id的情况跟这个类似)

<div id="testBox">
    <ul>
        <li v-for="(p,index) in persons" :key="index">
            {{p.name}}:{{p.age}}-<input type="text">
        </li><br />
        <button @click.once="addPeople">加个人</button>
    </ul>
</div>
<script type="text/javascript">
    new Vue({
        el:'#testBox',
        data:{
            persons:[
                {id:'001', name:'野原新之助', age: '6岁'},
                {id:'002', name:'野原广志', age: '35岁'},
                {id:'003', name:'野原美伢', age: '29岁'}
            ],
            
        },
        methods: {
            addPeople() {
                const newObj = {id:'004', name:'卖间久里代', age: 'unKnown'};
                this.persons.unshift(newObj);
            }
        },
    })
</script>

对于没有用key的情况,vue默认用index作为它的key。


列表过滤 watch实现
<div id="testBox">
    <ul>
    	<!-- 表单的双向绑定用v-model -->
        <input type="text" v-model="keyword">
        <li v-for="(p,index) in newPersons" :key="index">
            {{p.name}}:{{p.age}}
        </li><br />
    </ul>
</div>
<script type="text/javascript">
    new Vue({
        el:'#testBox',
        data:{
            keyword:'',
            persons:[
                {id:'001', name:'野原新之助', age: '6岁'},
                {id:'002', name:'野原广志', age: '35岁'},
                {id:'003', name:'广场舞', age: '29岁'},
                {id:'003', name:'舞蹈', age: '29岁'}
            ],
            //使用空数组接收新数据,避免改变原数据使搜索内容越来越少
            newPersons:[]
        },
        watch:{
            keyword:{
            	/*默认一进去就执行handler,也就是在没
            	输入的时候就调一次,让旧数组的内容给新数组*/
                immediate: true,
                handler(value) {
                	/*filter实现过滤功能,但是不改变原数据,
                	而是产生新数据,所以需要接收*/
                    this.newPersons = this.persons.filter((p)=>{
                    	/*index用来判断里面有没有相应的内容
                    	有的话返回索引值,没有的话返回-1*/
                        return p.name.indexOf(value) !== -1;
                    })
                }
            }
        }
    })
</script>


computed实现
<div id="testBox">
    <ul>
        <input type="text" v-model="keyWord">
        <!-- 这里计算属性得用到,不然就没效果了 -->
        <li v-for="(p,index) in filFun" :key="index">
            {{p.name}}:{{p.age}}
        </li><br />
    </ul>
</div>
<script type="text/javascript">
    new Vue({
        el:'#testBox',
        data:{
            keyWord:'',
            persons:[
                {id:'001', name:'野原新之助', age: '6岁'},
                {id:'002', name:'野原广志', age: '35岁'},
                {id:'003', name:'广场舞', age: '29岁'},
                {id:'003', name:'舞蹈', age: '29岁'}
            ]
        },
        computed: {
            filFun() {
                return this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyWord) !== -1;
                })
            }
        }
    })
</script>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1320141.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-11
下一篇 2022-06-11

发表评论

登录后才能评论

评论列表(0条)

保存