1. 开发中常见的 32+ Vue 修饰符,你掌握几种啦?

开发中常见的 32+ Vue 修饰符,你掌握几种啦?

前端有道;)

前端有道

微信号 leadingEnd

功能介绍 给小白逆袭前端高手的学习社区,定期分享前端面试、前端最新技术和实战技巧等系列内容。如果你前端基础差,缺项目经验,这里就是为你量身定制的!如有需要,公众号后台准备了一些备战大厂面试资料,可以关注获取!

2021-11-08 08:00

收录于话题

以下文章来源于前端胖头鱼 ,作者前端胖头鱼

[Vue 修饰符 - 图1

前端胖头鱼 .

曾在阿里跑堂的 “小二”,在美团烧得一壶“好开水” 的逗比前端。也许你我素未谋面,但很可能相见恨晚,关注我,一起快乐学前端。](#)

来着: 前端胖头鱼
https://juejin.cn/post/7026867875990208543

前言

vue 简洁好用体现在很多个地方,比如其内置了 32 + 修饰符,可以很方便我们阻止冒泡、阻止默认事件、鼠标事件处理、系统键盘事件等等,让我们可以快速搞定业务,简直不要太方便噢!!!

耽误您 15 分钟您可以收获:

  1. 32 + 修饰符(包括事件修饰符、鼠标修饰符、表单修饰符、系统修饰符等等)的含义和使用
  2. 如何利用 webpack 动态注册 vue 路由,再也不手写路由配置啦!

文章中例子都放在了 github 源码[1]上,也可以点击直接看例子[2]

如何动态注册路由?

文中的每个修饰符例子都由一个页面承载,聪明的你肯定不想手动引入几十个. vue 文件并配置路由.

有什么办法可以帮我们自动完成路由注册呢?

1. 文件目录结构

目录结构(已去除其他文件目录)大概如下

`├── package.json
└── src
├── App.vue
├── main.js
├── router.js
└── views
├── About.vue
├── Home.vue
└── modifiers
├── capture.vue
├── once.vue
├── order.vue
├── passive.vue
├── prevent.vue
├── self.vue
└── stop.vue
└── …

`

2. 期望的路由配置

最终给到vue-router的配置大概长下面这个样子,每个配置最重要的部分分别是pathnamecomponent

`[
{
“path”: “/home”,
“name”: “home”,
“component”: {
“name”: “Home”,
“methods”: {},
“staticRenderFns”: [],
“_compiled”: true,
“_scopeId”: “data-v-fae5bece”,
“beforeCreate”: [
null
],
“beforeDestroy”: [
null
],
file”:”src/views/Home.vue”
}
},
{
“path”: “/modifiers/capture”,
“name”: “modifiersCapture”,
“component”: {
“name”: “capture”,
“methods”: {},
“staticRenderFns”: [],
“_compiled”: true,
“_scopeId”: “data-v-63b4eeee”,
“beforeCreate”: [
null
],
“beforeDestroy”: [
null
],
file”:”src/views/modifiers/capture.vue”
}
},
… // 其他路由配置
]

`

3. require.context 实现动态注册路由

借助 webpack require.context[3] 的能力,可以非常方便地实现上面目录到路由配置的映射工作,源码如下

`const registerRoutes = () => { const contextInfo = require.context('./views', true, /.vue$/) const routes = contextInfo.keys().map((filePath) => { // filePath 形如 ./Home.vue、./modifiers/capture.vue // path 我们希望是 / home、/modifiers/capture // 所以需要把开头的./ 和. vue 都替换为空 const path = filePath.toLowerCase().replace(/^\.|\.vue/g, '') // name 的话将 / home、/modifiers/capture 转成小驼峰即可 // 把开头的 / 先替换掉,再把第一个 / 后的单词变成大写就可以了 const name = path.replace(/^\//, '').replace(/\/(\w)/, ($0, $1) => $1.toUpperCase()) // 通过 require 去读取. vue 文件内容 const component = require(./views${filePath.replace(/^./, ‘’)}`).default

return {
path,
name,
component
}
})

return routes
}

``

效果

经过上面的简单处理,动态注册路由就完成啦!您也可以点击 vue-demos[4]查看效果

Vue 修饰符 - 图2

事件修饰符

1. 阻止冒泡的两种方式

`


我是爸爸

我是儿子


export default {
name: ‘stop’,
methods: {
onClickParent () {
console.log(‘我是爸爸’)
},
onClickChild () {
console.log(‘我是儿子’)
}
}
}

`

击子节点的时候因为事件冒泡的缘故不仅会打印出我是儿子还会打印我是爸爸。有什么办法可以阻止子节点的事件冒泡呢?

Vue 修饰符 - 图3

stop2.gif

1 .stop

只要加. stop 修饰符即可,阻止事件冒泡的及简方式,很方便是不是。

当添加上.stop修饰符时,只会出现我是儿子

`


我是爸爸

我是儿子


`

Vue 修饰符 - 图4

stop.gif

2. event.stopPropagation

当然了,我们也可以通过调用event.stopPropagation来阻止冒泡。不过更加推荐修饰符的做法,这样你的函数会更加专注在逻辑处理上,而不用关心 DOM 事件细节

`export default {
name: ‘stop’,
methods: {
onClickChild (event) {
console.log(‘我是儿子’)
event.stopPropagation()
}
}
}

`

Vue 修饰符 - 图5

stop.gif

2. 阻止默认事件的两种方式

vue 中阻止冒泡有两种方式,那阻止默认事件呢?

1 .prevent

`

点击跳转掘金


阻止默认事件,无法跳转掘金

export default {
name: ‘prevent’,
methods: {
onNoPrevent () {
console.log(‘未阻止默认事件’)
},
onPrevent () {
console.log(‘阻止默认事件’)
}
}
}

`

只要添加.prevent轻松实现阻止默认事件

Vue 修饰符 - 图6

prevent.gif

2.event.preventDefault()

和阻止冒泡一样,我们也可以通过调用事件对象的preventDefault方法来阻止默认事件

`export default {
name: ‘prevent’,
methods: {
onPrevent (event) {
console.log(‘阻止默认事件’)
event.preventDefault()
}
}
}

`

3 .capture

默认情况下,事件流是以冒泡(由里向外) 的形式传递的,如果想以捕获(由外向里)的形式应该怎么办呢?

`


父节点
自节点

export default {
name: ‘capture’,
methods: {
onClickParent () {
console.log(‘我是父节点’)
},
onClickChild () {
console.log(‘我是子节点’)
}
}
}

`

不加catpture修饰符,点击子节点会陆续打印我是父节点以及我是子节点,加了之后,则是反过来了

Vue 修饰符 - 图7

capture.gif

4 .self

只有当event.target是当前元素自身时才会触发事件回调函数

`




export default {
name: ‘self’,
methods: {
onClickSelf () {
console.log(‘我是 self 节点’)
},
onClickInner () {
console.log(‘我是 inner 节点’)
}
}
}

`

不加self修饰符的话,点击inner节点也会触发self的事件,加了之后只有触发事件的元素本身是self,才会打印出我是 self 节点

Vue 修饰符 - 图8

self.gif

暂停一下:修饰符的顺序如何理解?

已经回顾了 4 个修饰符,单独使用的时候很容易理解,但是注意官网有这么一句话

Vue 修饰符 - 图9

image.png

怎么理解呢?我们来看两个栗子

`



我是父节点,会跳转掘金


我是子节点






我是父节点,无法跳转掘金


我是子节点




export default {
name: ‘order’,
methods: {
onClickParent () {
console.log(‘我是父节点’)
},
onClickChild () {
console.log(‘我是子节点’)
}
}
}

`

您可以猜一下,上面的代码会发生什么,以下三点是可以明确的?

  1. 首先可以明确的是点击上面和下面的子节点都不会触发父节点的点击事件
  2. 点击下面的父节点会打印出我是父节点,但是不会跳转掘金
  3. 点击上面的父节点打印出我是父节点,也不会跳转掘金

但是点击上面的子节点,父节点会不会跳转至掘金呢?答案是

为什么?

a@click.self.prevent="onClickParent"的意思是当点击的元素是 a 元素本身时,会阻止默认事件(可以解释 3,不会发生跳转),并且执行onClickParent回调。

而点击 span 元素时,由于冒泡的缘故,点击事件会传递给 a,但是此时 a 会判断出该事件不是由自身触发的也就不会阻止默认事件(此时也就发生跳转了),当然也不会触发onClickParent回调

同理来我们分析一下a@click.prevent.self="onClickParent"

不管是子节点还是自身点击,都是先阻止默认事件,只有当触发点击事件是 a 元素本身时才会执行onClickParent回调函数。

Vue 修饰符 - 图10

order.gif

回过头看,你理解事件的顺序含义了吗?

Vue 修饰符 - 图11

image.png

5. once

顾名思义,事件只会触发一次

`


只触发一次

export default {
name: ‘once’,
methods: {
onClickOnce () {
console.log(‘once,我只会触发一次点击事件回调’)
}
}
}

`

触发一次点击之后,任我再怎么点,回调怎也不会触发了。

Vue 修饰符 - 图12

once.gif

6 .native

我们知道在自定义组件上,只能监听自定义事件,一些原生事件(比如 click)是没有办法直接触发的,但是使用.native修饰符可以帮我们办到这点

native.vue

`



export default {
name: ‘nativeCustom’,
methods: {
onKeydown () {
this.$emit(‘onKeydown’)
}
}
}

`

custom.vue

`




import NativeCustom from ‘../../components/native.vue’

export default {
name: ‘native’,
components: {
NativeCustom
},
methods: {
onKeydown () {
console.log(‘onKeydown’)
},
onClick () {
console.log(‘onClick’)
}
}
}

`

Vue 修饰符 - 图13

native.gif

7 .passive

vue 对应 addEventListener 中的 passive 选项[5]提供了 .passive 修饰符

<br />

这个修饰符对于滚动性能的提升,一直没找到合适的例子,跪求广大掘友有例子啊

这个修饰符对于滚动性能的提升,一直没找到合适的例子,跪求广大掘友有例子啊

这个修饰符对于滚动性能的提升,一直没找到合适的例子,跪求广大掘友有例子啊

v-bind 修饰符

8 .sync

当我们想要在父组件子组件之间对某个属性值进行双向绑定时, 有什么便捷的方式?是的只要.sync修饰符即可办到

父组件

`

我是父组件: {{text}}


import Child from ‘./child.vue’

export default {
name: ‘SyncParent’,
data () {
return {
text: ‘parent’
}
},
components: {
Child,
}
}

`

子组件

`

我是子组件:


export default {
name: ‘child’,
props: {
text: {
type: String
}
},
data () {
return {
value: this.text
}
},
methods: {
onInput () {
// 注意这里,必须是 update:xxx 的形式 xxx 即属性 prop
this.$emit(‘update:text’, this.value)
}
}
}

`

Vue 修饰符 - 图14

sync.gif

9 .camel

.camel 修饰符允许在使用 DOM 模板时将 v-bind property 名称驼峰化,例如 SVG 的 viewBox property:

`

`

10 .prop

关于. prop 修饰符官网只有这句话 .prop 作为一个 DOM property 绑定而不是作为 attribute 绑定。`。

有啥作用?

  1. 通过自定义属性存储变量,避免暴露数据
  2. 防止污染 HTML 结构

比如有以下代码

`


// 最终变成了

// 最终变成了