一、指令的概念
Vue
中的指令就是带有v-前缀的特殊属性。
它们能扩展HTML标签的功能。
二、Vue中的基础指令
2.1 v-once
v-once
用于指定元素或者组件只渲染一次。
当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过。
该指令可以用于性能优化。
<div id="app">
<!-- 指令: v-once -->
<h2 v-once>{{ message }}</h2> <!-- 点击changeMessage按钮 这里的数据不变化 -->
<h1>{{message}}</h1> <!-- 点击changeMessage按钮 这里的数据变为 哈喽 Vue -->
<!-- 因此点击changeMessage按钮后,数据`message`是已经发生改变了的 -->
<button @click="changeMessage">改变message</button>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
message: "Hello Vue",
counter: 100
}
},
methods: {
changeMessage: function() {
this.message = "哈喽 Vue"
}
}
})
// 2.挂载app
app.mount("#app")
</script>
2.2 v-text
用于更新元素的文本内容。
<div id="app">
<!-- message对应的Hello Vue会直接被渲染到当前标签当中 -->
<h2 v-text="message">aaa</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
message: "Hello Vue"
}
},
})
// 2.挂载app
app.mount("#app")
</script>
2.3 v-html
如果我们展示的内容本身是html
的,Vue
并不会对其进行特殊的解析。
如果我们希望这个内容被Vue
可以解析出来,那么可以使用 v-html
来标识当前的元素。
<div id="app">
<h2>{{ content }}</h2> <!-- 这里的content会原样字符串展示 -->
<h2 v-html="content"></h2> <!-- 这里的content会被Vue解析成Html -->
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
content: `<span style="color: red; font-size: 30px;">v-html演示</span>`
}
},
})
// 2.挂载app
app.mount("#app")
</script>
2.4 v-pre
v-pre
用于跳过元素和它的子元素的编译过程,显示原始的Mustache
标签。
它可以跳过不需要编译的节点,加快编译的速度。
<div id="app">
<div v-pre>
<h2>{{ message }}</h2> <!-- 这里直接原样展示{{ message }},不进行编译 -->
</div>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
message: "Hello Vue",
}
},
})
// 2.挂载app
app.mount("#app")
</script>
2.5 v-cloak
给元素加一个斗篷,让元素慢慢渲染,等元素渲染完成后再显示。
-
这个指令保持在元素上直到关联组件实例结束编译。
-
这个指令可以隐藏未编译的
Mustache
标签直到组件实例准备完毕。
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app">
<h2 v-cloak></h2>
</div>
<script src="../lib/vue.js"></script>
<script>
/*
3秒内由于还没有Vue实例,因此{{message}}会原样显示
但是这样明显是不太合理的。
只要加了v-cloak指令,并且添加在css中添加[v-cloak],
那么在{{message}}没有值的时候就会按[v-cloak]中写的一样先把元素 display: none;
而是会等Vue实例创建完毕后, message有值了再再移除 display: none,从而把元素渲染出来
*/
setTimeout(() => {
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
message: "Hello Vue"
}
},
})
// 2.挂载app
app.mount("#app")
}, 3000)
</script>
2.6 v-memo(3.2版本之后才支持)
缓存一个模板的子树。在元素和组件上都可以使用。
为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。
如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。
<div id="app">
<!--
当组件重新渲染,如果 name 和 age 都保持不变。
那么这个 <div> 及其子项的所有更新都将被跳过。
其它东西变了就直接不管
-->
<div v-memo="[name, age]">
<h2>姓名: {{ name }}</h2>
<h2>年龄: {{ age }}</h2>
<h2>身高: {{ height }}</h2>
</div>
<button @click="updateInfo">改变信息</button>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
name: "lucy",
age: 18,
height: 1.88
}
},
methods: {
updateInfo: function() {
// this.name = "jack" //改变它 回去检查 v-memo所在div中的元素是否变化
// this.age = 20 //改变它 回去检查 v-memo所在div中的元素是否变化
this.height = 1.76 //改变它 不会检查 v-memo所在div中的元素是否变化
}
}
})
// 2.挂载app
app.mount("#app")
</script>
2.7 v-bind
v-bind
用于绑定一个或多个属性值,或者向另一个组件传递props值。
被绑定的值将会被Vue
管理。
- 缩写:
:
或者.
(当使用.prop
修饰符) - 期望:
any
(带参数) |Object
(不带参数) - 参数:
attrOrProp
(可选的) - 修饰符:
.camel
——将短横线命名的attribute
转变为驼峰式命名。.prop
——强制绑定为DOM property。3.2+
.attr
——强制绑定为DOM attribute。3.2+
1) 绑定属性
<div id="app">
<div>
<button @click="switchImage">切换图片</button>
</div>
<!-- 1.绑定img的src属性 -->
<img v-bind:src="showImgUrl" alt="">
<!-- 语法糖: v-bind -> : -->
<img :src="showImgUrl" alt="">
<!-- 2.绑定a的href属性 -->
<a :href="href">百度一下</a>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
imgUrl1: "test1.jpg",
imgUrl2: "test2.jpg",
showImgUrl: "test3",
href: "http://www.baidu.com"
}
},
methods: {
switchImage: function() {
this.showImgUrl = this.showImgUrl === this.imgUrl1 ? this.imgUrl2: this.imgUrl1
}
}
})
// 2.挂载app
app.mount("#app")
</script>
2) 绑定class属性
在开发中,有时候我们的元素class也是动态的。
绑定class有两种方式:
-
对象语法
-
数组语法
<div id="app">
<!-- 1.基本绑定class -->
<h2 :class="classes">Hello World</h2>
<!-- 2.动态class可以写对象语法 -->
<button :class=" isActive ? 'active': '' " @click="btnClick">对象语法1</button>
<!-- 2.1.对象语法的基本使用(常用) -->
<button :class="{ active: isActive }" @click="btnClick">对象语法2</button>
<!-- 2.2.对象语法的多个键值对 -->
<button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">多个键值对对象语法</button>
<!-- 2.3.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">动态绑定的class是可以和普通的class同时的使用1</button>
<!-- 2.4.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="getDynamicClasses()" @click="btnClick">动态绑定的class是可以和普通的class同时的使用2</button>
<!-- 3.了解下动态class可以写数组语法 -->
<h2 :class="['abc', 'cba']">Hello Array</h2>
<h2 :class="['abc', className]">Hello Array</h2>
<h2 :class="['abc', className, isActive? 'active': '']">Hello Array</h2>
<h2 :class="['abc', className, { active: isActive }]">Hello Array</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
classes: "abc cba nba",
isActive: false,
className: "why"
}
},
methods: {
btnClick: function() {
this.isActive = !this.isActive
},
getDynamicClasses: function() {
return { active: this.isActive, why: true, kobe: false }
}
}
})
// 2.挂载app
app.mount("#app")
</script>
3) 绑定style属性
我们可以利用v-bind:style
来绑定一些CSS
内联样式。
这次因为某些样式我们需要根据数据动态来决定:比如某段文字的颜色,大小等等。
CSS 属性名可以用驼峰式命名或短横线分隔来命名。
<div id="app">
<!-- 1.普通的html写法 -->
<h2 style="color: red; font-size: 30px;">啦啦啦</h2>
<!-- 2.style中的某些值, 来自data中 -->
<!-- 2.1.动态绑定style, 在后面跟上 对象类型 (常用)-->
<h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">啦啦啦</h2>
<!-- 2.2.动态的绑定属性, 这个属性是一个对象 -->
<h2 :style="objStyle">啦啦啦</h2>
<!-- 3.style的数组语法 -->
<h2 :style="[objStyle, { backgroundColor: 'purple' }]">啦啦啦</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
fontColor: "blue",
fontSize: 30,
objStyle: {
fontSize: '50px',
color: "green"
}
}
},
})
// 2.挂载app
app.mount("#app")
</script>
4) 动态绑定属性
在某些情况下,属性的名称可能也不是固定的。
一般情况下无论绑定src
、href
、class
、style
,属性名称都是固定的。
如果属性名称不是固定的,我们可以使用 :[属性名]=“值”
的格式来定义动态属性。
<div id="app">
<!-- 动态绑定name动态属性的值为test -->
<h2 :[name]="'test'">Hello Vue</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
name: "class"
}
},
})
// 2.挂载app
app.mount("#app")
</script>
4) 动态绑定对象
如果希望将一个对象的所有属性,绑定到元素上的对应属性,可以直接使用 v-bind
绑定一个 对象。
<div id="app">
<h2 :name="name" :age="age" :height="height">Hello Vue</h2>
<!-- v-bind绑定对象: 今后可以给组件传递参数, 非常有用; 此时info对象会被拆解成div的各个属性-->
<h2 v-bind="infos">Hello Bind</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
infos: { name: "why", age: 18, height: 1.88, address: "广州市" },
name: "why",
age: 18,
height: 1.88
}
},
})
// 2.挂载app
app.mount("#app")
</script>
三、如何自定义指令
3.1 概述
通常在某些情况下,需要对DOM元素进行底层操作,这个时候就会用到自定义指令;
**自定义指令分为两种: **
自定义局部指令:组件中通过 directives
选项,只能在当前组件中使用;
自定义全局指令:通过app
的 directive
方法,可以在任意组件中被使用;
3.2 使用示例–使用自定义指令自动获取元素焦点
1)自定义局部指令
<template>
<div class="app">
<input type="text" v-focus>
</div>
</template>
<!-- vue2 选项式api写法 -->
<script>
export default {
directives: {
focus: { // 此时指令的命名不需要加上v
mounted(el){ // 自定义指令的生命周期的函数
el?.focus() // ?.代表el存在才执行focus()
},
}
}
}
</script>
<!-- vue3 组合式api写法 -->
<script setup>
// 这里的命名必须以v开头,这样在使用时才可以用v-focus
const vFocus = {
mounted(el){ // 自定义指令的生命周期的函数
el?.focus() //?.代表el存在才执行focus()
},
}
</script>
2)自定义全局指令
- directives文件夹下定义focus.js存放自定义指令:
export default function directiveFocus(app) {
app.directive("focus", {
mounted(el) {
el?.focus()
}
})
}
- directives文件夹下定义index.js作为指令函数统一导出入口:
// 之所以需要这个文件,是因为如果有很多个自定义指令,在main.js中一个个注册是非常难维护的
import directiveFocus from "./focus"
export default function directives(app) {
directiveFocus(app)
}
- 在main.js中引入
import { createApp } from 'vue'
import directives from "./directives/index" // 导入directives文件夹下的index.js
createApp(App).use(directives).mount("#app") // 使用use注册全部的自定义指令
一般来说,很少去自定义指令,就算是项目中有这个需求,也一般是定义全局的,方便整个项目复用
3.3 自定义指令的生命周期
一个指令定义的对象,Vue
提供了如下的几个钩子函数:
created
:在绑定元素的 attribute
或事件监听器被应用之前调用;
beforeMount
:当指令第一次绑定到元素并且在挂载父组件之前调用;
mounted
:在绑定元素的父组件被挂载后调用;
beforeUpdate
:在更新包含组件的 VNode
之前调用;
updated
:在包含组件的 VNode
及其子组件的 VNode
更新后调用;
beforeUnmount
:在卸载绑定元素的父组件之前调用;
unmounted
:当指令与元素解除绑定且父组件已卸载时,只调用一次;
3.4 指令的参数和修饰符
比如对于下面的指令用法:
v-test:info.stop = "'message'"
v-test
:指令名称info
:指令参数的名称stop
:指令修饰符的名称
<template>
<div class="app">
<h2 v-test:info.abc.cba="message">我是h2的默认值</h2>
</div>
</template>
<script setup>
const message = 'hello directive'
const vTest = {
// el用于获得dom元素
// bindings用于获取指令参数或者修饰符
mounted(el, bindings) {
/*
bindings对象中的arg属性 可以获取到指令参数的名称 info
bindings对象中的value属性 可以获取到指令参数的值 hello directive
bindings对象中的modifiers属性 可以获取到指令的修饰符 abc cba
*/
console.log(bindings)
el.textContent = bindings.value // 用hello directive 替换 我是h2的默认值
}
}
</script>
四、Vue中的全部内置指令
https://cn.vuejs.org/api/built-in-directives.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/116488.html