2024年Vue 32个修饰符,你不一定全知道!,项目实战

最后

总的来说,面试官要是考察思路就会从你实际做过的项目入手,考察你实际编码能力,就会让你在电脑敲代码,看你用什么编辑器、插件、编码习惯等。所以我们在回答面试官问题时,有一个清晰的逻辑思路,清楚知道自己在和面试官说项目说技术时的话就好了

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[

{

“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 的能力,可以非常方便地实现上面目录到路由配置的映射工作,源码如下

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查看效果

事件修饰符

=====

1. 阻止冒泡的两种方式


我是爸爸

我是儿子

 

export default {

name: ‘stop’,

methods: {

onClickParent () {

console.log(‘我是爸爸’)

},

onClickChild () {

console.log(‘我是儿子’)

}

}

}

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

17c4fb3a2ffcf8cd49350779831cc72a.gif

stop2.gif

1 .stop

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

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

我是爸爸

我是儿子

 

5bfc38ff9cea576d0591e2fc52f659eb.gif

stop.gif

2. event.stopPropagation

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

export default {

name: ‘stop’,

methods: {

onClickChild (event) {

console.log(‘我是儿子’)

event.stopPropagation()

}

}

}

07e62484426dc893fe77e2481ae6f26c.gif

stop.gif

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


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

1 .prevent

<a href=“https://juejin.cn/” @click=“onNoPrevent”>点击跳转掘金



<a href=“https://juejin.cn/” @click.prevent=“onPrevent”>阻止默认事件,无法跳转掘金

export default {

name: ‘prevent’,

methods: {

onNoPrevent () {

console.log(‘未阻止默认事件’)

},

onPrevent () {

console.log(‘阻止默认事件’)

}

}

}

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

4428f17f9047398dd01dc45a31125034.gif

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修饰符,点击子节点会陆续打印我是父节点以及我是子节点,加了之后,则是反过来了

8c513876add10828083080daffcfe2f9.gif

capture.gif

4 .self


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

export default {

name: ‘self’,

methods: {

onClickSelf () {

console.log(‘我是self节点’)

},

onClickInner () {

console.log(‘我是inner节点’)

}

}

}

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

1708913f92f403b448e44f0c535d15c4.gif

self.gif

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


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

b279a30f28fd7b09d2b13debb56ec9a8.png

image.png

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

<a href=“https://juejin.cn/” class=“order-parent” @click.self.prevent=“onClickParent”>

我是父节点,会跳转掘金


<span class=“order-child” @click=“onClickChild”>

我是子节点


<a href=“https://juejin.cn/” class=“order-parent” @click.prevent.self=“onClickParent”>

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


<span class=“order-child” @click=“onClickChild”>

我是子节点

 

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回调函数。

3e54cbbd6a2d6781b0a6a68bb4100ce0.gif

order.gif

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

9a978f4e239fa66a60626c4c45c599d9.png

image.png

5. once


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

只触发一次

export default {

name: ‘once’,

methods: {

onClickOnce () {

console.log(‘once,我只会触发一次点击事件回调’)

}

}

}

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

6da13880d332e5d2e31a0d13c2d71c96.gif

once.gif

6 .native


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

native.vue

<input type=“text” @keydown=“onKeydown”>

export default {

name: ‘nativeCustom’,

methods: {

onKeydown () {

this.$emit(‘onKeydown’)

}

}

}

custom.vue

<NativeCustom @onKeydown=“onKeydown” @click.native=“onClick” />

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

export default {

name: ‘native’,

components: {

NativeCustom

},

methods: {

onKeydown () {

console.log(‘onKeydown’)

},

onClick () {

console.log(‘onClick’)

}

}

}

4f5e7d8d360c6754882dc4f0df4f2a5f.gif

native.gif

7 .passive


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

     

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

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

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

v-bind修饰符

=========

8 .sync


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

父组件

我是父组件: {{ text }}

import Child from ‘./child.vue’

export default {

name: ‘SyncParent’,

data () {

return {

text: ‘parent’

}

},

components: {

Child,

}

}

子组件

我是子组件:

<input type=“text” v-model=“value” @input=“onInput”>

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)

}

}

}

67798fc94334c377e14a31490c2840ce.gif

sync.gif

9 .camel


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

10 .prop


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

有啥作用?

  1. 通过自定义属性存储变量,避免暴露数据

  2. 防止污染 HTML 结构

比如有以下代码

// 最终变成了 

// 最终变成了

<button @click=“onGetResult”>获取结果

export default {

name: ‘prop’,

data () {

return {

prop: ‘hello prop’,

prop2: ‘hello prop2’

}

},

methods: {

onGetResult () {

const  r e f P r o p   =   t h i s . refProp = this. refProp = this.refs.prop

const  r e f P r o p 2   =   t h i s . refProp2 = this. refProp= this.refs.prop2

console.log($refProp.getAttribute(‘my-name’)) // hello prop

console.log($refProp2.getAttribute(‘my-name’)) // null

}

}

}

从示例上可以看出未使用.prop修饰符的my-name属性会绑定到dom节点的attribute,从而出现暴露的情况。

7e12893b227ae3da1e53e8e6a59dd263.gif

prop.gif

鼠标修饰符

=====

当咱们想监听用户点击了左键右键或者中键时也有修饰符可以快捷使用,分别是.left.rightmiddle,来看个例子试试

根据MDN MouseEvent.button,介绍。

41b616738d83e3e946844a711cb45686.png

image.png

在最外层div.mouse监听mousedown事件,看下用户点击的是鼠标哪个键,三个button分别用三个修饰符快捷方式监听左键中键右键并打印出leftmiddleright

<button @click.left=“onClickBtn(‘left’)”>left

<button @click.middle=“onClickBtn(‘middle’)”>middle

<button @click.right=“onClickBtn(‘right’)”>right

export default {

name: ‘mouse’,

mounted () {

},

methods: {

onClickBtn (msg) {

console.log(msg)

},

onMousedown (event) {

const mosueMsgMap = {

0: ‘鼠标左键’,

1: ‘鼠标中键’,

2: ‘鼠标右键’

}

console.log(‘点击了’, mosueMsgMap[event.button])

}

}

}

没有带鼠标回来,中键点击暂时不能演示,后续会补上

ef10a9e17436458a5c5783db3296bc9c.gif

mouse.gif

11 .left


同上例子,监听鼠标左键点击

12 .right


同上例子,监听鼠标右键点击

13 .middle


同上例子,监听鼠标中键点击

表单相关修饰符

=======

14 .trim


对于输入的内容,希望可以过滤首尾空格应该怎么做呢?

用户名:{{ name }}

用户名2:{{ name2 }}

export default {

name: ‘trim’,

data () {

return {

name: ‘’,

name2: ‘’,

}

},

watch: {

name (newVal) {

console.log('----${newVal}----')

},

name2 (newVal) {

console.log('----${newVal}----')

},

}

}

.trim修饰符可以很方便做到

b325c8c4936228c981baca046bc1f358.gif

trim.gif

15 .lazy


v-model大家都很熟悉,默认情况下,每次input事件触发的时候都会将输入框的值与其绑定的数据进行实时同步。但是如果想要实现光标离开的时候再更新数据如何实现呢?

思路1: 绑定change事件,在事件回调中手动获取target的值

思路2: 直接使用.lazy修饰符即可达到效果

无.lazy: {{ text }}

.lazy: {{ text2 }}

export default {

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

最后写上我自己一直喜欢的一句名言:世界上只有一种真正的英雄主义就是在认清生活真相之后仍然热爱它

type=“text” v-model.trim=“name2”>

用户名2:{{ name2 }}

export default {

name: ‘trim’,

data () {

return {

name: ‘’,

name2: ‘’,

}

},

watch: {

name (newVal) {

console.log('----${newVal}----')

},

name2 (newVal) {

console.log('----${newVal}----')

},

}

}

.trim修饰符可以很方便做到

b325c8c4936228c981baca046bc1f358.gif

trim.gif

15 .lazy


v-model大家都很熟悉,默认情况下,每次input事件触发的时候都会将输入框的值与其绑定的数据进行实时同步。但是如果想要实现光标离开的时候再更新数据如何实现呢?

思路1: 绑定change事件,在事件回调中手动获取target的值

思路2: 直接使用.lazy修饰符即可达到效果

无.lazy: {{ text }}

.lazy: {{ text2 }}

export default {

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

最后写上我自己一直喜欢的一句名言:世界上只有一种真正的英雄主义就是在认清生活真相之后仍然热爱它

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值