Vue提供了一些修饰符,这些修饰符在使用起来非常方便,比如阻止默认事件、冒泡等。
1. 表单修饰符
.lazy:
v-modeil不用多说,输入框改变,这个数据就会改变,lazy这个修饰符会在光标离开input框才会更新数据;
<input type="text" v-model.lazy="value">
.trim:
输入框过滤首尾的空格;
<input type="text" v-model.trim="value">
.number:
先输入数字就会限制输入只能是数字,先字符串就相当于没有加number;
**注意:**不是输入框不能输入字符串,是这个数据是数字;
<input type="text" v-model.number="value">
2. 事件修饰符
.stop:
阻止事件冒泡,相当于调用了 event.stopPropagation( )方法;
<button @click.stop="test">test</button>
.prevent:
阻止默认行为,相当于调用了 event.preventDefault() 方法;
比如:表单的提交、a标签的跳转就是默认事件;
<a @click.prevent="test">test</a>
.self:
只有元素本身触发时才触发方法,就是只有点击元素本身才会触发;
比如:一个 div 里面有个按钮,div 和按钮都有事件。我们点击按钮,div 绑定的方法也会触发,如果 div 的 click 加上 self,只有点击到 div 的时候才会触发,变相的算是阻止冒泡:
<div @click.self="test"></div>
.once:
只能用一次,无论点击几次,执行一次之后都不会再执行;
<div @click.once="test"></div>
.capture:
完整的事件机制是:捕获–目标–冒泡。
默认的呢,是事件触发是从目标开始往上冒泡。
当我们加了这个 .capture 以后呢,就反过来了,事件触发从包含这个元素的顶层开始往下触发。
// 1 2 4 3 <div @click.capture="shout(1)"> obj1 <div @click.capture="shout(2)"> obj2 <div @click="shout(3)"> obj3 <div @click="shout(4)"> obj4 </div> </div> </div> </div>
.passive:
当我们在监听元素滚动事件的时候,会一直触发onscroll事件,在pc端是没问题的;
但是在移动端,会让我们的网页变卡,我们使用这个修饰符的时候,相当于给 onscroll 事件整了一个 .lazy 修饰符
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --> <!-- 而不会等待 `onScroll` 完成 --> <!-- 这其中包含 `event.preventDefault()` 的情况 --> <div v-on:scroll.passive="onScroll">...</div>
.native:
组件绑定事件是不会触发的,需要用native才能触发;
可以理解为该修饰符的作用就是把一个 vue 组件转化为一个普通的 HTML 标签;
注意:使用.native修饰符来操作普通HTML标签是会令事件失效的;
<My-component @click="shout(3)"></My-component>
3. 鼠标修饰符
.left 左键点击
.right 右键点击
.middle 中键点击
<button @click.right="test">test</button>
4. 键盘修饰符
.keyCode:
如果不用keyCode修饰符,那我们每次按下键盘都会触发shout。当我们想指定按下某一个键才触发这个shout的时候,这个修饰符就有用了,具体键码查看键码对应表;
<input type="text" @keyup.keyCode="shout(4)">
vue给一些常用的键提供了别名:
// 普通键 .enter .tab .delete // (捕获“删除”和“退格”键) .space .esc .up .down .left .right // 系统修饰键 .ctrl .alt .meta .shift
通过全局 config.keyCodes 对象自定义按键修饰符别名:
// 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
我们从上面看到,键分成了普通常用的键和系统修饰键,区别是什么呢?
当我们写如下代码的时候,我们会发现如果仅仅使用系统修饰键是无法触发 keyup 事件的。
我们需要将系统修饰键和其他键码链接起来使用;
<input type="text" @keyup.ctrl.67="shout(4)">
这样当我们同时按下 ctrl+c 时,就会触发 keyup 事件。
另,如果是鼠标事件,那就可以单独使用系统修饰符。
<button @mouseover.ctrl="shout(1)">ok</button> <button @mousedown.ctrl="shout(1)">ok</button> <button @click.ctrl.67="shout(1)">ok</button>
不能单手指使用系统修饰键的修饰符(最少两个手指,可以多个)。
可以一个手指按住系统修饰键一个手指按住另外一个键来实现键盘事件。
也可以用一个手指按住系统修饰键,另一只手按住鼠标来实现鼠标事件。
.exact:
当我们像这样 <button type=“text” @click.ctrl=“shout(4)”> 绑定了 click 键按下的事件,我们同时按下几个系统修饰键,
比如:ctrl shift 点击,也能触发,可能有些场景我们只需要或者只能按一个系统修饰键来触发(像制作一些快捷键的时候),而当我们按下ctrl和其他键的时候则无法触发。
注意:这个只是限制系统修饰键的。
像下面这样书写以后你还是可以按下ctrl+c,ctrl+v 或者 ctrl+普通键 来触发,但是不能按下 ctrl + shift +普通键 来触发。
<button type="text" @click.ctrl.exact="shout(4)">ok</button>
下面这个你可以同时按下 enter+普通键 来触发,但是不能按下 系统修饰键+enter 来触发。
<input type="text" @keydown.enter.exact="shout('我被触发了')">
5. v-bind 修饰符
.sync
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。
遗憾的是,真正的双向绑定会带来维护上的问题。因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。
我们通常的做法是:
// 父亲组件 <comp :myMessage="bar" @update:myMessage="func"></comp> //js func(e){ this.bar = e; } // 子组件js func2(){ this.$emit('update:myMessage',params); }
.sync修饰符就是简化了上面的步骤
//父组件 <comp :myMessage.sync="bar"></comp> //子组件 this.$emit('update:myMessage' , params);
注意:
使用 sync 的时候,子组件传递的事件名必须为 update:value,其中 value 必须与子组件中 props 中声明的名称完全一致(如上例中的myMessage,不能使用my-message);
带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如: v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,只能提供你想要绑定的属性名,类似 v-model;
将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑;
.prop
区分:
Property:节点对象在内存中存储的属性,可以访问和设置。
Attribute:节点对象的其中一个属性( property ),值是一个对象。
通过点访问法 document.getElementById(‘xx’).attributes 或者 document.getElementById(‘xx’).getAttributes(‘xx’) 读取,
通过 document.getElementById(‘xx’).setAttribute(‘xx’,value) 新增和修改。
在标签里定义的所有属性包括 HTML 属性和自定义属性都会在 attributes 对象里以键值对的方式存在。
attribute 和 property 两个单词,翻译出来都是属性,但是《javascript高级程序设计》将它们翻译为特性和属性,以示区分
// 这里的 id,value,style 都属于 property // index 属于 attribute // id、title 等既是属性,也是特性。修改属性,其对应的特性会发生改变;修改特性,属性也会改变 <input id="uid" title="title1" value="1" :index="index"> // input.index === undefined // input.attributes.index === this.index
从上面我们可以看到如果直接使用 v-bind 绑定,则默认会绑定到 dom 节点的 attribute。
为了:1.通过自定义属性存储变量,避免暴露数据;2. 防止污染 HTML 结构;
我们可以使用这个修饰符,如下:
<input id="uid" title="title1" value="1" :index.prop="index"> //input.index === this.index //input.attributes.index === undefined
.camel
由于HTML 特性是不区分大小写的。
<svg :viewBox="viewBox"></svg>
实际上会渲染为
<svg :viewbox="viewBox"></svg>
这将导致渲染失败,因为 SVG 标签只认 viewBox,却不知道 viewbox 是什么。
如果我们使用.camel修饰符,那它就会被渲染为驼峰名。
另,如果你使用字符串模版,则没有这些限制。
new Vue({ template: '<svg :viewBox="viewBox"></svg>' })