金三银四跳槽季,前端面试题记录(2021),VUE

Q、 简述一下对vue的mvvm模型的理解

mvvm:model-view-viewmodel,而vue实现了一套响应式系统实现了viewmodel层监听model(data)数据,通知view层patch dom。

响应式系统:说响应式系统是因为vue的实现很像观察者/发布订阅模式,但不完全是,这点尤其在vue3.0+的源码上提现更明显

Q、 双向绑定的实现

vue2.x: 通过Object.defineProperty实现对数据的监听;

vue3.x: 通过ES6的扩展对象Proxy实现对数据的监听,原生支持,并且对数组有天然的支持,不用像vue2.x那样要重写数组原生方法来触发数据更新,速度更快,但对浏览器兼容有要求,不支持ie11浏览器;

具体流程: 在Observer对数据的劫持,添加getter setter,在setter添加上notify,数据改变,通知到Dep订阅器,并给到Watcher订阅者重新计算,然后Compile解析器更新视图;

Q、 简述一下vue生命周期

生命周期名称触发条件
beforeCreate在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created在实例创建完成后被立即调用。但此时虚拟 DOM 还没生成,property不可用。
beforeMount虚拟 DOM 生成并且渲染前被调用。
mounted虚拟 DOM 生成并且渲染完毕后被调用
beforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
activated被 keep-alive 缓存的组件激活时调用。
deactivated被 keep-alive 缓存的组件停用时调用。
beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
errorCaptured当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

vue3.x: 舍弃了beforeCreate和created这两个生命周期,使用setup方法去代替

在这里插入图片描述

Q、组件间通讯方法有哪些

  • props、v-model向下传递
  • emit广播事件 on监听事件
  • provide提供和inject接收注入,用于跨层级组件.
  • eventBus总线事件处理
  • Vuex全局状态管理

Q、用过自定义指令吗?怎么实现一个指令

使用directive API去注册指令

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

Q、 实现一个全局toast方法

// ./ToastComponent.vue里面的代码就是普通的组件代码
import ToastComponent from "./ToastComponent.vue";


const globalToast = {
    install: function (Vue, conf_options = {}) {
        if (!conf_options) {
            conf_options = {}
        }
        const ToastConstructor = Vue.extend(ToastComponent);
        let loadedToasts = [];

        // 生成并在body子级挂载
        function toast(msg, options = {}) {
            //接受全局和局部options
            let propsData = Object.assign(conf_options, options, { msg: msg });
            // 创建组件实例
            const instance = new ToastConstructor({ propsData });
            // 挂载到body下面
            if (!instance.$el) {
                let vm = instance.$mount();
                document.body.appendChild(vm.$el);
            }
            loadedToasts.push(instance);
            return instance;
        }

        // 显示与隐藏
        function showLoading(msg) {
            loadedToasts.push(toast(msg, { type: "loading" }));
        }

        function hideLoading() {
            loadedToasts.forEach(ins => {
                ins.closeToast();
            })
        }

        // 全局注册方法
        Vue.prototype.$toast = toast;
        Vue.prototype.$showLoading = showLoading;
        Vue.prototype.$hideLoading = hideLoading;
    }
}


// 全局注册
Vue.use(globalToast);

Q、 Virtual DOM(虚拟dom)为什么比普通dom渲染快

真实dom的每一次操作方法调用,都会触发浏览器的生成的一系列操作(回流、重绘),特别是多个数据多个dom更新多次操作dom是很费性能
在这里插入图片描述
而相比dom操作,js的计算性能消耗是极其小的,通过对patch(diff算法)的优化,更新数据变化部分,它保证了不管你的数据变化多少,每次重绘的性能都可以接受。保证了性能的下限。并保证不同平台的迁移成本,可以在其他平台使用,小程序、app、桌面端。

下面vue作者尤大的话:
在这里插入图片描述

Q、 diff算法

掘金 - 请阐述vue的diff算法
知乎 - vue3.0 diff算法详解(超详细)

Q、 vue.nextTick实现

nextTick本质上是一个微任务函数,在下次DOM更新循环结束之后执行的延迟回调,如果所有微任务的方法都不支持才会采用setTimeout回调。
Vue在更新dom时是异步执行的。只要监听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个watcher被多次触发,只会被推入到队列中一次。nextTick方法会在队列中加入一个回调函数,确保该函数在前面的dom操作完成后才调用。

Q、watch与computed的区别

computed是一个属性,vue实例初始化属性的时候会运行computed属性的方法,收集方法内的属性进行监听,当监听的属性发生变化时,通知这个计算属性更新。
watch相当于添加一个观察者,但监听的属性变化时,触发watch定义的方法;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值