点亮你的 Vue 技术栈(二):超好用的修饰符

626 阅读5分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。

在 Vue 中利用好修饰符这个角色可以大幅提高我们的开发效率,下面给大家介绍一下 Vue 中超好用且常用的修饰符。

事件修饰符

v-on 指令修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符

1. stop

stop 修饰符能阻止事件冒泡。

<template>
  <div @click="divClick">
    <button @click.stop="btnClick">按钮</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {}
  },
  methods: {
    divClick() {
      console.log('You click the div..')
    },
    btnClick() {
      console.log('You click the button..')
    },
  },
}
</script>

事件冒泡

添加 .stop 阻止冒泡效果:

2. prevent

prevent 修饰符能阻止默认行为,如 <a> 标签的跳转。

<template>
  <div id="app">
    <a href="http://www.baidu.com" @click.prevent="toBaiDu">百度亿下,你就知道</a>
  </div>
</template>

<script>
export default {
  methods: {
    toBaiDu() {
      console.log('前往百度')
    },
  },
}
</script>

有无 prevent 修饰符的对比效果:

3. capture

事件默认都是由内往外冒泡(🧢见上文演示),capture 修饰符说简单点就是反着来由外向内捕获事件。

补充:捕获与冒泡

<template>
  <div @click.capture="outerDiv">
    <button @click="innerBtn">Capture_捕获</button>
  </div>
</template>

<script>
export default {
  methods: {
    outerDiv(){
      console.log('Outer Div');
    },
    innerBtn(){
      console.log('Inner Button');
    }
  },
}
</script>

演示捕获效果:

如果不加 capture 修饰符,点击按钮后控制台输出的结果顺序为:Inner ButtonOuter Div(即冒泡)。

4. once

once 修饰符的作用是让事件只执行一次。

<template>
  <div>
    <button @click.once="onceClick">Just One Time?</button>
  </div>
</template>

<script>
export default {
  methods: {
    onceClick() {
      console.log('Yeah..')
    },
  },
}
</script>

演示效果:

5. self

self 修饰符作用:只当事件在该元素本身触发时(⛳比如不会因子元素触发而触发该元素所绑定的事件),才会触发事件。

官方解释:只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的。

<template>
  <div @click.self="clickEvent(1)">
    输出1
    <div @click="clickEvent(2)">输出2</div>
  </div>
</template>

<script>
export default {
  methods: {
    clickEvent(num) {
      console.log(num)
    },
  },
}
</script>

演示结果:

6. passive

当我们监听元素滚动事件时,会一直触发 onscroll 事件,在 PC 端感受不到,但在移动端会使得网页变卡。

passive 修饰符能据此提升性能,尤其是移动端,相当于给 onscroll 事件整一个 lazy 修饰符。

<div @scroll.passive="scrolling"></div>

记住:不要同时使用 .passive.prevent 修饰符。

7. keyCode

在监听键盘事件时,我们经常需要检查详细的按键。Vue 为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 无论什么按键都会触发submit事件 -->
<input @keyup="submit" />

如果要根据输入的键位进行触发时,就需要 keyCode 修饰符登场了。

keyCode 修饰符紧随 keyup 修饰符后面。

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码 keyCode 的别名

  • .enter
  • .tab
  • .delete: "删除"和"退格"键皆可捕获
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

举个例子:

<input @keyup.enter="enterKey" />
<input @keyup.delete="deleteKey" />
<input @keyup.esc="escKey" />
<input @keyup.space="spaceKey" />

效果演示:

还可以用如下系统修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click(下图演示) -->
<div v-on:click.ctrl="doSomething">Do something</div>

修饰符组合使用效果:

此外还有一个 exact 修饰符可以搭配系统修饰符使用,其作用是允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>

8. left、middle、right

这三个修饰符分别对应鼠标的左、中、右按键触发的事件。

<button @click.left="left">Button1</button>
<button @click.middle="middle">Button2</button>
<button @click.right="right">Button3</button>

效果演示:

补充👝

修饰符是可以串联使用的。

<a @click.stop.prevent="doIt"></a>

表单输入绑定修饰符

v-model 指令修饰符

1. lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框中的值与数据进行同步。

lazy 修饰符可以使得同步的时间转化为 change 事件触发之后。

<input type="text" v-model.lazy="msg" />

有无 lazy 修饰符的对比演示:

2. number

如果想把输入框中的值自动转为数值类型,可以使用 number 修饰符。

该修饰符经常使用,因为即使在 type="number" 时,输入值也时返回字符串;添加 number 修饰符后,输入值会被 parseFloat() 解析,如果无法解析,则返回原始数据。

<input v-model.number="age" />

效果演示:

🥊如图,数字先/后于字母输入效果不同。

3. trim

如果要自动过滤用输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg" />

其他修饰符

1. native

native 修饰符用于自定义组件上,保证事件能执行。

自定义组件在后面的文章中会讲解。

<template>
  <div>
    <Compo @click.native="info"></Compo>
  </div>
</template>

<script>
import Compo from '@/components/Compo.vue'

export default {
  methods: {
    info() {
      console.log('事件正常响应..')
    },
  },
  components: {
    Compo,
  },
}
</script>

演示效果:

2. sync

官方文档解释 .sync 修饰符。

父组件子组件 传值时,子组件若直接修改这个传入的值会报错(如下图)

但在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。

这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:

this.$emit('update:title', newTitle)

然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:

<text-document v-bind:title.sync="doc.title"></text-document>

3. camel

由于 HTML 特性是不区分大小写的,camel 修饰符允许在使用 DOM 模板时将 v-bind 属性名称驼峰化,例如 SVG 的 viewBox 属性:实际会被渲染为:

<svg viewbox="viewbox"></svg>

这将导致渲染失败,因为 SVG 标签只认 viewBox,却不知道 viewbox 是什么。

<svg :viewBox.camel="viewBox"></svg>

OK,本文的内容就到这里,如果还有不懂的地方可以在评论区留言,我们一起探讨。

💍本文参考:

❤️/ END / 如果本文对你有帮助,点个「赞」支持下吧。