1. v-for遍历数组

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <!-- 1.遍历过程没有使用索引(下标值) -->
    <ul>
      <li v-for="item in names" >{{item}}</li>
    </ul>
    <!-- 2.遍历过程有使用索引(下标值) -->
    <ul>
        <li v-for="(item,index) in names"  >{{index+":"+item}}</li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        names:["zzz","ttt","yyy"]
      }
    })
  </script>
</body>
</html>

​ 一般需要使用索引值。<li v-for="(item,index) in names" >{{index+":"+item}}</li>index表示索引,item表示当前遍历的元素。

2. v-for遍历对象

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <!-- 1.遍历过程没有使用index索引-->
    <!-- 格式为:(value, name) -->
    <ul>
      <li v-for="(item,key) in user" >{{key+"-"+item}}</li>
    </ul>
    <!-- 格式为:(value, name, index) -->
    <ul>
      <li v-for="(item,key,index) in user" >{{key+"-"+item+"-"+index}}</li>
    </ul>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        user:{
          name:"zzz",
          height:188,
          age:24
        }
      }
    })
  </script>
</body>
</html>
  1. 遍历过程没有使用index索引,<li v-for="(item,key) in user" >{{key+"-"+item}}</li>,item表示当前元素是属性值,key表示user对象属性名。
  2. 遍历过程使用index索引,index表示索引从0开始。

 3. v-for使用key

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>v-for使用key</title>
</head>
<body>
  <div id="app">
    <!-- 不加key如果要插入f依次改变 -->
    <ul>
      <li v-for="item in letters">{{item}}</li>
    </ul>
    <button @click="add1">没有key</button>
    <!-- 加key如果要插入f使用diff算法高效,如果使用index做key一直变,所以item如果唯一可以使用item-->
    <ul>
        <li v-for="item in letters" :key="item">{{item}}</li>
    </ul>
    <button @click="add2">有key</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        letters:['a','b','c','d','e']
      },
      methods: {
        add1(){
          this.letters.splice(2,0,'f')
        },
        add2(){
          this.letters.splice(2,0,'f')
        }
      }
    })
  </script>
</body>
</html>
  1. 使用key可以提高效率,加key如果要插入f使用diff算法高效,如果使用index做key一直变,所以item如果唯一可以使用item。
  2. 不加key如果要插入f依次替换。 一、什么是虚拟dom? 虚拟dom 其实就是一个普通的JavaScript对象,用来描叙试图上有哪些界面结构,并不生成界面,我们可以在生命周期【mounted阶段】打印this._vnode,如下:

它描叙了该阶段是div,有 哪些子节点,哪些属性,它是采用一个js对象来描叙这些,但是它并不会显示在页面上。

 

 

 在vue中,每一个组件都有一个render函数,这个函数会生成一个虚拟dom,这就意味着每一个组件都对应一个虚拟dom树。 二、为什么需要虚拟dom? 这个主要是由vue结构所决定的,在vue中,渲染试图会调用render函数,不仅在创建视图的时候被调用,当组件所依赖的数据或者属性发生了改变的时候,也会调用render函数,如果是使用真实的dom,当创建,修改,删除,插入dom的话是非常消耗性能的,如下所示,当修改一个js对象远比操作真实的dom要有效率的多。

 

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

		2.对比规则:
		(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是没有问题的。

 

v-for加key与不加

​ 不加key渲染时候会依次替换渲染,加了key会直接将其放在指定位置,加key提升效率。 

4. 数组的响应方式

​ 我们改变DOM绑定的数据时,DOM会动态的改变值。数组也是一样的。但是对于动态变化数据,有要求,不是任何情况改变数据都会变化。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数组的响应式方法 </title>
</head>
<body>
  <div id="app">
    <!-- 数组的响应式方法 -->
    <ul>
      <li v-for="item in letters">{{item}}</li>
    </ul>
    <button @click="btn1">push</button><br>
    <button @click="btn2">通过索引值修改数组</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        letters:['a','b','c','d','e']
      },
      methods: {
        btn1(){
          //1.push
          this.letters.push('f')
          //2.pop()删除最后一个元素
          //this.letters.pop()
          //3.shift()删除第一个
          //this.letters.shift()
          //4.unshift()添加在最前面,可以添加多个
          //this.letters.unshift('aaa','bbb','ccc')
          //5.splice():删除元素/插入元素/替换元素
          //splice(1,1)在索引为1的地方删除一个元素,第二个元素不传,直接删除后面所有元素
          //splice(index,0,'aaa')再索引index后面删除0个元素,加上'aaa',
          //splice(1,1,'aaa')替换索引为1的后一个元素为'aaa'
          // this.letters.splice(2,0,'aaa')
          //6.sort()排序可以传入一个函数
          //this.letters.sort()
          //7.reverse()反转
          // this.letters.reverse()

        },
        btn2(){
          this.letters[0]='f'
        }
      }
    })
  </script>
</body>
</html>
  1. btn2按钮是通过索引值修改数组的值,这种情况,数组letters变化,DOM不会变化。

  2. 而数组的方法,例如push()pop()shift()unshift()splice()sort()reverse()等方法修改数组的数据,DOM元素会随之修改。

  3. push():在最后添加元素

    pop():删除最后一个元素

    shift():删除第一个元素

    unshift():添加在最前面,可以添加多个

    splic():删除元素、插入元素、替换元素

    splice(1,1)再索引为1的地方删除一个元素,第二个元素不传,直接删除后面所有元素

    splice(index,0,'aaa')再索引index后面删除0个元素,加上'aaa'

    splice(1,1,'aaa')替换索引为1的后一个元素为'aaa'

还可以改变其引用类型重新赋值改变

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数组的响应式方法 </title>
</head>
<body>
  <div id="app">
    <!-- 数组的响应式方法 -->
    <ul>
      <li v-for="item in letters">{{item}}</li>
    </ul>
    <button @click="btn1">push</button><br>
    <button @click="btn2">通过索引值修改数组</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        letters:['a','b','c','d','e']
      },
      methods: {
        btn1(){
          //1.push
          this.letters.push('f')
          //2.pop()删除最后一个元素
          //this.letters.pop()
          //3.shift()删除第一个
          //this.letters.shift()
          //4.unshift()添加在最前面,可以添加多个
          //this.letters.unshift('aaa','bbb','ccc')
          //5.splice():删除元素/插入元素/替换元素
          //splice(1,1)在索引为1的地方删除一个元素,第二个元素不传,直接删除后面所有元素
          //splice(index,0,'aaa')再索引index后面删除0个元素,加上'aaa',
          //splice(1,1,'aaa')替换索引为1的后一个元素为'aaa'
          // this.letters.splice(2,0,'aaa')
          //6.sort()排序可以传入一个函数
          //this.letters.sort()
          //7.reverse()反转
          // this.letters.reverse()

        },
        btn2(){
          this.letters=['a','b','dd','d','e']
        }
      }
    })
  </script>
</body>
</html>

模板占位符的使用 以前的写法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数组的响应式方法 </title>
</head>
<body>
  <div id="app">
    <!-- 数组的响应式方法 -->
    <template v-for="item in letters">
      <div>{{item}}</div>
	  <span>{{item}}</span>
    </template>
    <button @click="btn1">push</button><br>
    <button @click="btn2">通过索引值修改数组</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        letters:['a','b','c','d','e']
      },
      methods: {
        btn1(){
          //1.push
          this.letters.push('f')
        },
        btn2(){
          this.letters=['a','b','dd','d','e']
        }
      }
    })
  </script>
</body>
</html>

现在的写法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数组的响应式方法 </title>
</head>
<body>
  <div id="app">
    <!-- 数组的响应式方法 -->
    <template v-for="item in letters">
      <div>{{item}}</div>
	  <span>{{item}}</span>
    </template>
    <button @click="btn1">push</button><br>
    <button @click="btn2">通过索引值修改数组</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        letters:['a','b','c','d','e']
      },
      methods: {
        btn1(){
          //1.push
          this.letters.push('f')
        },
        btn2(){
          this.letters=['a','b','dd','d','e']
        }
      }
    })
  </script>
</body>
</html>

5. 综合练习

​ 现在要求将数组内的电影展示到页面上,并选中某个电影,电影背景变红,为选中状态。

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>综合练习</title>
  <style>
    .active {
      background-color: red;
    }
  </style>
</head>

<body>
  <div id="app">
    <!-- 数组的响应式方法 -->
    <ul>
      <li v-for="(item,index) in movies"  @click="liClick(index)" :class="{active:index===curIndex}">{{index+"---"+item}}</li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        movies: ['复仇者联盟', '蝙蝠侠', '海贼王', '星际穿越'],
        curIndex:0
      },
      methods: {
        liClick(index){
          this.curIndex = index
        }
      }
    })
  </script>
</body>

</html>
  1. 先使用v-for将电影列表展示到页面上,并获取index索引定位当前的<li>标签。
  2. 给每个<li>标签加上,单击事件,并将index传入单击事件的回调函数methods的liClick()
  3. 定义一个变量curIndex表示当前索引,初始值为0,用于表示选中状态的电影列。
  4. 定义个class样式active,在active为激活状态是, background-color: red;为红

总结: 概括 slice(start,end) 从哪到哪开始删 splice(strt,end,index1,index2) 从什么位置开始,删几个?删了后插入什么新元素? 数组中的slice()方法 ---可以用来从数组中提取指定元素 ---该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回

参数:

1.截取开始的位置的索引,包含开始索引 2.截取结束的位置的索引,不包含结束索引

  -第二个参数可以忽略不写,此时会截取从开始索引往后的所有元素   -索引可以传递一个负值,如果传递一个负值,则从后往前计算   -1 倒数第一个   -2 倒数第二个 let zm = ['a', 'b', 'c', 'd', 'e'] let rel = zm.slice(1,3) console.log(rel); 结果是: ['b','c']

let zm = ['a', 'b', 'c', 'd', 'e'] let rel = zm.slice(3) console.log(rel); 结果是: ['d','e']

let zm = ['a', 'b', 'c', 'd', 'e'] let rel = zm.slice(1,-2) console.log(rel); 结果是: ['b','c'] arr.slice(1,-2) -2表示截取到倒数第二个元素,但是不包含该元素

数组中的splice() 方法 -可以用于删除数组中的指定元素 -使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回 -参数:   第一个,表示开始位置的索引   第二个,表示删除的数量   第三个及以后。。可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边 let zm = ['a', 'b', 'c', 'd', 'e'] let rel = zm.splice(0,3) console.log(rel); //abc console.log(zm); //de

let zm = ['a', 'b', 'c', 'd', 'e'] let rel = zm.splice(4,0,'zm','xc') console.log(rel); //[] console.log(zm);//["a", "b", "c",'zm','xc','d','e']

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐