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

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


前言

今天主要学习的是关于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的变量值,
与{
   
   { }}语法基一样但不完全相同:
<h1>{
   
   {msg}}</h1>
<h1 v-text="msg"></h1>

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

如果msg中的数据是一个链接:
msg:'<a href="http://www.baidu.com">百度</a>
<h1 v-text="msg"></h1>

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

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 标记时(如: <ahref=“http://www.baidu.com”>百度),v-html 会解析 html标记,v-text 就会原样显示。
在更新数据上,我们也可以使用 Mustache 语法(即{ {}})进行更新数据,不同于 v-text、v-html 指令,{ {}}表达式只会更新原本占位插值所在的数据内容,而 v-text、v-html 指令则会替换掉整个的内容

<body>
     <!-- dom部分 view部分 -->
     <div id="app">
        <p>+++++++++ {
   
   {msg}} -----------</p>
        <p v-text="msg">=================</p>
        <p v-text="msgHtml">==============</p>
        <p v-html="msgHtml">============</p>

    </div>
    <!-- js部分 -->
    <script>
        // model部分
        var datamodel = {
      
      
            msg: "helloworld",
            msgHtml:"<a href='http://www.baidu.com'>百度</a>"
        }
        // viewmodel
        new Vue({
      
      
             el: "#app",//element
             data:datamodel
        })
    </script>
</body>

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

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

2.4、v-model

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

<div id="app">
<!--显示数据-->
{
   
   {msg}}
<!--使用v-model将input框里的数据和data中的数据进行双向绑定,
 v-model:value="msg"可以省略value成v-model="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 type="text" v-model="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=" "
<!-- 所有属性(指普通 html 属性)都一样,只要在前面加一个:
即表示访问到 vue 中的数据[属性],也就是所谓的绑定属性 -->
<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">
<!-- 普通 css 绑定 -->
<p class="fontmy">徐照兴</p>
<!-- 直接这样绑定不行,加了:表示到 vue 中去找 fontmy 属性 -->
<!-- <p :class="fontmy">徐照兴</p> -->
<!-- 正确方式 1,直接在原来的类名外面写上一对单引号 -->
<p :class="'fontmy'">徐照兴 1</p>
<!-- 正确方式 2:通过变量形式 -->
<p :class="fontmyvar">徐照兴 2</p>
<!-- 正确方式 3:应用多个样式,用数组形式,数组值为多个属性变
量值 -->
<p :class="[fontmyvar,bgmyvar]">徐照兴 3</p>
<!-- 正确方式 4(常用):json 形式,键值对,键就是样式名,值
固定为布尔型,即 true 或 false,true 表示应用该样式,false 表示不应用 -->
<!-- 当然直接写 true 或 false 也就是写死,可以用变量,比如 flag,
就这表示来自 vue 中的值 -->
<p :class="{fontmy:flag,bgmy:false}">徐照兴 4</p>
<p :class="{fontmy:num>0,bgmy:false}">徐照兴 5</p>
<!--上面键值对如果太长了,影响阅读,正确方式 5:通过变量引
用 json 形式 -->
<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>

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

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>

结果:
在这里插入图片描述
特点:当 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">
<!-- v-show 后面也可以直接跟 true 或 false,也可以使用 vue
实例中的对象(因为 v 指令都可以访问 vue 实例中的数据 -->
<div style="width:100px;height:100px;background-color:r
ed;" v-show="flag">欢迎来到徐照兴课堂</div>
<!-- 通过下面按钮来切换上面 div 的显示与隐藏 -->
<hr>
<!-- 第一种方法 -->
<!-- <button v-on:click="change">隐藏</button> -->
<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 不支持 <template> 元素,也不支持 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>

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

2.11.2、循环对象

<div id="app">
<ul>
<!-- 循环输出的是对象 users 的值 -->
<li v-for="value in user">{
   
   {value}}</li>
</ul>
<ul>
<!-- 循环输出的是对象 user 的键、值及索引 -->
<li v-for="(value,key,index) in user">{
   
   {index}}:{
   
   {key}}={
   
   {v
alue}}</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>
<!-- 循环输出的是对象 users 的值 user.属性输出具体某属性值-->
<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>

运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/dc94989f7b77409e9f5a2fccc8ccbc4c.png

2.11.4、遍历数字与字符串

<!-- 遍历数字 结果 12345-->
<span v-for="item in 5" :key="item">{
   
   { item }}</span>
<hr>
<!-- 遍历字符串结果 徐照兴 -->
<span v-for="item in '徐照兴'" :key="item">{
   
   { item }}</span

结果:
在这里插入图片描述
使用 v-for 时尽量提供 key,提高修改元素的效率

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

<div id="app">
<ul>
<li v-for="value in arr2">{
   
   {value}}</li>
<hr>
<!-- 通过指定:key 属性为每个元素绑定一个唯一的 key,其优
势是当更新元素时可重用元素提高效率 -->
<!-- 也就是说假设数组 arr2 元素值发生变化时,如果没有:key
属性,那么会把 arr2 所有值先删除再重新插入。有 key 的话就会重用
原有元素,也就是在原先基础上修改 -->
<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>
        <!-- 只绑定一次 ,后面修改了 msg 的值这里不变-->
        <h3 v-once>{
   
   {msg}}</h3>
        <!-- 这里我就想把{
    
    {}}显示出来怎么办? 加一个 v-pre 指令-->
        <h3 v-pre>{
   
   {msg}}</h3>
        <!-- <h3 v-pre>{
    
    {hello vue}}</h3> 这里如果没有 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>

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

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 的和,写{
    
    {num1+num2}} 的话num1+num2 会变成字符串的连接 -->
         <!--{
    
    {parseFloat(num1)+parseFloat(num2)}} -->
        {
   
   {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>

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

有了 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,就不会显示整个无序列表内容。

猜你喜欢

转载自blog.csdn.net/qq_46152664/article/details/124364125