单独使用v-if,变量为布尔值,为true才渲染DOM
<h1 v-if="isScore"> v-if 这次测验熏悟空考了: {{score}}分h1>
联合使用相当于if、elseif、else,但是在条件比较多的时候建议使用计算属性。
- <h1 v-if="score<60">分数小于60分h1>
- <h1 v-else-if="score<90">分数大于60分 小于90分h1>
- <h1 v-else="">不及格h1>
通过样式display:block来显示 当值为假时,通过display:none来隐藏
<h2 v-show="isShow">v-show 我只是隐藏了h2>
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Documenttitle>
- <script src="./vue.js">script>
- head>
-
- <body>
- <div id="app">
-
-
- <h1 v-if="isScore"> v-if 这次测验熏悟空考了: {{score}}分h1>
-
- <h2 v-show="isShow">v-show 我只是隐藏了h2>
- <button @click="isScore=!isScore,isShow=!isShow">切换button>
- <hr>
-
- <h1 v-if="score<60">分数小于60分h1>
- <h1 v-else-if="score<90">分数大于60分 小于90分h1>
- <h1 v-else="">不及格h1>
- div>
- <script>
- var vm = new Vue({
- el: '#app',
- data() {
- return {
- score: 50,
- isScore: true,
- isShow: true
- }
- }
-
- })
- script>
- body>
-
- html>
由此我们的到结论如下
1. v-if 在首次渲染的时候,如果条件为假,什么也不操作,页面当作没有这些元素。当条件为真的时候,开始局部编译,动态的向DOM元素里面添加元素。当条件从真变为假的时候,开始局部编译,卸载这些元素,也就是删除。
说白了就是当布尔值为真的时候,向DOM元素中添加元素,布尔值为假的时候 卸载元素或者说删除元素
2. v-show 不管条件是真还是假,第一次渲染的时候都会编译出来,也就是标签都会添加到DOM中。之后切换的时候,通过display: none;样式来显示隐藏元素。可以说只是改变css的样式,几乎不会影响什么性能。
简而言之 就是 布尔值为真时,通过样式display:block来显示 值为假时,通过display:none来隐藏
一般需要使用索引值。 index表示索引,item表示当前遍历的元素。
<li v-for="(item,index) in names" >{{index+":"+item}}li>
来吧直接上代码,操作起来
- 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>Documenttitle>
- head>
-
- <body>
- <div id="app">
-
- <ul>
- <li v-for="item in names">{{item}}li>
- ul>
-
- <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>
遍历过程使用index索引,index表示索引从0开始。
item表示当前元素是属性值,key表示user对象属性名。
<li v-for="(item,key) in user" >{{key+"-"+item}}li>
- 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>Documenttitle>
- head>
-
- <body>
- <div id="app">
-
-
- <ul>
- <li v-for="(item,key) in user">{{key+"-"+item}}li>
- ul>
-
- <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>
①,当我们在使用v-for
时,需要给单元加上key
<li v-for="item in items" :key="item.id">什么是key值li>
②,用+new Date()
生成的时间戳作为key
,手动强制触发重新渲染
<Comp :key="+new Date()" />
简单的来讲 key 就是给节点添加一个唯一值,能让浏览器引擎 快速,准确无误找到节点
给v-for
需要给单元加上key
创建一个实例,3秒后往items
数组插入数据
- 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>Documenttitle>
- <script src="../Vue/vue.js">script>
- head>
-
- <body>
- <div id="demo">
- <p v-for="(item,index) in items" :key="item">{{item}}---{{index}}p>
- div>
- <script>
- // 创建实例
- const app = new Vue({
- el: '#demo',
- data: { items: ['a', 'b', 'c', 'd', 'e'] },
- mounted () {
- setTimeout(() => {
- this.items.splice(2, 0, 'f') //
- }, 3000);
- },
- });
- script>
-
- body>
-
- html>
效果图展示
在不使用key
的情况,vue
会进行这样的操作:
分析下整体流程:
patch
,但数据相同,不发生dom
操作patch
,但数据相同,不发生dom
操作patch
,数据不同,发生dom
操作patch
,数据不同,发生dom
操作patch
,数据不同,发生dom
操作DOM
中一共发生了3次更新,1次插入操作
在使用key
的情况:vue
会进行这样的操作:
patch
,但数据相同,不发生dom
操作patch
,但数据相同,不发生dom
操作patch
,但数据相同,不发生dom
操作patch
,但数据相同,不发生dom
操作patch
,但数据相同,不发生dom
操作一共发生了0次更新,1次插入操作
虚拟dom 其实就是一个普通的JavaScript对象,用来描叙试图上有哪些界面结构,并不生成界面,我们可以在生命周期【mounted阶段】打印this._vnode,如下:
它描叙了该阶段是div,有 哪些子节点,哪些属性,它是采用一个js对象来描叙这些,但是它并不会显示在页面上。
在vue中,每一个组件都有一个render函数,这个函数会生成一个虚拟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是没有问题的。