在 Vue.js 中,指令(Directive)是一种特殊的属性,它可以用于扩展 HTML 元素的行为。指令以 v-
前缀作为标识符,用于标识当前属性是一个指令。
数据绑定类指令
1.v-text填充文本
v-text
是 Vue.js 内置指令之一,用于将元素的文本内容设置为指令表达式的值。
1.相比差值表达式更加简洁
2.与差值表达式同时存在时,显示v-text
3.与v-html同时存在时,显示写在后面的一个
4.不识别标签
<body>
<div id="app" >
<div v-text="aa">
</div>
</div>
</body>
<script>
let vm=new Vue({
el:"#app",
data:{
mag:'2',
aa:'<h1>aaa</h1>',
}
})
</script>
2.v-html填充网页
v-html
是 Vue.js 内置指令之一,用于将元素的 HTML 内容设置为指令表达式的值。
1.相比差值表达式更加简洁
2.与差值表达式同时存在时,显示v-html
3.与v-text同时存在时,显示后面的一个
4.识别标签
<body>
<div id="app" >
<div v-html="aaa" v-text="aa">
{{aa}}
</div>
</div>
</body>
<script>
let vm=new Vue({
el:"#app",
data:{
mag:'2',
aa:'<h1>aaa</h1>',
aaa:'<h1>as</h1>'
}
})
</script>
3.v-cloak隐藏未编译
v-cloak
是 Vue.js 内置指令之一,用于解决在页面加载过程中,由于 Vue.js 运行时需要一定时间来渲染页面,导致页面出现闪烁的问题。它的原理是先隐藏文件挂载位置,处理渲染好后在显示最终结果。这个指令需要与css规则一起使用才可以
//css
[v-cloak] {
display: none;
}
//html
<h1 v-cloak>{{mag}} </h1>
//js
new Vue({
el: '#app',
data: {
mag: 'hellow word',
}
})
4.v-once一次性渲染
v-once
是 Vue.js 内置指令之一,它可以用于将元素或组件的内容只渲染一次,并将其缓存起来,以后再次渲染时不再重新计算。
1.即绑定显示之后,视图不会再改变(data是会变的)
2.可以跟v-html text一起出现互不影响
3.遇到v-pre还是会直接跳过绑定
<div v-once v-html="aa">
{{aaa}}
</div>
let vm=new Vue({
el:"#app",
data:{
aa:'<h1>aaa</h1>',
aaa:'aa',
}
})
vm.aa='sa'
console.log(vm.aa);
//页面显示标题格式的aaa
//log结果是sa
5.v-pre不绑定(跳过编译)
v-pre
是 Vue.js 框架提供的一个指令,用于在特定元素上跳过编译过程,直接将其作为静态的内容渲染。通常情况下,Vue.js 会通过编译模板生成渲染函数,然后将渲染函数与数据结合,生成最终的页面内容。而 v-pre
指令可以使得该元素及其子元素被视为静态内容,跳过编译的过程,从而提高渲染的性能。
1.填充原始信息 显示原始信息 跳过编译阶段(也就是标签里写啥就是啥)
2.若与v-html或v-text一起出现,v-pre的权重更高
<h3 v-pre> {{name}} </h3>
new Vue({
el: '#app',
data: {
name: 'cderfrgtrghy'
}
})
// {{name}}
6.v-bind:属性绑定
v-bind
是 Vue.js 框架提供的一个指令,用于将组件或元素的属性与表达式进行绑定,实现动态地设置属性值。通常情况下,元素的属性值是静态的,而 v-bind
指令可以将属性值设置为动态的,根据表达式的值实时更新。
1.v-bind:将vue实列对象中的data中的某个属性数据,绑定到根元素内某个元素的属性上
要在属性的前面加一个v-bind 否则无法绑定
2.可以简写成 :
3.绑定非原有属性不会显示在标签上,同时getattribute获取为null
<div id="app">
<a v-bind:href="url">百度1</a>
<!-- 简写 -->
<a :href="url">百度1</a>
</div>
let vm = new Vue({
el: "#app",
data: {
url: 'http://www.baidu.com'
},
})
6-1.特殊掌握——:is与动态组件的应用
:is
属性和动态组件是 Vue.js 框架提供的一种动态加载组件的方式。
在 Vue.js 中,通常我们通过使用组件名的方式引入组件,并在需要使用组件的地方使用组件标签。但是,在某些情况下,我们可能需要根据某些条件来动态加载组件,例如根据用户的登录状态显示不同的组件,或者根据用户的操作加载不同的组件等。这时,我们可以使用 :is
属性和动态组件来实现这种需求。
在 Vue.js 中,动态组件指的是在同一个挂载点内动态地切换不同的组件。实现动态组件的方式是在组件标签上使用 :is
属性,并将要加载的组件的名称或组件对象的引用赋给 :is
属性的值。
// 结构
<div id="app">
<component :is="currentView"></component>
<button @click="changeView('A')">切换到A</button>
<button @click="changeView('B')">切换到B</button>
<button @click="changeView('C')">切换到C</button>
</div>
// 逻辑代码
Vue.component('componentA', {
template: `<div>组件A</div>`,
})
Vue.component('componentB', {
template: `<div>组件B</div>`
})
Vue.component('componentC', {
template: `<div>组件C</div>`,
})
let vm = new Vue({
el: "#app",
data () {
return {
currentView: 'componentB' // 显示默认组件
}
},
methods: {
changeView: function (name) {
this.currentView = `component${ name }`
}
}
})
数据绑定类指令
7.v-on事件绑定
v-on
是 Vue.js 框架中用于绑定事件处理函数的指令。通过 v-on
指令,可以将 DOM 元素上的事件与 Vue 实例中定义的方法进行关联,实现事件处理的功能。例如 click
、mouseover
、keyup
等。
1.简写:@click="函数名(括号可写可不写)"
<div id="app">
{{num}}
<button @click="handel">+1</button>
<button v-on:click="handel">+1</button>
</div>
let vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handel() {
this.num++
}
},
})
7-1.事件对象
直接上例子
写法①
<template>
<button @click="handleClick">Click Me</button>
</template>
<script>
export default {
methods: {
handleClick(event) {
console.log(event)
}
}
}
</script>
写法②
<button @click="onClick($event)">Click Me</button>
<script>
export default {
methods: {
handleClick(event) {
console.log(event)
}
}
}
</script>
7-2.事件修饰符
在 Vue 中,事件修饰符是指用于修改事件行为的特殊后缀,用于在事件触发时执行一些特定的行为或操作。
(1).stop阻止冒泡
.stop
是 Vue 中的事件修饰符之一,用于阻止事件冒泡。当一个元素被点击时,该事件可能会向上冒泡并触发其父元素的相应事件处理程序。在某些情况下,我们希望阻止事件冒泡以防止其它元素的相应事件被触发,此时就可以使用 .stop
修饰符。
<div id="big" @click.stop="fn1">
<div id="center" @click.stop="fn2">
<div id="small" @click.stop="fn3"></div>
</div>
</div>
new Vue({
el:"#big",
data:{},
methods: {
fn1(){
console.log('big');
},
fn2(){
console.log('center');
},
fn3(){
console.log('small');
}
},
})
(2).prevent阻止默认行为
.prevent
是 Vue 中的事件修饰符之一,用于阻止事件的默认行为。在某些情况下,我们希望阻止某个元素触发某个事件的默认行为,例如在一个表单中阻止提交按钮的默认提交行为,此时就可以使用 .prevent
修饰符。
1.例如组织超链接跳转
<a href="https://www.baidu.com" @click.prevent id="big">百度</a>
(3).capture事件捕获
.capture
是 Vue 中的事件修饰符之一,用于对事件进行捕获阶段处理。在 DOM 树中,事件会从最外层元素往里层元素依次传递,这个过程包括两个阶段,分别是捕获阶段和冒泡阶段。默认情况下,Vue 的事件监听是在元素的冒泡阶段处理的。但是,当我们希望在事件捕获阶段处理某些事件时,可以使用 .capture
修饰符。
<div @click.capture="handleClick">...</div>
(4).self自身触发
.self
是 Vue 中的事件修饰符之一,用于只在事件触发的元素自身上触发事件处理函数,而不会在其子元素上触发。
不会阻止冒泡,但是无论是捕获还是冒泡,自己不会触发,只有鼠标确实点在自己身上时才会触发
<div @click.self="handleClick">...</div>
(5).once只触发一次
.once
是 Vue 中的事件修饰符之一,用于只在事件第一次触发时执行事件处理函数,而在之后的事件触发中不再执行。只能触发一次(冒泡触发也算1次)
<button @click.once="handleClick">Click Me</button>
分支结构类指令
8.v-if是否渲染
v-if
是 Vue 中的条件渲染指令之一,用于根据条件动态地插入或移除元素。
1.如果v-if=true就渲染,否则压根不渲染
2.v-else-if关联的是相邻上一行的v-if
3.v-else同理
4.如果上一行没有则会报错
<div id="app">
<div v-if="fenshu>90">优秀</div>
<div v-else-if="fenshu<90&&fenshu>=80">良好</div>
<div v-else-if="fenshu<80&&fenshu>=60">合格</div>
<div v-else>比较差</div>
</div>
new Vue({
el:"#app",
data:{
fenshu:80
},
methods: {
}
})
9.v-show是否显示
v-show
是一个 Vue.js 指令,用于根据表达式的值来控制元素的显示或隐藏。
和 v-if
指令区别:v-show
指令只是简单地切换元素的 CSS 属性 display
,因此在初始渲染时它不会导致额外的性能开销。使用 v-show
指令的元素始终会被渲染,并保留在 DOM 中,只是简单地通过修改样式来控制其显示或隐藏。因此,v-show
指令在需要频繁切换显示/隐藏的元素上具有更好的性能表现。
<body>
<div id="app">
<div v-show="flag">aa</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
flag:true
}
})
</script>
循环结构指令
10.v-for循环遍历
v-for
是 Vue.js 的一个指令,用于渲染一个列表或集合的数据。它可以通过遍历数组或对象的属性来生成列表或一组元素。为了避免渲染时的性能问题,需要在列表中添加一个 :key
属性,用于唯一标识每个元素。
10-1.遍历数组
(1)写法1—“item in list”
1.item是每一项
2.list是你data里定义的数组名
<div id="app">
<ul id="ul">
<li v-for="item in list">{{item}}--{{list}} </li>
</ul>
<div>
new Vue({
el: '#app',
data: {
list: ['efref', 'efref', 'efref', 'efref', 123]
}
})
(2)写法2——“(item,index) in list”
1.item是每一项
2.index是下标(索引)
3.list是你data里定义的数组名
<div id="app">
<ul id="ul">
<li v-for="(item,index) in list"> {{index}}--{{item}} -- {{list}} </li>
</ul>
</div>
new Vue({
el: "#app",
data: {
list: ["ceerfr", '你好', 3, 4]
}
})
遍历json格式的数组
<div id="app">
<ul id="ul">
<li v-for="(item,index) in list">{{item.cname}}---{{index}} </li>
</ul>
</div>
new Vue({
el: "#app",
data: {
list: [{
id: 1,
cname: '苹果',
},
{
id: 2,
cname: '香蕉',
}, {
id: 3,
cname: '橘子',
}]
}
})
10-2.遍历对象
(1)写法1——“(value,key,index) in obj”
1.value是每一个属性值
2.key是每一个属性名
3.index是索引
4.obj是你data里定义的对象名
<div id="app">
<div v-for="(value,key,index) in obj"> {{value}} -- {{key}} -- {{index}}</div>
</div>
new Vue({
el: "#app",
data: {
obj:{
name:'张三',
age:23,
addres:'北京'
}
}
})
10-3.当v-if和for同时使用
vue2中 v-for 的 优先级 要比 v-if 的优先级要高。vue3 中 相反
先判断在循环,在外围写 v-if 在自己身上写v-for
<ul v-if="true">
<li v-for="(item,index) in arr"> {{item.title}} </li>
</ul>
表单指令
11.v-model双向数据绑定
v-model是Vue.js框架中的一个指令,用于在表单元素和Vue实例的数据之间双向绑定,即数据的变化可以实时反映到视图上,同时视图上的变化也会同步到数据上。v-model可以用在input、textarea、select等表单元素上,也可以用在自定义组件上。
1.改变视图数据也能同步改变data里的数据
2.而:value不行
3.如果与:value同时出现则显示v-model
11-1.输入框
<div id="app">
<input type="text" v-model="uname"> {{uname}}
</div>
new Vue({
el: "#app",
data: {
uname: '张三'
}
})
11-2.单选
1.v-model用来区分表单,值一样的为同一表单
2.value有两个作用,如果value值与v-model值相等,则打开网页时自动勾选
3.在同一表单的前提下,如果出现两个选项的value为同一个值会被同时勾选,相反如果value不为同一个值才可以实现单选效果
<div id="app">
男: <input type="radio" v-model="geene" value="1">
女: <input type="radio" v-model="geene" value="0">
s: <input type="radio" v-model="geenee" value="1">
</div>
new Vue({
el: "#app",
data: {
geene: 1,
geenee:55
}
})
11-3.多选
1.v-model用来区分表单,值一样的为同一表单
2.value有两个作用,如果value值与v-model值相等,则打开网页时自动勾选
3.在同一表单的前提下,如果出现两个选项的value为同一个值会被同时勾选,相反如果value不为同一个值才可以一次选一个
<div id="app"> 爱好:
<input type="checkbox" v-model="hoddy" value="1"> 篮球
<input type="checkbox" v-model="hoddy" value="2"> 足球
<input type="checkbox" v-model="hoddy" value="1"> 排球
</div>
11-4.文本域
<div id="app">
<textarea v-model="uname"></textarea>
</div>
let vm = new Vue({
el: "#app",
data: {
uname: "李四",
}
})
表单修饰符
(1).number转数字型
.number
是Vue.js中的修饰符之一,用于将用户输入的字符串类型的数字转换为数字类型,以便在应用程序中进行数值计算。当我们使用v-model指令与输入元素一起使用时,我们可以在输入元素上添加.number
修饰符,以确保绑定的数据在更新时始终是数字类型,而不是字符串类型。
1.如果第一位是字母,则将输入框内内容全部看成字符串并采用拼接方式
2.如果第一位是数字,则保留数字部分(字母往后的内容自动去掉),并正常计算
3.小数也可以计算
<div id="app">
<input type="text" v-model.number="age">
<button @click="add">dianji</button>
{{msg}}
</div>
new Vue({
el: '#app',
data: {
msg:'',
age: '',
},
methods: {
add() {
this.msg = this.age + 13
}
},
})
(2).trim去掉前后空格
在Vue.js中,.trim
是一个修饰符,可以用于在数据绑定中去除绑定值的前导和尾随空格。
1.只去掉前后空格
2.如果是出现在两个字符中间的空格则不会去掉,且数量能够叠加
<div id="app">
<input type="text" v-model.trim="ab">
<button @click="a">dianji</button>
</div>
new Vue({
el: '#app',
data: {
ab: '',
},
methods: {
a() { console.log(this.age.length);
}
},
})
(3).lazy失焦触发
在 Vue 的 <input>
和 <textarea>
元素中,.lazy
修饰符用于将 v-model
的更新延迟到 "change" 事件而不是默认的 "input" 事件。当你想要在输入时不频繁更新组件的状态,而是在失去焦点或按下回车键时进行更新时,可以使用 .lazy
修饰符。
1.并不是实时更新 的 而是失去焦点或者 回车事件的时候 会触发
2.data的值也是只有失焦后才会改变
<div id="app">
<input type="text" v-model.lazy="age" @keyup="aa">
{{age}}
</div>
new Vue({
el: '#app',
data: {
age: '',
},
methods:{
aa(){
console.log(this.age);
}
}
})
自定义指令
Vue 的自定义指令是用来扩展 HTML 元素行为的指令。自定义指令分为全局自定义指令和局部自定义指令。
12.vue2写法
12-1.钩子函数
在 Vue 2 中,自定义指令可以定义一些钩子函数来处理指令的生命周期事件。
(1) bind()只调用一次,指令第一次绑定到元素时调用,可以在这里进行一次性的初始化设置。
(2) inserted ()被绑定元素插入父节点时调用,即 DOM 元素插入到页面中。很常用。
(3) update ()指令所在的组件的 VNode(虚拟节点) 更新时调用,但可能发生在其子 VNode 更新之前。
(4) componentUpdated() 指令所在的组件的 VNode 及其子 VNode 全部更新后调用。
(5)unbind () 只调用一次,指令与元素解绑时调用,可以在这里进行清理操作。
VNode(虚拟节点):在Vue.js中,VNode(Virtual DOM node)是一个JavaScript对象,用于表示DOM中的一个节点,包括其标签名、属性、子节点等信息。它是虚拟的DOM节点,可以被用来描述真实的DOM节点。通过对比新旧两个VNode,Vue可以高效地渲染视图。同时,VNode还可以用来实现一些高级功能,例如自定义组件、过渡动画等。
12-2.局部自定义指令
(1)无参数
在 Vue 组件内部定义局部自定义指令需要在 directives
选项中定义。
1.v-名字是自己起的
2.在调用focus的时候就是在调用inserted,然后执行的focus这个方法(inserted 被绑定元素插入节点时候调用的,可以看成一个普通函数)
3.inserted里的参数(一般写el),代表绑定的标签本身
4.focus 是原生的自动获取焦点的方法
<div id="app">
<input type="text" v-focus>
</div>
Vue.directive('focus', {
inserted(a) {
console.log(a);
a.focus()
},
})
(2)有参数
1.v-名字是自己起的
2.在调用color的时候就是在调用bind,只执行1次
3.第一个参数 el 代表着整个标签 DOM对象
4.第二个参数binding 代表一个绑定的对象,即含有你传进来的参数中的信息。成为value(名字变成value),通过binding.value.属性 获取
<div id="app">
<div v-color="redss">下周一见</div>
</div>
new Vue({
el: '#app',
data: {
redss: {
color: 'red',
}
},
directives: {
color: {
bind(el, b) {
console.log(b);
el.style.color = b.value.color
},
},
12-3.全局自定义指令
要在Vue中全局自定义指令,可以使用Vue.directive()方法来定义,这个方法接受两个参数:指令名称(自拟)和一个指令定义对象。指令定义对象包含指令的几个生命周期钩子函数
(1)无参数
<div id="app">
<input type="text" v-focus>
</div>
Vue.directive('focus', {
inserted(a) {
console.log(a);
a.focus()
},
})
(2)有参数
<div id="app">
<div v-color="redss">下周一见</div>
</div>
Vue.directive('color', {
bind(el, binding) {
console.log(binding);
el.style.color = binding.value.color
}
})
new Vue({
el: '#app',
data: {
redss: {
color: 'red',
}
}
})
13.vue3写法
vue2 和 vue3 在自定义指令上有一些差异,并不是完全一致
13-1.钩子函数
beforeMount
:指令和组件挂载之前调用mounted
:指令和组件挂载后调用beforeUpdate
:在更新页面时调用,但是组件和指令本身还没有更新updated
:在更新页面时调用,指令和组件已经更新完毕beforeUnmount
:在组件或指令卸载之前调用unmounted
:在组件或指令卸载之后调用
13-2.局部自定义指令
<template>
<div>
<input type="text" v-focus />
</div>
</template>
<script>
export default {
directives: {
focus: {
mounted(el) {
el.focus();
},
},
},
};
</script>
13.3-全局自定义指令
<template>
<div v-color="redss">下周一见</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
data() {
return {
redss: {
color: 'red',
},
};
},
directives: {
color: {
mounted(el, binding) {
console.log(binding);
el.style.color = binding.value.color;
},
},
},
});
</script>
13-4.自定义权限指令
自定义指令可以用来操作 DOM,实现一些自定义的交互行为和效果。而自定义权限指令则可以用来控制组件的渲染,以达到对权限的控制和限制。
例如,在一个管理系统中,某些敏感信息需要授权才能查看,那么可以使用自定义权限指令来实现只有授权用户才能查看敏感信息的功能。自定义权限指令可以根据用户的权限等级来判断是否允许渲染该组件,从而实现权限控制。这种方式相比在模板中直接使用 v-if 指令更加灵活和易于维护。
// main.js
const userPermissions = ['name'] // 当前用户所具备的权限,是一个数组
app.directive('hasPermission', {//注册一个名为 hasPermission 的自定义指令
mounted(el, binding) {
const value = binding.value.name //接收标签传来的参数(对象中name的值)
let f = userPermissions.some(p => {//遍历数组,如果查找是否存在一个元素包含了此名称。
return p.indexOf(value) !== -1//如果找到了,就将 f 标记为 true,否则 f 为 false。
})
if(!f) {//如果!f 为 true,也就是没找到
el.parentNode && el.parentNode.removeChild(el)//此时就将元素从 DOM 树中删除,否则元素保持不变。在这里,&& 起到了一种短路的作用。当 el.parentNode 为 false 值(比如 null 或 undefined)时,不再继续计算第二个操作数,直接返回 false。这么做的目的是:如果不做判断直接调用 removeChild 方法,当元素没有父元素时就会出现错误。
}
}
})
//html
<button @click="btnClick" v-hasPermission="{name: 'delete'}">shanchu</button>
插槽指令
14.v-slot插槽指令
v-slot
是Vue 2.6.0版本中引入的用于在组件中定义插槽的指令,用于替代旧的slot
和slot-scope
语法。在Vue 3.0及以上的版本中,v-slot
指令仍然存在,v-slot
的作用是在组件中定义插槽,即允许父组件在子组件内嵌入任意内容。
从Vue 2.6.0开始,可以使用#
符号作为v-slot:
的简写形式,例如<template v-slot:header>
可以简写为<template #header>
14-1.普通插槽用法
(1)默认插槽
//子
<template>
<div>
<slot></slot>
</div>
</template>
//父
<template>
<my-component>
<p>这是默认插槽中的内容</p>
<p v-slot:default>这也是默认插槽中的内容</p>
<p #default>这同样是默认插槽中的内容</p>
</my-component>
</template>
(2)具名插槽
//子
<template>
<div>
<slot name="header"></slot>
<div class="content">
<slot></slot>
</div>
<slot name="footer"></slot>
</div>
</template>
//父
<template>
<my-component>
<template v-slot:header>
<h1>这是头部内容</h1>
</template>
<p>这是主要内容</p>
<template v-slot:footer>
<p>这是底部内容</p>
</template>
</my-component>
</template>
14-2.作用域插槽用法
作用域插槽(Scoped Slots)是Vue.js中比较高级的特性之一,它允许父组件向子组件传递数据,同时也能让子组件决定如何渲染数据。
传统的插槽只能简单地将父组件的内容放置到子组件的指定位置上,但如果父组件需要向子组件传递一些数据,那么就需要用到作用域插槽了。
作用域插槽可以传递一个插槽props对象,这个props对象包含了一些数据,这些数据是父组件可以传递给子组件的。子组件可以根据这些数据来自定义渲染内容,从而实现更灵活的布局。
(1)默认插槽
<template>
<div>
<my-component>
<template v-slot="slotProps">
<p>用户名: {{ slotProps.user.name }}</p>
<p>年龄: {{ slotProps.user.age }}</p>
</template>
</my-component>
</div>
</template>
<script>
Vue.component('my-component', {
template: `
<div>
<h3>用户信息</h3>
<slot :user="{ name: 'John', age: 30 }"></slot>
</div>
`
(2)具名插槽
<div id="app">
<my-list>
<template v-slot:detail="slotProps">
我叫:{{slotProps.detail.name}}
我的爱好是:{{slotProps.detail.love}}
</template>
</my-list>
</div>
Vue.component('myList', {
template: `
<div><slot :detail="detail" name="detail"></slot></div>
`,
data: function () {
return {
detail: {
name: 'lisi',
love: 'No coding 1234567'
}
}
}
})
let vm = new Vue({
el: "#app",
})