Skip to content

2024 面试题第一站

1.vue的组件通信

vue是一个构建页面的js框架,是一个声明式,组件式的模型。封装复用组件是vue的一大特点,组件之间的通信是封装组件必须学习的内容。

  1. 父子之间通信: props、$emit。
  2. 事件总线:eventBus.$emit、eventBus.$on,第三方js插件mitt。
  3. 依赖注入:provide、inject。
  4. 获取某个组件实例:this.$parent、this.$children、this.$refs。
  5. 全局混入 mixin。

2.vuex和pinia的区别

vuex和pina作为vue2,3的全局状态管理工具,操控全局的数据,双向数据流动,方便管理。

  1. 架构设计原则,vuex有5个核心概念:state,getter,action,mutations,modules。pina采用中心化管理有三个核心概念:state,getter,action。
  2. state中的数据修改,vuex 通过派发action,通知mutations修改state数据。pina可以直接修改state数据。
  3. 对 ts 的支持,pina对ts支持较全面。
  4. 包的大小,vuex的包大,pina小。
  5. 性能上,pina采用集中化管理状态变更,效率更高。每个Store都是独立的,更容易进行状态追踪和优化。

3.怎么实现类似vuex让两个比较远的组件进行通信

  1. 定义全局变量,在window,vuex中挂载。
  2. 路由之间的参数传递,params、query。
  3. 事件总线 EventBus、mitt。

4.定义全局变量方法

定义全局变量太多,会影响代码质量以及性能,尽量减少全局变量的定义。

  1. 使用全局变量 window,定义全局的aa变量:window.aa = 1234。
  2. 全局状态管理工具 vuex。使用:this.$store.state.baseUrl
  3. main.js定义全局变量 Vue.prototype.baseName = "asa"; 使用:this.baseName 取值;
  4. 在env文件定义全局变量VUE_APP_BASE_URL = "test"; 使用:process.env.VUE_APP_BASE_URL 获取值
  5. 全局或局部混入 mixin。
  6. 浏览器缓存。
  7. vue3 提供专门配置全局变量的api ,globalProperties、getCurrentInstance 。
  8. 使用var定义变量。

5.vue的响应式原理

vue是双向数据流动,react是单向数据流动。 双向数据流是指更新数据后,视图可以主动局部刷新,不需要主动全局刷新。 首先,遍历data的数据,通过 Obejct.defineProperty 劫持数据,给数据加上 geter 和 setter 函数,获取数据触发 getter函数, 修改数据时触发 setter函数,在 setter 函数更新视图 dom ,从而实现数据的响应式 ;原理就是发布订阅模式。vue3的响应式原理proxy替代了Obejct.defineProperty。

6.你了解过哪些设计模式

  1. 单例模式 核心思想:一个类只能有一个实例,并提供一个访问它的全局访问点,vuex的实现原理就是单例模式。 使用场景:vuex全局状态管理器 - new vuex.Store({}),在不同组件之间共享和管理状态数据。
js
<script>
  class Singleton {
    constructor(name) {
      this.name = name;
      this.instance = null;  // 用来判断是否已将创建了该类的实例
    }
    // 构造一个广为人知的接口,供用户对该类进行实例化
    static getInstance(name) {
      // 没有实例化的时候创建一个该类的实例
      if(!this.instance) {
        this.instance = new Singleton(name);
        console.log( this.instance );
      }
      // 已经实例化了,返回第一次实例化对象的引用
      return this.instance;
    }
  }
var a = Singleton.getInstance("a");
var b = Singleton.getInstance("b");
// a===b 说明指向的是唯一实例化的对象,说明a、b之间是引用关系。
console.log(a,b,a===b);  // { "name": "a","instance": null }  true
</script>
  1. 策略模式 定义:定义一系列算法,把他们全部封装起来,并是他们可以相互替换。就是把算法的使用和算法的实现分离出来。提高代码的可维护性和扩展性。核心是面向接口编程。 使用场景:使用了很多if,switch语句都可以使用策略模式改写。我们可以把策略从业务代码中抽离出来,以后维护或扩展业务,只需要修改策略即可。 核心概念:策略类(Strategy):封装了具体的算法,是算法实现的部分。环境类(Context): 算法的使用,把具体实现逻辑委托到策略类。
js
举例:公司绩效评级的方法
    // 特点:1. 一堆的if语句 2. 具体实现和使用不分离
    function computeBonus(level, basicBonus) {
        if(level === 'A') {
            return basicBonus * 1;
        } else if(level === 'B') {
            return basicBonus * 2;
        } else if(level === 'C') {
            return basicBonus * 3;
        } else if(level === 'D') {
            return basicBonus * 4;
        }
    }
    var result = computeBonus('A', 1000); 
    console.log(result);
    // 使用策略类 实现和使用分离
    // 1. 定义策略类 -- 具体实现
    const strategies = {
        'A': function(basicBonus) {
            return basicBonus * 1;
        },
        'B': function(basicBonus) {
            return basicBonus * 2;
        },
        'C': function(basicBonus) {
            return basicBonus * 3;
        },
        'D': function(basicBonus) {
            return basicBonus * 4;
        },
    }
    // 2. 定义环境类 -- 算法的使用
    function computeBonus2(level, basicBonus) {
        return strategies[level](basicBonus);
    }
    // 3. 使用环境类
    var b = computeBonus2("A",1000)
    console.log(b);
  1. 发布订阅模式(也叫观察者模式) 定义:定义了一种一对多的依赖关系,当一个对象的状态改变,其他依赖者(观察者)自动收到通知并更新 核心概念:
  2. 主题(Subject):也叫发布者,维护一组观察者,并在状态变化时通知观察者。
  3. 观察者(Observer): 也叫订阅者,负责接收主题的通知并做出对应的处理。 前端使用场景:
  4. 事件总线实现了观察者模式。
  5. 双向绑定,数据变化,自动更新相关视图。 优点:减少对象之间的依赖,实现解耦。灵活性:方便增加删除观察者。 缺点:观察者过多时,影响性能。

7.浏览器从输入url到渲染经过了哪些过程

  1. 浏览器解析URL,解析出协议、域名、方法体等信息。
  2. DNS解析,dns服务器解析url,把url解析对应的ip。
  3. 浏览器和服务器简历tcp三次链接。
  4. 浏览器发送http请求,服务器解析请求并返回响应数据。
  5. 浏览器处理数据生成dom树和cssom树合并为渲染树renderDom,加载js脚本,绘制页面。
  6. 断开tcp链接,四次挥手。

8.加载js脚本会阻塞渲染,怎么解决

使用async或defer属性来异步加载JavaScript脚本。 ● async属性会允许脚本异步加载并执行,但它不能保证脚本的执行顺序。 ● defer属性会延迟脚本的执行,直到整个页面解析完成。 ● defer和async的区别: defer:加载完资源不会执行,其他所有资源加载完毕才会执行 defer 资源,稳定。 async:加载完立即执行,如果在async代码段中修改了dom,可能出现错误,不稳定。 使用async或defer属性来异步加载JavaScript脚本。

9.watch和computed的区别?

watch是监听data和props中的数据是否改变,computed监听自己的数据是否改变。

  1. 计算属性会混入到vue实例中,watch监听data和props里面数据的变化。
  2. computed有缓存,它依赖的值变了才会重新计算,watch没有。
  3. computed是多对一(监听属性依赖其它属性)。
  4. computed必须有return返回值,watch不一定需要。
  5. 第一次加载computed就开始监听,watch如果需要第一次监听使用immediate: true; 属性。

10.vue组件的data为什么必须是函数

为什么是函数而不是对象形式。 组件复用的时候,要求每一份的数据都是独立的,互不影响,如果使用引用对象,那么复用组件中的data数据就会冲突。