【后端速成 Vue】初识指令(上)

前言:

Vue 会根据不同的指令,针对标签实现不同的功能。

在 Vue 中,指定就是带有v- 前缀 的特殊 标签属性,比如:

html 复制代码
<div v-html='str'> </div>

这里问题就来了,既然 Vue 会更具不同的指令,实现不同的功能,那么这个 v-html 是实现什么功能的呢?


1、v-html

v-html:设置元素的 innerHTML

如何不知道元素的 innerHTML 是什么的话,可以先去学习一下 js。

现在有这样一个需求,有一个 div,需要动态的将一个 a 标签加入到这个 div 中。

于是有的小伙伴就很聪明,上篇文章不是讲过插值表达式嘛,这简单,直接使用插值表达式就行了嘛:

html 复制代码
<body>
    <div id="app">
        {{ msg }}
    </div>
</body>
<!-- 开发版本引入包/生产版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            msg: '<a href="#">程序猿教你打篮球的博客</a>'
        }
    })
</script>

但是这样运行代码发现:

由此得知,插值表达式不具备解析标签的能力!

这时 v-html 就发挥出他的作用了:

html 复制代码
<body>
    <div id="app" v-html="msg">
        
    </div>
</body>
<!-- 开发版本引入包/生产版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            msg: '<a href="#">程序猿教你打篮球的博客</a>'
        }
    })
</script>

运行结果:

这样一来,就能正确的解析标签了,当然,想要理解这个,还是需要 js 的基础,如果没有 js 的基础,不建议着急学 Vue 哦!

通过 DOM 页面,也能看出来使用插值表达式和v-html的区别:


2、v-show 和 v-if

这两个功能类似,但是也有区别,所以这里放在一起对比讲解。先说他们两个的作用:

**v-show:**控制元素显示隐藏

语法:v-show="表达式" 表达式值为 true 显示,为 false 隐藏

**v-if:**控制元素显示隐藏(条件渲染)

语法:v-if="表达式" 表达式值为 true 显示,为 false 隐藏

这里写一段代码,来方便理解:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            margin: 10px;
            width: 150px;
            height: 100px;
            text-align: center;
            line-height: 100px;
            border: 1px solid black;
            border-radius: 10px;
            box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
        }
    </style>
</head>
<body>
    <div id="app">
        <div v-show="flag" class="box"> v-show 容器</div>
        <div v-if="flag" class="box"> v-if 容器</div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            flag: true
        }
    })
</script>
</html>

执行结果:

此时 app 实例中的 flag 的值是 true,显然这两个盒子都会显示,如果把 flag 设置成 false 呢?

javascript 复制代码
const app = new Vue({
    el: '#app',
    data: {
        flag: false
    }
})

很明显,这两个 div 都被隐藏了,满足上面讲的 v-show 和 v-if 的作用,但是上面强调过,v-show 和 v-if 的区别是:v-if 是条件渲染的,当然从显示上来看并不好发现 v-show 和 v-if 的区别。

这里可以在打开页面调试,也可以直接按 F12,或者右键'检查':

这里可以发现,使用 v-show 的 div 是通过设置 css 里的 display 属性来实现隐藏这个元素的。而 v-if 的 div 是通过条件判断进行创建和移除元素的(条件渲染)!

既然他们实现原理不同,那么他们的肯定有适用不同的使用场景:

v-show 更适合频繁显示隐藏的场景

v-if 适合不频繁显示隐藏的场景

由于 v-if 是根据条件判断来创建元素和移除元素的,本质还是在操作 DOM 树,所以效率显然是没有 v-show 高的,但使用 v-if 可以减少页面的冗余元素,因为 v-show 本质上元素还是在 DOM 树上的,所以在频繁切换隐藏显示的常见推荐用 v-show,不频繁时推荐使用 v-if。

举个例子,当鼠标滑过某个元素,需要展示详细信息,这时肯定使用 v-show 更合适,当用户登录了,不用显示登录逻辑元素了,这时肯定使用 v-if 更合适。


3、v-else 和 v-else-if

这俩就像 Java,C++,JavaScript 中的 else 和 else if 一样搭配 if 使用的,而 这里的 v-else 和 v-else-if 也是需要搭配 v-if 来使用的!

语法:v-else ,v-else-if="表达式"

注意:这两个需要紧挨着 v-if 一起使用。

案例需求:当 sex = 1 时,表示男生,当 sex = 2 表示女生,这两种情况之外,就定义为火星人,没有性别:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p v-if="sex === 1">性别: 🚹 男</p>
        <p v-else-if="sex === 2">性别: 🚺 女</p>
        <p v-else>火星人没有性别</p>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            sex: 1
        }
    })
</script>
</html>

4、v-on

作用:注册事件 = 添加监听 + 提供处理逻辑

语法:

① v-on:事件名 = "内联语句"

② v-on:事件名 = "methods 中的函数名"

什么叫做内联语句?简单来说就是一段可执行代码,比如 count++

案例需求:有两个按钮,分别是针对 count 进行 ++ -- 操作:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button v-on:click="count--">-</button>
        <span>{{ count }}</span>
        <button v-on:click="count++">+</button>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            count: 100
        }
    })
</script>
</html>

这里给第一个按钮注册了 click 监听事件,每次 click 一下就会使得 count--,由于 Vue 是响应式的,所以当 count 的值发生了变化,随之页面展示的 count 数据也会发生改变。

第二个按钮也注册了 click 监听事件,只是这个事件要处理的逻辑是 count++,于是每次点击第二个按钮,都会使 count 的值发生改变,当 Vue 监听到值发生变化了,随即就会重新渲染页面的数据了。

由于注册事件用的还是蛮多的,每次都写 v-on: 显然太麻烦了,于是 Vue 提供了一个简写,可以使用 @ 代替 'v-on:',上面的代码也可以改写成这个样子:

html 复制代码
<body>
    <div id="app">
        <button @click="count--">-</button>
        <span>{{ count }}</span>
        <button @click="count++">+</button>
    </div>
</body>

在实际中,通常会使用这种简写的方式。

截至目前为止,讲解的 v-on 注册的事件执行逻辑都是内联语句,内联语句只适合逻辑简单的代码,如果逻辑复杂,代码量长了,这时就需要用到第二种语法形式了。

在实例 Vue 对象的时候,目前已经见到了两个配置项,分别是 el,data,现在就需要来认识第三个配置项 methods 了。

在这个 methods 配置项中,可以提供很多方法供 Vue 实例使用。

案例需求:有一个 button 和 span,单击 button 显示 span 中的内容,再次单击隐藏 button 隐藏 span 中的内容:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 这里传要执行的函数名 -->
        <button @click="fn">切换显示隐藏</button>
        <span v-show="isShow">篮球哥</span>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            isShow: true
        },
        methods: {
            fn() {
                this.isShow = !this.isShow
            }
        }
    })
</script>
</html>

这里 button 绑定了一个单击事件,执行的逻辑是 fn 这个函数,在 fn 函数中,对 isShow 这个变量的值进行了修改。

此时注意,在 fn 中是不能直接访问 isShow 的,因为 js 会把 isShow 当作成一个全局变量,而这里的 isShow 是 app 这个实例的 isShow 变量,也可以使用 app.isShow,但是这样如果外面的 app 实例名改了,里面的 fn 也需要更改,于是 Vue 就让所有 methods 配置项中的函数的 this 都指向当前实例!

也即 this.isShow === app.isShow

看到这,细心的小伙伴就会发现,这里写函数名,那万一这个函数有参数应该怎么写呢?很简单,加上这个函数要传递的参数即可,比如:

html 复制代码
<button @click="fn(1, 2)">按钮</button>

案例需求:实现一个功德器,有两个按钮,分别对应认真工作,功德加1,摸鱼一会,功德减10,单击对应按钮增加或减少对应功德,初始功德 10:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            margin: 10px;
            width: 300px;
            height: 150px;
            text-align: center;
            border: 1px solid black;
            border-radius: 10px;
            box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="box">
            <h1>功德器</h1>
            <button @click="update(1)">认真工作(+1  功德)</button>
            <button @click="update(-10)">摸鱼一会(-10功德)</button>
        </div>
        <p>功德值: {{ count }}</p>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            count: 10
        },
        methods: {
            update(number) {
                this.count = this.count + number
            }
        }
    })
</script>
</html>

运行结果:


5、v-bind

上一篇文章讲解到的插值选择器是不能作用于 html 的标签属性的,比如:

html 复制代码
<!-- 错误写法 -->
<a href="{{url}}">程序猿教你打篮球</a>

作用: v-bind 就是动态的设置 html 的标签属性,比如 src,href,title,placeholder...

语法: v-bind:属性名="表达式"

案例需求:有一个input txt 输入框,要求通过 v-bind 动态设置标签的属性:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    </style>
</head>
<body>
    <div id="app">
        <input type="text" v-bind:placeholder="msg" v-bind:title="inputTitle">
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            msg: "你好呀",
            inputTitle: 'hello'
        }
    })
</script>
</html>

运行结果:

这样写代码冗余性太高了,那么多 v-bind,能不能跟 v-on 一样可以简写呢?当然可以,只是跟 v-on 简写有点不同,v-bind 可以直接去掉 v-bind,比如 :title="inputTitle"

上述的代码也可以替换成如下这样:

html 复制代码
<input type="text" :placeholder="msg" :title="inputTitle">

下期预告:【后端速成Vue】初识指令(下)

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax