2023前端二面vue面试题

本文详述了Vue.js的面试重点,包括监听pushState和replaceState的变化、Vue路由钩子函数、函数式组件的优势和原理、Vue修饰符、diff算法、Watch中的deep:true实现、vue-router守卫、路由模式、Vuex数据丢失解决方案以及Vue3的性能优化等。内容覆盖了Vue.js的基础知识和高级特性,适合前端开发者复习和准备面试。
摘要由CSDN通过智能技术生成

如何监听 pushState 和 replaceState 的变化呢?

利用自定义事件new Event()创建这两个事件,并全局监听:

<body>
  <button onclick="goPage2()">去page2</button>
  <div>Page1</div>
  <script>
    let count = 0;
    function goPage2 () {
     
      history.pushState({
      count: count++ }, `bb${
       count}`,'page1.html')
      console.log(history)
    }
    // 这个不能监听到 pushState
    // window.addEventListener('popstate', function (event) {
     
    //   console.log(event)
    // })
    function createHistoryEvent (type) {
     
      var fn = history[type]
      return function () {
     
        // 这里的 arguments 就是调用 pushState 时的三个参数集合
        var res = fn.apply(this, arguments)
        let e = new Event(type)
        e.arguments = arguments
        window.dispatchEvent(e)
        return res
      }
    }
    history.pushState = createHistoryEvent('pushState')
    history.replaceState = createHistoryEvent('replaceState')
    window.addEventListener('pushState', function (event) {
     
      // { type: 'pushState', arguments: [...], target: Window, ... }
      console.log(event)
    })
    window.addEventListener('replaceState', function (event) {
     
      console.log(event)
    })
  </script>
</body>

Vue路由的钩子函数

首页可以控制导航跳转,beforeEachafterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

  • beforeEach主要有3个参数tofromnext
  • toroute即将进入的目标路由对象。
  • fromroute当前导航正要离开的路由。
  • nextfunction一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转

函数式组件优势和原理

函数组件的特点

  1. 函数式组件需要在声明组件是指定 functional:true
  2. 不需要实例化,所以没有this,this通过render函数的第二个参数context来代替
  3. 没有生命周期钩子函数,不能使用计算属性,watch
  4. 不能通过$emit 对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件
  5. 因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement
  6. 函数式组件的props可以不用显示声明,所以没有在props里面声明的属性都会被自动隐式解析为prop,而普通组件所有未声明的属性都解析到$attrs里面,并自动挂载到组件根元素上面(可以通过inheritAttrs属性禁止)

优点

  1. 由于函数式组件不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件
  2. 函数式组件结构比较简单,代码结构更清晰

使用场景:

  • 一个简单的展示组件,作为容器组件使用 比如 router-view 就是一个函数式组件
  • “高阶组件”——用于接收一个组件作为参数,返回一个被包装过的组件

例子

Vue.component('functional',{
    // 构造函数产生虚拟节点的
    functional:true, // 函数式组件 // data={attrs:{}}
    render(h){
   
        return h('div','test')
    }
})
const vm = new Vue({
   
    el: '#app'
})

源码相关

// functional component
if (isTrue(Ctor.options.functional)) {
    // 带有functional的属性的就是函数式组件
  return createFunctionalComponent(Ctor, propsData, data, context, children)
}

// extract listeners, since these needs to be treated as
// child component listeners instead of DOM listeners
const listeners = data.on // 处理事件
// replace with listeners with .native modifier
// so it gets processed during parent component patch.
data.on = data.nativeOn // 处理原生事件

// install component management hooks onto the placeholder node
installComponentHooks(data) // 安装组件相关钩子 (函数式组件没有调用此方法,从而性能高于普通组件)

Vue 修饰符有哪些

vue中修饰符分为以下五种
  • 表单修饰符
  • 事件修饰符
  • 鼠标按键修饰符
  • 键值修饰符
  • v-bind修饰符

1. 表单修饰符

在我们填写表单的时候用得最多的是input标签,指令用得最多的是v-model

关于表单的修饰符有如下:

  • lazy

在我们填完信息,光标离开标签的时候,才会将值赋予给value,也就是在change事件之后再进行信息同步

<input type="text" v-model.lazy="value">
<p>{
  {value}}</p>
  • trim

自动过滤用户输入的首空格字符,而中间的空格不会过滤

<input type="text" v-model.trim="value">
  • number

自动将用户的输入值转为数值类型,但如果这个值无法被parseFloat解析,则会返回原来的值

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

2. 事件修饰符

事件修饰符是对事件捕获以及目标进行了处理,有如下修饰符

  • .stop 阻止了事件冒泡,相当于调用了event.stopPropagation方法
<div @click="shout(2)">
  <button @click.stop="shout(1)">ok</button>
</div>
//只输出1
  • .prevent 阻止了事件的默认行为,相当于调用了event.preventDefault方法
<form v-on:submit.prevent="onSubmit"></form>
  • .capture 使用事件捕获模式,使事件触发从包含这个元素的顶层开始往下触发
<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>
// 输出结构: 1 2 4 3 
  • .self 只当在 event.target 是当前元素自身时触发处理函数
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击

  • .once 绑定了事件以后只能触发一次,第二次就不会触发
<button @click.once="shout(1)">ok</button>
  • .passive 告诉浏览器你不想阻止事件的默认行为

在移动端,当我们在监听元素滚动事件的时候,会一直触发onscroll事件会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
  • 不要把 .passive.prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。
  • passive 会告诉浏览器你不想阻止事件的默认行为
  • native 让组件变成像html内置标签那样监听根元素的原生事件,否则组件上使用 v-on 只会监听自定义事件
<my-component v-on:click.native="doSomething"></my-component>

<!-- 使用.native修饰符来操作普通HTML标签是会令事件失效的 -->

3. 鼠标按钮修饰符

鼠标按钮修饰符针对的就是左键、右键、中键点击,有如下:

  • .left 左键点击
  • .right 右键点击
  • .middle 中键点击
<button @click.left="shout(1)">ok</button>
<button @click.right="shout(1)">ok</button>
<button @click.middle="shout(1)">ok</button>

4. 键盘事件的修饰符

键盘修饰符是用来修饰键盘事件(onkeyuponkeydown)的,有如下:

keyCode存在很多,但vue为我们提供了别名,分为以下两种:

  • 普通键entertabdeletespaceescupdownleftright…)
  • 系统修饰键ctrlaltmetashift…)
<!-- 只有按键为keyCode的时候才触发 -->
<input type="text" @keyup.keyCode="shout()">

还可以通过以下方式自定义一些全局的键盘码别名

Vue.config.keyCodes.f2 = 113

5. v-bind修饰符

v-bind修饰符主要是为属性进行操作,用来分别有如下:

  • async 能对props进行一个双向绑定
//父组件
<comp :myMessage.sync="bar"></comp> 
//子组件
this.$emit('update:myMessage',params);

以上这种方法相当于以下的简写

//父亲组件
<comp :myMessage="bar" @update:myMessage="func"></comp>
func(e){
   
 this.bar = e;
}

//子组件js
func2(){
   
  this.$emit('update:myMessage',params);
}

使用async需要注意以下两点:

  • 使用sync的时候,子组件传递的事件名格式必须为update:value,其中value必须与子组件中props中声明的名称完全一致
  • 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用
  • prop 设置自定义标签属性,避免暴露数据,防止污染HTML结构
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值