vue面试1

生命周期函数(父子)顺序

父beforeCreate  =>. 父created ==>. 父beforeMount ==> 子beforeCreate ==> 子created ==> 子beforeMount ==> 子mounted ==> 父mounted

更新顺序

父beforeUpdate ==> 子beforeUpdate ==> 子updated ==> 父updated

卸载顺序

父beforeDestory / 子beforeDestory / 子destroyed / 父destroyed

 

vue2自定义 v-model

props: ['text']  
model: {
   prop: 'text', event: 'change'
}
:value  @input="$emit('change')"

 

v-if(存在DOM销毁和创建,可以有多个互斥的分支)和v-show(使用 display: none 来控制是否显示)

v-html 会有XSS 风险,会覆盖 children 里面的内容

watch 深度监听一个对象,拿不到 oldvalue,因为是引用

 

v-for和v-if 不要在一个标签上面使用(在vue3上 v-if的优先级高于 v-for)

事件对象 $event 是原生的mouseEvent对象 和 react 不同
$event.target 是注册到的 div / @click定义的位置
$event.currentTarget 事件被注册到当前的元素,react是注册到 root 标签上的
但是 vue 不是
 
vue是异步渲染的,data修改之后 DOM不会立即渲染,多次 data修改做整合,只会触发渲染一次
但是可以在 $nextTick 中获取最新的DOM
 
slot 插槽
作用域插槽(使用子组件中的 data)
具名插槽(有名称)
 
动态组件 <component. :is='name'.  />
vue2只需要 名称, vue3必须是 一个具体的组件变量
 
异步组件
components: { FormDemo: () => import(.....) }
用到的时候才会去 加载对应的 js 文件,减小打包体积,提高性能
 
 
keepalive 用于频繁切换(常见性能优化
缓存组件,不需要重复渲染

 

mixin的问题

变量来源不清晰,不利于阅读,重名(当有多个的时候), 功能不能有效拆分

组件和mixin 可能出现多对多的现象
mixinMounted 先执行 mounted 后执行

 

组件化:并不是新出现的。 后端原本就有 <%include. 文件。 %>

MVVM: 数据驱动视图,不需要修改DOM,只关注于业务逻辑

vue的响应式,自动触发视图更新

proxy 兼容性不好,且无法 poly fill
 
defineProperty 的缺点
无法监听到新属性 / 下标 的 值,同样也无法 删除,无法监听原声数组,需要特殊处理
需要使用Vue.set / delete
 
复杂对象

需要开始深度监听 (递归操作),而且在赋值时也要 深度监听(在 runtime 时执行),计算量大

 

vdom 核心减少计算次数的难度, 计算出最小的变更,然后执行DOM操作
{ tag: 'div', props: { id: 'div1' }, children: [ ] } 使用JS来模拟DOM的结构
 
snabbdom 学习 vdom
h / patch 函数 h 函数接受 vdom得出vnode, patch函数负责 挂载/更新/卸载
新旧vnode对比,得出最小更新范围,最后更新DOM
 
tag都可以有 key 属性
patchVnode / addVnode / removeVnode
updateChildren key的重要性
 
diff 算法 是vdom中最核心,最关键的部分
并不是 vdom 独创的,如 Linux diff
比较2个JS对象也可以做 diff 库 jiff

 

树的时间复杂度为 O(n^3) 1000个节点,需要计算1000^3次 怎么办
优化时间复杂度到 O(n) ,怎么实现
1.只比较同一层级,不跨级比较
2.tag不相同,则直接删除重建,不再深度比较
3.tag和key相同,二者都相同,则认为是相同节点
日常中大多数就是同级比较
 

编译模板

vue template complier 将模板编译为 render 函数
执行 render 函数生成 vnode

with 要慎用,它打破了作用域规则,易读性变差
vue-loader 会在开发环境下编译模板
vue组建中使用render函数代替template

 

 组件渲染更新过程

  • 初次渲染过程
1.解析模板为render函数(或者在开发环境下完成 vue-loader)
2.触发响应式,监听data属性 getter setter
3.执行render函数,生成vnode,patch(container, vnode)
当data里面的 数据没有在 template中用到,就不会出发 getter,也就不会被监听到
因为和视图没有关系,没有用到
 
  • 更新过程
1.修改data,触发setter 此前getter中已经被监听
2.重新执行 render函数,生成newVnode
3.patch(vnode, newVnode)

异步渲染
减少DOM操作次数,提高性能
 
 
前端路由原理
hash变化会触发网页跳转,即浏览器的跳转
不会刷新页面,SPA必须的特点
hash永远不会提交到 server 端, 重写   window.onhashchange = (event) => { }
 
history 路由:URL规范的路由,跳转时不刷新页面
history.pushstate / onpopstate
window.pushstate
 
 
hash 管理系统,能用就尽量使用,比如不需要 SEO
history 可以考虑(to C 消费者)需要服务端支持
 
 
v-for中的key
diff算法中通过 tag 和 key来判断是否是 sameNode   减少DOM操作次数,提高性能
 
v-model的原理:手动控制。value和 input 事件,重新出发re-render
$props 传递给子组件
 
ajax 应该放在 mounted中: JS是单线程,放在mounted之前没有用,逻辑只会更加混乱
 
何时需要beforeDestory
解绑自定义事件 event$off
清除定时器
解除自定义的DOM事件,window.scroll
 
mutation 做原子操作
action 可以整合多个mutation操作
 
常见的性能优化
合理使用 v-show/ v-if / computed
v-for 增加 key,以及避免 v-if 一起使用
销毁事件,避免越用越卡
合理使用异步组件 / keep-alive
data 层级不要太深,因为需要深度监听
前端通用性能优化, 比如:图片懒加载
 
 
vue3有什么优势
性能更好,体积更小,更好的TS支持,更好的代码组织/逻辑复用
更多新功能,过度依赖 this,无法 treeshaking
 
vue3升级了那些功能
1.creatApp / emits
2.多事件处理 @click="one($event), two($event)"
3.fragment 以前必须是单一根节点
4.移除 .sync使用v-model代替 / 移除filter
5.异步组件 defineAsyncComponent
6.teleport / suspense
 
 
Reflect 反射到代理对象上来
规范化 / 标准化 / 函数化
代替了许多 Object 上的函数
 
proxy 如何实现监听
也是需要深度监听,并不是和defineProperty一样需要一次性监听
只有在get的时候才递归,而defineProperty需要开始就递归。提高了性能
可以原声监听数组变化
可监听新增和删除
 
.sync 实现:this.$emit('update: title', value)
 
watch和watchEffect
都可以监听,watch需要给出具体监听的值,watchEffect 则不需要
watchEffect 初始化会执行一次,要收集需要监听的数据
 
setup如何获取组件的实例: 没有 this
getCurrentInstance, data数据需要在 onMounted中才有,此时还没有完成初始化
 
vite为什么这么快
开发环境无需打包,启动很快,因为开发环境使用ES6 module
生产环境使用 rollup 并不会快很多
 
可以远程引入CDN包
可以动态引入 const add = await import('.....').default 点击按钮后才加载
 
组合式API 和 react hooks的区别
setup(相当于一个生命周期)只会被调用一次,后者会被多次调用
前者没有 useMemo/ useCallback ,因为只会被调用一次,数据已经是必包中
前者无需考虑调用顺序,后者需要保证hooks的顺序一致
 
 
 
 
 

 

posted @ 2024-03-08 19:14  escapist  阅读(2)  评论(0编辑  收藏  举报