目录
vue中的指令按照不同的用途可以分为如下6大类:
内容渲染指令、 属性绑定指令、 事件绑定指令、 双向绑定指令、 条件渲染指令和 列表渲染指令。内容渲染指令(v-text、v-html)
v-text 指令(更新元素的文本内容。如果要更新部分的文本内容,需要使用 {{ }} 插值。)、v-html 指令(更新元素的 innerHTML。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译)。
<div id="app">
<!-- 默认写法会替换所有内容,使用插值表达式{{}}可以替换指定内容 -->
<!-- 注意:v-text、v-html都会将所有的文本值用获得的数据替换掉,v-text也可进行字符串的拼接操作 -->
<h3 v-text="message + '呀!'">柳小姐</h3> //你好呀!
<h3>{{message + '呀!'}}柳小姐</h3> //你好呀!柳小姐
<!-- v-html会把html结构解析成标签,v-text无论内容是什么都只会解析成文本 -->
<p v-html="message"></p> //你好
<p v-text="message"></p> //你好
<p v-html="web"></p> //一个百度的链接
<p v-text="web"></p> //<a href='https://www.baidu.com'>百度</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: '你好',
web: "<a href='https://www.baidu.com'>百度</a>",
}
})
</script>
属性绑定指令(v-bind)
插值表达式只能使用在元素的文本节点上,不能使用在元素的属性节点中。所以可以使用该指令:v-bind 指令:为元素的属性动态绑定属性值。语法糖为:。操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
<div id="app">
<img v-bind:src="imgSrc" width="270px" height="400px">
<!-- 语法糖(简写方法)-->
<img :src="imgSrc" width="270px" height="400px">
<!-- 此外,v-bind:class指令也可以与普通的class属性共存。以下结果:<div class="static active"></div>-->
<div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
<!-- 表达式结果的类型是对象(对象语法)-->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div :style="styleObject"></div>
<div :class="[activeColor,width]"></div> <!-- 表达式结果的类型是数组(数组语法)-->
</div>
<!-- data部分-->
data: {
imgSrc: 'https://v3.cn.vuejs.org/logo.png',
isActive: true,
hasError: false,
activeColor: 'red',
width: '100px',
fontSize: 30,
styleObject: {
color: 'red',
fontSize: '13px'
}
}
事件绑定指令(v-on)
v-on 指令:为DOM元素绑定事件监听,并在触发时运行一些 JavaScript 代码。语法糖为@。注意:原生DOM对象有onclick、oninput、onkeyup等原生事件,替换为vue的事件绑定形式后,分别为: @click、@input、@keyup等。在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event property:@click="handle('ok', $event)"。
<div id="app">
<!-- v-on绑定的方法定义在methods属性中,方法内部可以通过this关键字访问定义在data中的数据,事件名不需要写on,指令可以简写为@ -->
<input type="button" value="v-on指令" v-on:click="doit">
<input type="button" value="v-on简写" @click="doit">
<input type="button" value="双击事件" @dblclick="doit">
<h2 @dblclick="changefood">{{food}}</h2>
</div>
<!-- methods部分-->
methods: {
doit(){
alert("做IT");
}
}
注意:在绑定事件处理函数的时候,可以使用()传递参数。$event的应用场景:如果默认的事件对象e被覆盖了,则可以手动传递一个$event。
<div id="app">
<p>{{count}}</p>
<!-- vue提供了内置变量 $event,它是原生DOM的事件对象e.传递的参数和$event可以交换位置,但在methods中的方法中位置也要互相对应.(了解)-->
<button @click="add(3,$event)">加三</button>
</div>
<!-- vue实例部分-->
data: {
count: 0
},
<!-- 如果我们传参了,另外还需要使用e这个事件对象时,就可以这样使用 -->
methods: {
add(n,e){
console.log(e);
this.count += n;
}
}
事件修饰符
作用:更方便的对事件的触发进行控制。修饰符是由点开头的指令后缀来表示的。
<div id="app">
<div style="background-color:skyblue; width:1000px; height:100px" @click="divClick">
<button @click="btnClick">点击</button>
<!-- 阻止默认事件——冒泡的方法一: -->
<!-- <button @click.stop="btnClick">点击</button> -->
</div>
</div>
methods: {
btnClick() {
console.log('btnClick');
},
// 阻止默认事件——冒泡的方法二:
// btnClick(e) {
// e.stopPropagation(); //阻止冒泡
// console.log('btnClick');
// },
divClick() {
console.log('divClick');
}
}
常见的6个事件修饰符:
| 事件修饰符 | 描述 |
|---|---|
.prevent | 阻止默认行为(如a链接的跳转、表单的提交等) |
.stop | 阻止事件冒泡 |
| .capture | 捕获模式触发当前的事件处理函数 |
| .once | 绑定的事件只触发一次 |
| .self | 只有在event.target是当前元素自身时触发事件处理函数,即事件不是从内部元素触发的 |
| .passive | 滚动事件scroll的默认行为 (即滚动行为) 将会立即触发,而不会等待 onScroll 完成,这其中包含 event.preventDefault() 的情况。该修饰符尤其能够提升移动端的性能 |
注意:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
按键修饰符、系统修饰键
按键码:.enter、.tab、.delete (捕获“删除”和“退格”键)、.esc、.space、.up、.down、.left、.right等;另外,还可以通过全局 config.keyCodes 对象自定义按键修饰符别名,例如:Vue.config.keyCodes.f1 = 112。
系统修饰键:可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。如.ctrl、.alt、.shift、.meta等。
.exact 修饰符允许控制由精确的系统修饰符组合触发的事件。
鼠标按钮修饰符:这些修饰符会限制处理函数仅响应特定的鼠标按钮:.left、.right、.middle等。
双向绑定指令(v-model:面试常客)
v-model 指令在表单控件(input、textarea、select)或者组件上实现双向绑定(即视图或者数据的改变都能影响另一个的改变)。v-bind指令是单向绑定(数据影响视图,视图不影响数据)。另外,v-model可以认为相当于v-bind:value+v-on:input。
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
修饰符
| 修饰符 | 说明 |
|---|---|
.lazy | 可以让输入框失去焦点或者回车时才会刷新数据 |
.number | 默认情况下在输入框输入的无论是字母还是数字都会被当作字符串处理,number修饰符可以让输入的内容自动转换成数字类型 |
.trim | 自动过滤用户输入的数据中首尾的空格字符 |
条件渲染指令(v-if(v-else-if、v-else)、v-show)
v-if 、v-show 指令都可以根据表达式的值的 true/false 来有条件地渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template>,将提出它的内容作为条件块。
就像if、else if、else一样,v-if指令也有它的‘else if’和‘else’块,就是v-else-if指令和v-else指令。其中,v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别;v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
v-if和v-show的区别:
v-show的原理是:动态为元素添加或移除display: none样式,来实现元素的显示和隐藏;v-if的原理是:在DOM中每次动态创建或移除元素,来实现元素的显示和隐藏;- 。如果要频繁的切换元素的显示状态,用v-show性能会更好;如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时v-if性能更好(即运行时条件很少改变)。
v-if有更高的切换开销,而v-show有更高的初始渲染开销。 v-show不支持<template>元素,也不支持v-else指令。
<h2 v-if="score >= 90">优秀</h2>
<h2 v-else-if="score >= 80">良好</h2>
<h2 v-else-if="score >= 60">及格</h2>
<h2 v-else>不及格</h2>
data: {
score: 85
} //良好
可复用元素管理
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。可查看官方例子:key实现可复用元素的管理。
列表渲染指令(v-for)
v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items或者 item of items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<ul id="app">
<li v-for="item in items" :key="item.message">{{ item.message }}</li><!-- 1个参数-->
<li v-for="(item, index) in items">{{ parentMessage }} - {{ index }} - {{ item.message }}</li><!-- 2个参数-->
<!-- 使用v-for来遍历一个对象的属性-->
<li v-for="value in object">{{ value }}</li>
<li v-for="(value, name) in object">{{ name }}: {{ value }}</li><!-- 2个参数-->
<li v-for="(value, name, index) in object">{{ index }}. {{ name }}: {{ value }}</li><!-- 3个参数-->
</ul>
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
key属性的使用
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每项提供一个唯一 key 属性:<div v-for="item in items" v-bind:key="item.id"><!-- 内容 --></div>。
注意:①key的值只能是 string 或 number 类型;②key的值必须具有唯一性(即:key的值不能重复);③建议把数据项id属性的值作为key的值(因为id 属性的值具有唯一性);④使用index的值当作key的值没有任何意义(因为index的值不具有唯一性);⑤建议使用v-for指令时一定要指定key的值(既提升性能、又防止列表状态紊乱)。
其它指令
v-pre 指令:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
<h2 v-pre>{{message}}</h2> <!-- 渲染结果:{{message}}-->
data: {
message: '柳小姐!'
}
v-cloak 指令:这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
<!-- css部分-->
[v-cloak] {
display: none;
}
<div v-cloak>{{ message }}</div> <!-- 一直隐藏-->
v-once 指令:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
<h2 v-once>{{message}}</h2> <!-- 渲染结果:柳小姐!(即使data中的message发生变化,结果也仍然不变-->
data: {
message: '柳小姐!'
}
v-slot 指令:语法糖为#,限用于 <template> 和组件 (对于一个单独的带 prop 的默认插槽)。提供具名插槽或需要接收 prop 的插槽。有关插槽的知识就不在这一一赘述了。
自定义指令
vue官方提供了v-for、v-model、v-if 等常用的指令。除此之外vue还允许开发者自定义指令。自定义指令分为两类:私有自定义指令(局部)和全局自定义指令。
局部自定义组件
在每个vue 组件中,可以在 directives 节点下声明私有自定义指令:
directives: {
//定义名为color的指令,指向一个配置对象
color: {
//当指令第一次被绑定到元素上的时候,会立即触发bind函数(钩子函数)
bind(el){
//形参中的el是绑定了此指令的、原生的DOM对象,是固定写法
console.log(el);
el.style.color = 'red'
}
}
}
钩子函数
指令定义函数提供了几个钩子函数:
| 钩子函数 | 说明 |
|---|---|
bind | 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。 |
inserted | 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。 |
update | 被绑定元素所在的模板DOM更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。 |
componentUpdated | 被绑定元素所在模板完成一次更新周期时调用。 |
unbind | 只调用一次, 指令与元素解绑时调用。 |
钩子函数参数
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM。binding:一个对象,包含以下 property:name:指令名,不包括 v- 前缀。value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。oldVnode:上一个虚拟节点,仅在update和componentUpdated钩子中可用。
使用示例:
<template>
<div id="app">
<div>
<div v-color:foo.a.b="message"></div>
</div>
</template>
<script>
export default {
data(){
return {
message: '你好啊!'
}
},
directives: {
color: {
//多个钩子函数参数
bind(el,binding,vnode){
let s = JSON.stringify;
console.log(s); //ƒ stringify() { [native code] }
console.log(binding);
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
}
}
}
</script>

全局自定义组件
在main.js中,全局共享的自定义指令需要通 Vue.directive() 进行声明:
//function:钩子函数bind和update的简写模式
//参数一:表示全局自定义组件的名字;参数二:用来接收指令的函数参数
Vue.directive('color1',function(el,binding){
el.style.color = binding.value;
})