Vue
中的指令就是带有v-前缀的特殊属性。
它们能扩展HTML标签的功能。
v-once
用于指定元素或者组件只渲染一次。
当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过。
该指令可以用于性能优化。
<div id="app">
<h2 v-once>{{ message }}h2>
<h1>{{message}}h1>
<button @click="changeMessage">改变messagebutton>
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>
用于更新元素的文本内容。
<div id="app">
<h2 v-text="message">aaah2>
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>
如果我们展示的内容本身是html
的,Vue
并不会对其进行特殊的解析。
如果我们希望这个内容被Vue
可以解析出来,那么可以使用 v-html
来标识当前的元素。
<div id="app">
<h2>{{ content }}h2>
<h2 v-html="content">h2>
div>
<script src="../lib/vue.js">script>
<script>
// 1.创建app
const app = Vue.createApp({
data: function() {
return {
content: `v-html演示`
}
},
})
// 2.挂载app
app.mount("#app")
script>
v-pre
用于跳过元素和它的子元素的编译过程,显示原始的Mustache
标签。
它可以跳过不需要编译的节点,加快编译的速度。
<div id="app">
<div v-pre>
<h2>{{ message }}h2>
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>
给元素加一个斗篷,让元素慢慢渲染,等元素渲染完成后再显示。
这个指令保持在元素上直到关联组件实例结束编译。
这个指令可以隐藏未编译的 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>
缓存一个模板的子树。在元素和组件上都可以使用。
为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。
如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。
<div id="app">
<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>
v-bind
用于绑定一个或多个属性值,或者向另一个组件传递props值。
被绑定的值将会被Vue
管理。
:
或者 .
(当使用 .prop
修饰符)any
(带参数) |Object
(不带参数)attrOrProp
(可选的).camel
——将短横线命名的 attribute
转变为驼峰式命名。.prop
——强制绑定为 DOM property。3.2+
.attr
——强制绑定为 DOM attribute。3.2+
<div id="app">
<div>
<button @click="switchImage">切换图片button>
div>
<img v-bind:src="showImgUrl" alt="">
<img :src="showImgUrl" alt="">
<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>
在开发中,有时候我们的元素class也是动态的。
绑定class有两种方式:
对象语法
数组语法
<div id="app">
<h2 :class="classes">Hello Worldh2>
<button :class=" isActive ? 'active': '' " @click="btnClick">对象语法1button>
<button :class="{ active: isActive }" @click="btnClick">对象语法2button>
<button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">多个键值对对象语法button>
<button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">动态绑定的class是可以和普通的class同时的使用1button>
<button class="abc cba" :class="getDynamicClasses()" @click="btnClick">动态绑定的class是可以和普通的class同时的使用2button>
<h2 :class="['abc', 'cba']">Hello Arrayh2>
<h2 :class="['abc', className]">Hello Arrayh2>
<h2 :class="['abc', className, isActive? 'active': '']">Hello Arrayh2>
<h2 :class="['abc', className, { active: isActive }]">Hello Arrayh2>
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>
我们可以利用v-bind:style
来绑定一些CSS
内联样式。
这次因为某些样式我们需要根据数据动态来决定:比如某段文字的颜色,大小等等。
CSS 属性名可以用驼峰式命名或短横线分隔来命名。
<div id="app">
<h2 style="color: red; font-size: 30px;">啦啦啦h2>
<h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">啦啦啦h2>
<h2 :style="objStyle">啦啦啦h2>
<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>
在某些情况下,属性的名称可能也不是固定的。
一般情况下无论绑定src
、href
、class
、style
,属性名称都是固定的。
如果属性名称不是固定的,我们可以使用 :[属性名]=“值”
的格式来定义动态属性。
<div id="app">
<h2 :[name]="'test'">Hello Vueh2>
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>
如果希望将一个对象的所有属性,绑定到元素上的对应属性,可以直接使用 v-bind
绑定一个 对象。
<div id="app">
<h2 :name="name" :age="age" :height="height">Hello Vueh2>
<h2 v-bind="infos">Hello Bindh2>
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>
通常在某些情况下,需要对DOM元素进行底层操作,这个时候就会用到自定义指令;
**自定义指令分为两种: **
自定义局部指令:组件中通过 directives
选项,只能在当前组件中使用;
自定义全局指令:通过app
的 directive
方法,可以在任意组件中被使用;
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)自定义全局指令
export default function directiveFocus(app) {
app.directive("focus", {
mounted(el) {
el?.focus()
}
})
}
// 之所以需要这个文件,是因为如果有很多个自定义指令,在main.js中一个个注册是非常难维护的
import directiveFocus from "./focus"
export default function directives(app) {
directiveFocus(app)
}
import { createApp } from 'vue'
import directives from "./directives/index" // 导入directives文件夹下的index.js
createApp(App).use(directives).mount("#app") // 使用use注册全部的自定义指令
一般来说,很少去自定义指令,就算是项目中有这个需求,也一般是定义全局的,方便整个项目复用
一个指令定义的对象,Vue
提供了如下的几个钩子函数:
created
:在绑定元素的 attribute
或事件监听器被应用之前调用;
beforeMount
:当指令第一次绑定到元素并且在挂载父组件之前调用;
mounted
:在绑定元素的父组件被挂载后调用;
beforeUpdate
:在更新包含组件的 VNode
之前调用;
updated
:在包含组件的 VNode
及其子组件的 VNode
更新后调用;
beforeUnmount
:在卸载绑定元素的父组件之前调用;
unmounted
:当指令与元素解除绑定且父组件已卸载时,只调用一次;
比如对于下面的指令用法:
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>
https://cn.vuejs.org/api/built-in-directives.html