面试题

57 阅读5分钟

第一次

vue中diff算法是什么,和vue3的算法有什么差异

答:

https://www.bilibili.com/video/BV1G7411N7Ef/?share_source=copy_web&vd_source=9aa11bbce84d32572e3bbacbbb4ae71e

https://juejin.cn/post/6883788411590279176?searchId=20240121112028874951F2B4DE683D04B3#heading-6

第二次

1.无论宽度如何变化,如何设置保持长宽比为 2/1

方式一:利用定位实现

.wrapper{
  position : relative;
  background: #ccc;
  width: 10%;
  padding-bottom : 20%;
}
.inner{
  position : absolute;
  top : 0; left : 0; right : 0; bottom : 0;
}
</style>
<div class="wrapper">
    <div class="inner">这是内容</div>
</div>
说明:其中奥妙就在于padding-bottom:20%, padding-bottom 是相对宽度的.也就是整个Wrapper的高度等于padding-bottom 的高度,Wrapper 没有内容高度.没有内容高度如何往其中放置我们准备的DIV呢?答案是 绝对定位, 所以Wrapper的样式中有position:relative, 方便子元素相对Wrapper的左顶点定位.

方式二:利用vw实现

.wrapper{
  position : relative;
  background: #ccc;
  width: 25vw;
  height: 50vw;
}
</style>
<div class="wrapper">
   
</div>

方式三:利用rem

.wrapper{
  position : relative;
  background: #ccc;
  width: 2rem;
  height: 4rem;
}
</style>
<div class="wrapper">
   
</div>

2.数组有哪些循环方式,那些能 break

循环数组的方式: for in, for of, for, forEach, mapfilter,reduce
其中for in, for of, for 能直接使用break中断循环
forEach, mapfilter,reduce, 不能使用break中断循环,但是可以使用throw Error阻止循环,用 try ctach包裹保证接下来的代码执行

3.vue 隔代组件怎么通讯的,有哪些方式

vue2

  1. props, emits, 一层一层传递或者Vue2.4 版本提供了另一种方法$attrs/$listeners$attrs$listeners 是两个对象,$attrs 里存放的是父组件中绑定的非 Props 属性,$listeners里存放的是父组件中绑定的非原生事件。
    但是inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性

  2. $emit/$on, 这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。 var Event=new Vue(); Event.emit(事件名,数据);Event.emit(事件名,数据); Event.on(事件名,data => {});(vue官方不推荐)

  3. vuex

  4. Vue2.2.0新增API,provide/inject, provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

  5. $parent / $children与 ref的方式(不推荐)

vue3:

  1. ref 和 defineExpose, defineExpose是子组件暴露变量, ref获取子组件调用
  2. provide 和 inject
  3. pinia 是一个为 vue3 设计的状态管理库,类似 Vuex 的设计模式,通过定义 store、状态、getter 和 action,来统一管理应用程序的状态和逻辑。
  4. 在 Vue 3 中,可以使用第三方库 mitt 实现组件之间的通信。mitt 是一个简单且强大的事件总线库(类似于 Vue 2 中的EventBus),它提供了一种方便的方式来在不同组件之间传递事件和数据。

4.js 删除一个dom节点的方式

  1. 使用Node.removeChild()方法删除dom字节点
var box=document.getElementById("box");
box.parentNode.removeChild(box);
  1. 使用Node.remove()方法删除dom节点本身
var box=document.getElementById("box");
box.remove();

remove()方法在IE等较旧的浏览器中可能无法正常工作。所以,为了获得更好的兼容性和可靠性,应该选择
removeChild()方法或innerHTML属性
  1. Node.outerHTML
const inner = document.querySelector('.inner')
inner.outerHTML = ''
  1. Node.innerHtml
const inner = document.querySelector('.inner')
inner.parentNode.innerHTML = ''

5.闭包的使用场景有哪些

  1. 封装:没有模块化之前, 闭包可以用于创建私有变量和函数,从而实现信息隐藏和封装。
  2. 函数式编程:在函数式编程中,闭包是非常有用的工具。通过使用闭包,可以创建高阶函数、延迟执行函数、柯里化等功能。
  3. 定时器和事件处理:在处理定时器和事件时,闭包可以帮助保存局部状态,从而在稍后的时间点执行所需的逻辑。
  4. 模块模式:闭包可以用于创建模块,将相关的函数和数据封装在一起,提供一种更加模块化的编程方式。
  5. 回调函数:在异步编程中,闭包常常与回调函数一起使用,可以捕获周围作用域的状态,并在回调被触发时使用这些状态。
  6. 循环中的异步操作:在循环中进行异步操作时,使用闭包可以解决由于 JavaScript 中的变量提升导致的问题,确保在异步操作完成时能够获取到正确的循环变量值。
  7. 缓存:利用闭包缓存计算结果,避免重复计算,提高程序的性能。

6.项目中 vue 的使用规范有哪些

https://v2.cn.vuejs.org/v2/style-guide/

7.vue 性能提升有哪些方式

  1. v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
  2. 长列表性能优化

Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 Vue 劫持我们的数据呢?可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

export default {
  data: () => ({
    users: {}
  }),

  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};
  1. Vue 钩子函数之钩子事件 hookEvent,监听组件简化代码

用法:

  1. 通过 $on(eventName, eventHandler) 侦听一个事件;
  2. 通过 $once(eventName,eventHandler) 一次性侦听一个事件;
  3. 通过 $off(eventName, eventHandler) 停止侦听一个事件;

通常实现一个定时器的调用与销毁我可能会以以下方式实现:

export default{
  data(){
    timer:null  // 需要创建实例
  },

  mounted(){
      this.timer = setInterval(()=>{
      //具体执行内容
      console.log('1');
    },1000);
  }

  beforeDestory(){
    clearInterval(this.timer);
    this.timer = null;
  }
}

这种方法存在的问题是:

vue 实例中需要有这个定时器的实例,感觉有点多余。创建的定时器代码和销毁定时器的代码没有放在一起,不容易维护,通常很容易忘记去清理这个定时器。

使用 监听beforeDestory生命周期可以避免该问题,并且因为只需要监听一次,所以使用 $once 进行注册监听。

export default{
  methods:{
    fn(){
      const timer = setInterval(()=>{
        console.log('1');
      },1000);

      this.$once('hook:beforeDestory',()=>{ // 监听一次即可
        clearInterval(timer);
        timer = null;
      })
    }
  }
}
  1. 组件懒加载

8.vue 中自定义组件怎么用 v-model 去改变数据