-
比如,我在干什么的时候就会使用nextTick,传⼀个回调函数进去,在里面执行dom操作即可。
-
我也有简单了解nextTick实现,它会在callbacks里面加⼊我们传⼊的函数,然后用timerFunc异步方式调用它们,首选的异步方式会是Promise。这让我明白了为什么可以在nextTick中看到dom操作结果。
-
key的作用主要是为了更高效的对比虚拟DOM中的某个节点是否是相同节点。
-
vue在patch过程中判断两个节点是否是相同节点是key是⼀个必要条件,渲染⼀组列表时,key往往是唯⼀标识,所以如果不定义key的话,vue只能认为比较的两个节点是同⼀个,哪怕它们实际上不是,这导致了频繁更新元素,使得整个patch过程比较低效,影响性能。
-
实际使用中在渲染⼀组列表时key必须设置,而且必须是唯⼀标识,应该避免使用数组索引作为key,这可能导致⼀些隐蔽的bug;vue中在使用相同标签元素过渡切换时,也会使用key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
-
从源码中可以知道,vue判断两个节点是否相同时主要判断两者的key和元素类型等,因此如果不设置key,它的值就是undefined,则可能永远认为这是两个相同节点,只能去做更新操作,这造成了大量的dom更新操作,明显是不可取的。
-
vuex是vue专用的状态管理库。它以全局方式集中管理应用的状态,并且可以保证状态变更的可预测性。
-
vuex主要解决的问题是多组件之间状态共享的问题,利用各种组件通信方式,我们虽然能够做到状态共享,但是往往需要在多个组件之间保持状态的一致性,这种模式很容易出现问题,也会使程序逻辑变得复杂。vuex通过把组件的共享状态抽取出来,以全局单例模式管理,这样任何组件都能用一致的方式获取和修改状态,响应式的数据也能够保证简洁的单向数据流动,我们的代码将变得更结构化且易维护。
-
vuex并非必须的,它帮我们管理共享状态,但却带来更多的概念和框架。如果我们不打算开发大型单页应用或者我们的应用并没有大量全局的状态需要维护,完全没有使用vuex的必要。一个简单的store 模式就足够了。反之,Vuex 将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是:Flux 架构就像眼镜:您自会知道什么时候需要它。
-
我在使用vuex过程中有如下理解:首先是对核心概念的理解和运用,将全局状态放入state对象中,它本身一棵状态树,组件中使用store实例的state访问这些状态;然后有配套的mutation方法修改这些状态,并且只能用mutation修改状态,在组件中调用commit方法提交mutation;如果应用中有异步操作或者复杂逻辑组合,我们需要编写action,执行结束如果有状态修改仍然需要提交mutation,组件中调用这些action使用dispatch方法派发。最后是模块化,通过modules选项组织拆分出去的各个子模块,在访问状态时注意添加子模块的名称,如果子模块有设置namespace,那么在提交mutation和派发action时还需要额外的命名空间前缀。
-
vuex在实现单项数据流时需要做到数据的响应式,通过源码的学习发现是借用了vue的数据响应化特性实现的,它会利用Vue将state作为data对其进行响应化处理,从而使得这些状态发生变化时,能够导致组件重新渲染。
- vue2数据响应式实现根据对象类型做不同处理,如果是object,则通过Object.defineProperty(obj,key,descriptor)拦截对象属性访问
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val
},
set(v) {
val = v
notify()
}
})
}
如果是数组,则覆盖数组的7个变更方法实现变更通知
const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto)
;[‘push’,‘pop’,‘shift’,‘unshift’,‘splice’,‘sort’,‘reverse’]
.forEach(function (method) {
const original = arrayProto[method]
def(arrayMethods, method, function mutator (…args) {
const result = original.apply(this, args)
notify()
return result
})
})
- 可以看到vue2中有几个问题:
初始化时需要遍历对象所有key,如果对象层级较深,性能不好
通知更新过程需要维护大量dep实例和watcher实例,额外占用内存较多。
动态新增、删除对象属性无法拦截,只能用特定set/delete api代替
不支持新的Map、Set等数据结构。
- vue3中为了解决以上问题,使用原生的Proxy代替:
function defineReactive(obj) {
return new Proxy(obj, {
最后
面试一面会问很多基础问题,而这些基础问题基本上在网上搜索,面试题都会很多很多。最好把准备一下常见的面试问题,毕竟面试也相当与一次考试,所以找工作面试的准备千万别偷懒。面试就跟考试一样的,时间长了不复习,现场表现肯定不会太好。表现的不好面试官不可能说,我猜他没发挥好,我录用他吧。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
96道前端面试题:
常用算法面试题:
前端基础面试题:
内容主要包括HTML,CSS,JavaScript,浏览器,性能优化
[外链图片转存中…(img-WMCNzEne-1714382763887)]
常用算法面试题:
- [外链图片转存中…(img-Sd2j3IHn-1714382763888)]
前端基础面试题:
内容主要包括HTML,CSS,JavaScript,浏览器,性能优化