> 文档中心 > vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

vue---关于我和v-on、if、for、html...这些指令之间的那些事儿


本文是我在学习vue的过程中记录学习的点点滴滴,仅仅为了学完之后巩固一下,日后忘记了也可以方便快速的复习。

vue中常用的那些指令介绍

  • 前言
  • 一、什么是指令
  • 二、指令系统
    • 2.1、v-text、v-html
    • 2.2、v-html
    • 2.3、v-text、v-html、{{ }}的正确理解与区别
    • 2.4、v-model
    • 2.5、v-cloak
      • 2.5.1、{{}}模板语法的不足
      • 2.5.2、使用 v-cloak 来解决
    • 2.6、v-bind
    • 2.7、v-bind 绑定 class 和 style 属性
    • 2.8、v-on指令及this、methods、push的含义
    • 2.9、v-if
    • 2.10、v-show
      • 2.10.1、v-show
      • 2.10.2、v-show VS v-if
    • 2.11、v-for
      • 2.11.1、循环数组
      • 2.11.2、循环对象
      • 2.11.3、循环对象数组(指数组元素值为对象)
      • 2.11.4、遍历数字与字符串
    • 2.12、v-once 与 v-pre
    • 2.12、v-model 常用的三个修饰符
      • 2.12.1、.lazy 修饰符
      • 2.12.2、.number 修饰符
      • 2.12.3、 .trim 修饰符
  • 三、v-if 与 v-for 结合使用(循环与条件的结合)

前言

今天主要学习的是关于vue中那些常用的一些指令的介绍,包括v-text、v-html、v-model、v-cloak、v-bind、 v-on、v-if、v-show、v-for


一、什么是指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute【vue 指令都以 v-开头】。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for是例外情况)

二、指令系统

2.1、v-text、v-html

{{msg}}可以用 v-text 指令替代

以下两种效果一致,都是显示data中的msg的变量值,与{{ }}语法基一样但不完全相同:

{{msg}}


v-text只会识别其中的字符串,并不会解析其中的标签

如果msg中的数据是一个链接:msg:'百度
<h1 v-text="msg"></h1>

显示结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

2.2、v-html

v-html和v-text一样都是显示文本内容,也可以替代{{}},但是v-html会解析data中msg中的标签
例如我们来对v-text和v-html进行比较

<h1>{{msg}}</h1><h1 v-text="msg"></h1><h1 v-html="msg"></h1> 

运行结果:
在这里插入图片描述

2.3、v-text、v-html、{{ }}的正确理解与区别

v-text 与 v-html 指令都可以更新页面元素的内容,不同的是,v-text 会将数据以字符串文本的形式更新,而 v-html 则是将数据以 html 标签的形式更新。当变量的值含有 html 标记时(如: 百度),v-html 会解析 html标记,v-text 就会原样显示。
在更新数据上,我们也可以使用 Mustache 语法(即{{}})进行更新数据,不同于 v-text、v-html 指令,{{}}表达式只会更新原本占位插值所在的数据内容,而 v-text、v-html 指令则会替换掉整个的内容

<body>          <div id="app"> <p>+++++++++ {{msg}} -----------</p> <p v-text="msg">=================</p> <p v-text="msgHtml">==============</p> <p v-html="msgHtml">============</p>    </div>        <script> // model部分 var datamodel = {     msg: "helloworld",     msgHtml:"百度" } // viewmodel new Vue({      el: "#app",//element      data:datamodel })    </script></body>

运行结果:
在这里插入图片描述

上面三种形式对于数据间的交互都是单向的,即只能将vue 实例里的值传递给页面,页面对数据值的任何操作却无法传递给model

2.4、v-model

在表单控件或者组件上创建双向绑定。

<div id="app">{{msg}}<input type="text" v-model="msg"></div><script>var vm= new Vue({el: '#app', data: {msg: 'hello world', }});</script>
此时改变输入框的值,data中msg的值也会跟着发生改变数据的双向绑定:{{msg}} :data.msg-->msg     :input.msg-->data.msg

再次认识 MVVM 框架
MVVM 中最重要的一个特性,可以说就是数据的双向绑定,而vue 作为一个 MVVM 框架,理所应当的实现了数据的双向绑定,所以我们可以使用内置的 v-model 指令完成数据在 View 与Model 间的双向绑定。在这里插入图片描述
当然,因为只有表单元素可以与用户进行交互,所以我们只能使用 v-model 指令在表单控件上创建双向绑定。对于组件的双向绑定,我们后续讲解。

2.5、v-cloak

2.5.1、{{}}模板语法的不足

上面{{}}模板语法还有一个不足:可能会出现闪烁问题,就是可能页面数据还没加载渲染完成,就提前看到了两对{}。
实际应用中可能就是 vue 实例中 data 数据,比如可能是通过发送异步请求获取数据,数据来自于网络(服务器),由于网络或者数据量大,需要一定的时间,这个时候 vue 中的 data 尚没有数据,就不会去渲染 view,那么在 view 中就会提前看到类似{{msg}},这就不太合适,所以需要在数据尚未渲染加载完成时不要让类似{{msg}}出现。

2.5.2、使用 v-cloak 来解决

可以使用 v-cloak 来解决。使用 v-cloak,需要配合 css 样式一起使用,否则不会生效。通过 css 样式先设置为不显示,在数据渲染完成之后就会自动修改 display

<style>[v-cloak] {display: none;}</style></head><body><div id="app"><h3 v-cloak> {{msg}}</h3></div><script>var vm = new Vue({el: '#app', data: {msg: '欢迎来到徐照兴课堂', },// 使用 created 函数作用就是测试页面尚未渲染数据时提前看到了{{}},created 是 vue 生命周期中的一个钩子函数,刚创建vue实例后立马执行钩子函数,页面尚未渲染数据created: function () {alert('vue 实例刚创建,页面尚未渲染数据')}});</script></body>

在这里插入图片描述

2.6、v-bind

v-bind 可以用来在标签上绑定标签的属性(例如:img 的 src、title 属性等等)和样式(可以用 style 的形式进行内联样式的绑定,也可以通过指定 class 的形式指定样式),同时,对于绑定的内容,是做为一个 js 变量,因此,我们可以对该内容进行编写合法的 js 表达式

语法: v-bind:属性="值"属性就是普通 html 属性,值就来自于 vue 中的数据v-bind 可以简写为:如:v-bind:src=" "简写为:src=" "
<img v-bind:src="url" :width="w" :height="h+'px'" :title="msg+'欢迎您'"

绑定的值也可以是表达式,如上述的h+'px'、msg+'欢迎您'

2.7、v-bind 绑定 class 和 style 属性

绑定 class 和 style 时语法相对比较复杂些。

1、绑定class:

:class=“fontmyvar” 双引号是到data里取数据
:class=“‘fontmy’” 要去style中取数据要再加一个单引号
:class=“[fontmyvar,bgmyvar]” 同时运用多个样式要用数组形式
:class=“{fontmy:flag,bgmy:false}” json 形式,键值对,键就是样式名,值固定为布尔型,即 true 或 false,true 表示应用该样式,false 表示不应用
this表示现在这个vue对象

<style>.fontmy{color:red;font-size:20px;}.bgmy{background-color: royalblue;}</style></head><body><div id="app"><p class="fontmy">徐照兴</p><!-- 

徐照兴

-->
<p :class="'fontmy'">徐照兴 1</p><p :class="fontmyvar">徐照兴 2</p><p :class="[fontmyvar,bgmyvar]">徐照兴 3</p><p :class="{fontmy:flag,bgmy:false}">徐照兴 4</p><p :class="{fontmy:num>0,bgmy:false}">徐照兴 5</p><p :class="varStyle">徐照兴 6</p></div><script>var vm = new Vue({el: "#app", data: {fontmyvar:'fontmy', bgmyvar:'bgmy', flag:true, num:-3, varStyle:{fontmy:true,bgmy:true// 这个地方也可使用 flag 指定,但要在前面加上 this,即 this.flag}}})</script></body>

运行效果:
在这里插入图片描述
2、绑定style:

style里面的属性名要遵循驼峰命名法,属性值需要单引号引起来。
驼峰命名法:第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采用大写字母。
vue中class使用font-size:20px,但在style中不允许使用-,直接使用驼峰命名法且属性值要用单引号:fontSize:‘20px’

<div id="app"><p :style="myStyle">徐照兴 1</p><p :style="[myStyle,myStyle2]">徐照兴 2</p></div><script>var vm = new Vue({el: "#app", data: {myStyle:{// 注意这里的属性名要使用驼峰命名法,属性值需要单引号引起来//驼峰命名法:第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采用大写字母color:'blue', fontSize:'30px' },myStyle2:{backgroundColor:'#ccc' }}})</script>

运行结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

2.8、v-on指令及this、methods、push的含义

用法:
v-on:事件名=”函数”。
事件名比如:click、dblclick、mousedown、mouseup 等等。
v-on:可以简写为@

<body>    <div id="app"> <button @click="show()">点我</button> <button v-on:click="show()">点我</button> <hr> <button @mouseover="show">鼠标经过时执行</button> <button @dblclick="show">鼠标双击时执行</button> <hr> <button @click="add">向数组中添加一个元素</button>    </div>    <script> var vm = new Vue({     el: "#app",     data: {  arr:[12,23,34,45]     },     methods: {  show() {      //    alert("1111")      console.log("这是一个show方法")  },  add(){      console.log(this)      console.log(this===vm)      this.arr.push(88)      vm.arr.push(99)      console.log(this.arr)      this.show();  }     }, })    </script></body>

结果:
在这里插入图片描述
上述项目使用了v-on和@来绑定了事件,此外绑定的事件必须要在vue实例中的methods里面定义,并且事件也可以有参数。 可以看出上述使用===号来判断this是否全等于vm这个vue实例,控制台输出为true,

2.9、v-if

v-if 指令是根据表达式的真假值判断元素的显示与否。

v-if和v-else可以组合成三种组合(语法和逻辑与平时的if-else是一样的):
单分支:v-if
双分支:v-if v-else
多分支v-if v-elseif v-else

<body>    <div id="app"><div v-if="flag">Yes</div><div v-else>no</div><div v-if="grade>90">优秀</div><div v-else-if="grade>70">中等</div><div v-else-if="grade>60">及格</div><div v-else>不及格</div>    </div>    <script> var vm = new Vue({     el: "#app",     data: {  flag:false,  grade:78     },     methods: {}, })    </script></body>

结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿
特点:当 flag 值为 false 时 dom 元素会销毁,当为 true 时又会重新创建,如下 2 个图所示。
在这里插入图片描述
在这里插入图片描述
当需要同时隐藏多个div或其他标签时可以将多个div或其他标签放入template中通过改变template的v-if属性来同时显示或隐藏多个div或其他标签

2.10、v-show

2.10.1、v-show

v-show 指令也是根据表达式的真假值判断元素的显示与否,和v-if类似。

<body>    <div id="app"><h1 v-show="flag">徐照兴欢迎您!</h1>    </div>    <script> var vm = new Vue({     el: "#app",     data: {  flag: false,     },     methods: {     }, })    </script></body>

特点:带有 v-show 的元素始终会被渲染并保留在 DOM 中。 v-show 只是简单地切换元素的 CSS 属性 display。

flag 为 true 时效果:在这里插入图片描述
flag 为 false 时效果:
在这里插入图片描述

2.10.2、v-show VS v-if

用来根据表达式的值显示或隐藏元素,v-show 是通过display 实现,显示与隐藏只是切换 display 属性;v-if 每次删除后重新创建,即显示与隐藏是在销毁与创建元素之间切换。

<div id="app"><div style="width:100px;height:100px;background-color:red;" v-show="flag">欢迎来到徐照兴课堂</div><hr><!--  --><button v-on:click="change">隐藏/显示</button><button v-on:click="flag=false">隐藏</button><button v-on:click="flag=!flag">隐藏/显示</button></div><script>var vm = new Vue({el: "#app", data: {//存储数据地方flag:true},methods:{change(){// this.flag=false;//隐藏this.flag=!this.flag;//隐藏与显示切换}}})</script>

结果:
在这里插入图片描述
使用this.flag=!this.flag;取反,可以反复单击该按钮改变flag的值并显示或隐藏上述div,为true时改为false,为false时改为true

分析:上面是通过 v-show 显示与隐藏,切换到代码查看器,会发现 div 的显示与隐藏是通过 display 是否为 none。
如果把 v-show 换成 v-if,则当 v-if 后面表达式值为 false 时,是销毁整个 div 元素,为 true 时,则重新创建。

1、v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。2、v-show 不支持  元素,也不支持 v-else。一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,当我们需要频繁控制元素的显示与否时,推荐使用v-show 指令,避免因为使用 v-if 指令而造成的高性能消耗。

2.11、v-for

v-for 指令,可以对数组、对象、数字、字符串进行循环,获取到源数据的每一个值。使用 v-for 指令,必须使用特定语法 item in items ,其中 items 是源数据(数组、字符串等),而 item 则是当前遍历的元素的别名,这里类似于 C# 中的 foreach 的循环格式。

2.11.1、循环数组

<div id="app"><ul><li v-for="value in arr">{{ value }}</li></ul></div><script>var app4 = new Vue({el: '#app', data: {arr: [1,2,3,4,5]}})</script>

运行结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

2.11.2、循环对象

<div id="app"><ul><li v-for="value in user">{{value}}</li></ul><ul><li v-for="(value,key,index) in user">{{index}}:{{key}}={{value}}</li></ul><ul></div><script>var app4 = new Vue({el: '#app', data: {arr: [1,2,3,4,5], user:{id:1,username:'张三',age:20,sex:'男'}, }})</script>

运行结果:在这里插入图片描述

2.11.3、循环对象数组(指数组元素值为对象)

<div id="app"><ul><li v-for="(user,index) in users">{{index+1}}- {{user.id}}-{{user.username}}-{{user.sex}}</li></ul></div><script>var vm = new Vue({el: '#app', data: {users:[{id:1,username:'张三',age:20,sex:'男'}, {id:2,username:'李四',age:22,sex:'女'}, {id:3,username:'王五',age:23,sex:'男'}, ]}})</script>

运行结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

2.11.4、遍历数字与字符串

<span v-for="item in 5" :key="item">{{ item }}</span><hr><span v-for="item in '徐照兴'" :key="item">{{ item }}</span

结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿
使用 v-for 时尽量提供 key,提高修改元素的效率

通过指定:key 属性为每个元素绑定一个唯一的 key(index唯一也可以),其优势是当更新元素时可重用元素提高效率。
也就是说假设数组 arr2 元素值发生变化时,如果没有:key
属性,那么会把 arr2 所有值先删除再重新插入。有 key 的话就会重用原有元素,也就是在原先基础上修改

<div id="app"><ul><li v-for="value in arr2">{{value}}</li><hr><li v-for="(value,key) in arr2" :key="key">{{value}}</li></ul></div><script>var app4 = new Vue({el: '#app', data: {arr2: [1,2,3,4,5], }})</script>

2.12、v-once 与 v-pre

v-once 只绑定一次。
v-pre 不解析{{}}

<body>    <div id="app"> <input type="text" v-model="msg">{{msg}}</input>  <h3 v-once>{{msg}}</h3>  <h3 v-pre>{{msg}}</h3> <!-- 

{{hello vue}}

这里如果没有 v-pre 指令就会报错, 因为会认为 hello vue 是 data 里的一个属性,而实际不存在,所以会报错-->
<h3 v-pre>{{hello vue}}</h3> </div> <script> var vm = new Vue({ el: "#app", data: { msg:"欢迎来到小豆子学堂" }, }) </script></body>

结果:
在这里插入图片描述

此外,v-pre指令会导致跳过这个元素和它的子元素的编译过程。加快编译。
例如:网页中的一篇文章,文章内容不需要被 Vue 管理渲染,则可以在此元素上添加 v-pre 指令,将会忽略对文章编译(也就是不去检测文章内容是否含有 vue 的语法,并对其进行解析),从而提高性能。

2.12、v-model 常用的三个修饰符

2.12.1、.lazy 修饰符

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步。也就是文本框中输入的与显示的同步,每输入一个字符都会同步显示。而可以添加.lazy 修饰符,从而转变为失去焦点同步。也就是说现在在文本框中输入字符是,msg 的值不会及时改变,要等光标移到文本框外面才同步改变。

<body>    <div id="app"><input type="text" v-model.lazy="msg">{{msg}}</input>    </div>    <script> var vm = new Vue({     el: "#app",     data: { msg:"hello"     },     })    </script></body>

结果:vue---关于我和v-on、if、for、html...这些指令之间的那些事儿
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

2.12.2、.number 修饰符

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<body>    <div id="app"><input type="text" v-model.lazy="msg">{{msg}}</input> <input type="text" v-model.lazy="num1">{{num1}}</input> <input type="text" v-model.lazy="num2">{{num2}}</input> <br>    {{num1+num2}}    </div>    <script> var vm = new Vue({     el: "#app",     data: { msg:"hello", num1:1, num2:2     },     })    </script></body>

v-model 后面加了.number,即是转为数值型数据,就只能是求和。
也可以用不加.number使用 parseInt 进行转换,即上面的注释{{parseFloat(num1)+parseFloat(num2)}},效果一样是求和。

2.12.3、 .trim 修饰符

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符

<body>    <div id="app"><input type="text" v-model.trim="msg">{{msg}}</input>     </div>    <script> var vm = new Vue({     el: "#app",     data: { msg:"hello",     },     })    </script></body>

结果:
vue---关于我和v-on、if、for、html...这些指令之间的那些事儿

有了 trim 修饰,只要光标离开了文本框在其他地方单击 下,两端若有空格就会自动去掉

三、v-if 与 v-for 结合使用(循环与条件的结合)

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,
当你只想为部分项渲染节点时,这种优先级的机制会十分有用。也就是说当 v-if 与 v-for 一起使用时,v-for 循环在外,v-if 条件判断在内部。

<body>    <div id="app"><ul>  <li v-for="item in items" v-if="item.isOK">{{item.text}}</li></ul>   </div>    <script> var vm = new Vue({     el: "#app",     data: {  arr:[1,2,3,4,5],  items:[      {text:'vue',isOK:true},      {text:'react',isOK:true},      {text:'angular',isOK:true},      {text:'html5',isOK:false},      {text:'css3',isOK:false}      ]     },     })    </script></body>

结果:
在这里插入图片描述

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素上。

<body>    <div id="app"><ul v-if="isOK">  <li v-for="item in items">{{item.text}}</li></ul>   </div>    <script> var vm = new Vue({     el: "#app",     data: {  isOK:true,  items:[      {text:'vue',isOK:true},      {text:'react',isOK:true},      {text:'angular',isOK:true},      {text:'html5',isOK:false},      {text:'css3',isOK:false}      ]     },   })    </script></body>

运行结果:
在这里插入图片描述
如果我把上面 isOK 后面的 true 改为 false,就不会显示整个无序列表内容。