[편집 및 요약] Vue 면접에 자주 나오는 질문 20가지

青灯夜游
풀어 주다: 2022-10-17 20:20:27
앞으로
2245명이 탐색했습니다.

[편집 및 요약] Vue 면접에 자주 나오는 질문 20가지

프로그래머로서 자신이 좋아하는 직업을 찾고 싶다면 필연적으로 8부작 에세이를 많이 물어보게 됩니다. 그 중 일부는 직업과 관련이 없지만 그래도 해야 한다면 해야 합니다. 면접에 합격하고 싶어요. 그래서 저는 최근 몇 가지 인터뷰 질문을 요약하기 시작했습니다. 첫째, 이해를 강화하고 좋은 직업을 찾고, 둘째, 가능한 한 많은 친구들이 관련 지식을 빨리 익히거나 인터뷰에 성공적으로 통과하도록 돕기 위해?

이 글에서는 vue의 몇 가지 일반적인 문제를 소개합니다. 나는 이러한 질문을 난이도와 관련성에 따라 정리하여 쉽게 전환하고 이해할 수 있도록 노력합니다. 물론 이 글은 팔다리 에세이처럼 단순할 뿐만 아니라 이러한 지식 포인트가 업무에 자주 활용되기도 한다. [관련 추천 : vuejs 영상 튜토리얼]

vue lifecycle

이 질문은 일반적으로 많이 질문하지 않지만, 묻는다면 꼭 대답해야 합니다

answer

Vue2(옵션 API) Vue3(설정) 설명
beforeCreate - 인스턴스 생성 전
created - 인스턴스 생성 후
beforeMount onBeforeMount 호출됨 DOM 마운팅 전
mounted onMounted DOM 마운팅 완료 Called
beforeUpdate onBeforeUpdate 데이터 업데이트 전 호출
updated onUpdated 은 데이터가 업데이트된 후 호출됩니다.
beforeDestroy onBeforeUnmount 구성 요소가 삭제되기 전에 호출
destroyed onUnmounted 구성 요소가 삭제된 후 호출

Vue 상위-하위 구성 요소 수명 주기

이것은 이전 질문보다 조금 더 복잡합니다. 메모리를 이해하려고 노력하거나 직접 기억해 볼 수도 있습니다.

렌더링 프로세스

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 아버지 beforeCreate
아버지 created
아버지 beforeMount
코 beforeCreate
코 created
코 beforeMount
아버지 mounted

업데이트 프로세스

코 beforeUpdate
코 updated
아버지 updated

파기과정

코 beforeDestroy
코 destroyed
아버지 destroyed

참고하위 구성 요소가 비동기 구성 요소인 경우 실행 순서가 변경됩니다. 상위 구성 요소의 수명 주기가 먼저 실행된 다음 하위 구성 요소의 수명 주기가 실행됩니다.

v-if 및 v- show

이 질문은 매우 기본적인 질문이며 이해하기 쉽습니다. 인터뷰에서는 일반적으로 이 두 지침의 차이점이 무엇인지, 어떤 지침이 어떤 시나리오에 사용하기에 적합한지 묻습니다. code>v-if 는 DOM 요소가 생성되었는지 여부를 나타내고 v-show는 이 DOM 요소의 display 속성이 none<strong> </strong>

일반적으로 상태가 자주 바뀌는 곳에서는 v-show를 사용합니다. 전환 비용이 상대적으로 높기 때문에 자주 변경하지 마세요.

  • v-for 및 v-if 우선순위

    v-if表示一个dom元素是否被创建,而v-show则是控制这个dom元素的display属性是否为none

  • 一般在频繁切换状态的地方使用v-show,v-if则更适合条件不经常改变的场景,因为它切换开销相对较大

  • v-for和v-if优先级

    这个问题被问到的频率还是比较高的,虽然它在实际开发中并不会这么用。

    回答

    • 开发过程中一般不建议同时将v-for和v-if放在一个标签中使用

    • Vue2中v-for的优先级会更高,所以会先执行循环,再进行v-if判断,所以这样就会导致无论需不需展示这个元素,都会先遍历整个列表

    • 在Vue3中v-if的优先级会更高,但是当我们遍历一个数组的时候,根据数组中的某个元素进行v-if判断的时候就会报错,因为v-if会先执行此时还没有拿到这个数组。所以Vue3中依然不建议这样使用

    说一下computed和watch

    computed和watch实际工作中用的比较多,所以问的也比较多,一般理解了基本都能回答上来

    • computed是计算属性,当一个属性受一个或者多个属性影响的时候可以使用.watch是侦听器,当我们需要根据一个属性的变化而做出一些处理的时候,可以使用watch来对这个属性进行监听

    • computed具有缓存的特点,即当它所依赖的属性发生改变的时候它才会重新执行内部逻辑.如下代码

    <template>
        <div>{{ addSum }}</div>
        <div>{{ addSum }}</div>
        <div>{{ addSum }}</div>
    </template>
    <script setup>
    import { computed, ref, watch } from "vue";
    const a = ref(1)
    const b = ref(2)
    let addSum = computed(() => {
        console.log('内部逻辑执行')
        return a.value + b.value
    })
    </script>
    로그인 후 복사

    页面多次使用addSum,但是只会打印一次"内部逻辑执行"

    • watch在页面首次加载的时候默认不会执行,需要设置immediate:true首次才会执行监听

    • watch默认只监听一层数据,不监听多层数据里属性的变化,需要设置deep:true才会进行深度监听

    vue-router

    关于vue-router能问的问题非常多,比如它的实现原理,路由跳转,路由守卫等等,所以建议去系统的查看vue-router文档

    问题1:vue-router是什么,描述一下它的原理?

    Vue Router是Vue官方的路由管理器,有hash和history两种模式

    hash模式是通过监听hashchange事件来实现更新页面部分内容的操作,url后面会带有#

    history模式则是通过监听popstate事件来实现更新页面部分内容的操作原理和hash模式差不多,只不过url后面不会出现#会显得更加美观。同时会带来一个问题,因为没有#号,所以当用户刷新页面时会向服务器发请求导致请求资源为404,因此需要对nginx进行一个配置,需要把所有路由都重定向到根页面

    问题2:路由跳转方式有哪些?

    • 内置组件跳转

    • router.push({ path: '/home' }),router.replace({ path: '/home' })

    问题3:说一下路由守卫?

    路由守卫分为全局路由守卫路由独享守卫组件路由守卫

    • 全局路由守卫
    • beforeEach,接收to、from、next三个参数,每个路由跳转前都会触发,登录验证时用的比较多

    • beforeResolve,和beforeEach类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后调用

    • afterEach,在路由跳转完成后调用,接收to、from两个参数

    • 路由独享守卫

    beforeEnter

    이 질문은 실제 개발에서는 사용되지 않지만 상대적으로 자주 묻는 질문입니다. 🎜🎜🎜답변🎜🎜🎜🎜🎜개발 과정에서 동일한 태그에 v-for와 v-if를 동시에 사용하는 것은 일반적으로 권장되지 않습니다🎜🎜🎜Vue2에서 v-for의 우선순위 더 높을 것이므로 루프가 먼저 실행된 다음 v-if 판단이 수행되므로 이 요소를 표시해야 하는지 여부에 관계없이 전체 목록을 먼저 순회하게 됩니다🎜🎜🎜In Vue3 , v-if의 우선순위가 더 높을 것입니다. 그러나 배열을 순회할 때 배열의 특정 요소를 기반으로 v-if 판단을 내릴 때 오류가 보고됩니다. 왜냐하면 v-if가 먼저 실행되고 배열이 현재는 획득되지 않았습니다. 따라서 Vue3에서는 이 기능을 사용하는 것이 여전히 권장되지 않습니다🎜

    🎜computed 및 watch에 대해 이야기해 보겠습니다🎜🎜🎜computed 및 watch가 Vue3에서 더 많이 사용됩니다. 실제 작업이므로 질문이 많고 기본적으로 이해하면 답변할 수 있습니다. 🎜는 리스너입니다. 속성 변경에 따라 일부 처리를 수행해야 할 때 🎜watch🎜를 사용하여 이 속성을 모니터링할 수 있습니다.🎜🎜🎜🎜computed🎜는 캐싱의 특성을 가지고 있습니다. 속성이 변경되면 내부 로직을 다시 실행합니다. 다음 코드는🎜
    //子组件
    <template>
        <slot />
    </template>
    
    //父组件
    <Child>
      <div>默认插槽</div>  
    </Child>
    로그인 후 복사
    로그인 후 복사
    🎜페이지에서 addSum을 여러 번 사용하지만 "내부 논리 실행"은 한 번만 인쇄됩니다.🎜🎜🎜🎜🎜 watch🎜는 페이지가 처음 로드될 때 기본적으로 실행되지 않습니다. 모니터링을 실행하려면 immediate:true를 설정해야 합니다. 처음으로🎜🎜🎜🎜watch🎜기본적으로 하나의 데이터 레이어만 모니터링하고 여러 레이어는 모니터링하지 않습니다. 레이어 데이터 속성의 변경 사항을 deep:true로 설정해야 합니다. 심층 모니터링 수행🎜

    🎜vue-router🎜 🎜🎜vue-router에 관해 궁금한 점이 많이 있습니다. 구현 원리, 경로 점프, 경로 가드 등과 같은 내용이 있으므로 시스템 vue-routerDocumentation🎜🎜🎜을 확인하는 것이 좋습니다.질문 1: vue-router 란 무엇이며 그 원리를 설명합니까? 🎜🎜🎜Vue Router는 Vue의 공식 라우팅 관리자입니다. 해시와 기록의 두 가지 모드가 있습니다. 🎜🎜hash 모드는 hashchange를 수신하여 페이지 콘텐츠의 일부를 업데이트합니다. > 이벤트, URL 뒤에 숫자 #🎜🎜가 붙습니다. history 모드는 작동 원리를 구현하고 popstate 이벤트. hash 모드는 URL 뒤에 #가 표시되지 않는다는 점을 제외하면 비슷합니다. 동시에 문제가 발생합니다. # 번호가 없기 때문에 사용자가 페이지를 새로 고칠 때 서버에 요청이 이루어지며 결과적으로 404 리소스 요청이 발생합니다. nginx 구성이 필요합니다. 모든 경로는 루트 페이지로 리디렉션되어야 합니다🎜🎜🎜질문 2: 라우팅 점프 방법은 무엇입니까? 🎜🎜🎜🎜🎜내장 구성 요소 점프🎜🎜🎜router.push({ 경로: '/home' }),router.replace({ 경로: '/ home' ' })🎜🎜🎜질문 3: 라우팅 가드에 대해 알려주세요. 🎜🎜🎜루트 가드는 🎜글로벌 루트 가드🎜, 🎜루트 독점 가드🎜, 🎜컴포넌트 루트 가드🎜🎜
      🎜글로벌 루트 가드
      🎜🎜beforeEach, to, from 및 next의 세 가지 매개변수를 받습니다. 각 경로 점프 전에 트리거됩니다. 종종 다음 용도로 사용됩니다. 🎜🎜🎜beforeResolvebeforeEach와 유사하지만 탐색이 확인되기 전과 가드 및 비동기 라우팅 구성 요소 후에 호출된다는 차이점이 있습니다. 모든 구성 요소에서 해결됩니다🎜 🎜🎜afterEach, 경로 점프가 완료된 후 호출되고 🎜
      🎜경로에 대한 독점 가드
    🎜beforeEnter는 일반적으로 라우팅 구성 파일(router/index.js)에 구성되어 있으며 특정 경로에 진입하기 전에 관련 작업을 수행합니다🎜
    • 组件路由守卫

    接收to、from、next三个参数

    • beforeRouteEnter,进入该组件之前调用,无法获取到vue实例

    • beforeRouteUpdate,在当前路由改变,但是该组件被复用时调用

    • beforeRouteLeave, 在离开当前组件时调用

    vue2和vue3区别

    当面试问你会用vue3吗,如果你回答会用的话,那么大概率会问vue2和vue3有哪些区别,最近我去面试的时候百分之90都问了这个问题。

    回答

    • 写法上的区别:vue2使用的是options(选项)Api,vue3的是composition Api(当然vue3也兼容composition api)。options Apimethods,compute,data等api都是分散的。而composition api中的代码是根据逻辑功能来组织的,我们可以将一个功能所定义的methods,compute,data等api会放在一起,让我们可以更灵活地组合组件逻辑。

    • vue2将响应式数据放到data函数中,而vue3则是使用refreactive将数据声明为响应式

    • 响应式实现方式:vue2中是通过Object.defineProperty对数据劫持实现的,vue3中则是使用Proxy对数据代理实现的。

    • 生命周期区别:vue3中将beforeCreatecreated合并到了setup函数中

    • 根节点: vue3组件允许多个根节点,而vue2只允许一个

    • 内置组件: vue3新增了传送组件Teleport和异步依赖处理组件Suspense

    vue插件使用

    面试一般会问你如何写一个vue插件,所以没写过vue插件的最好去亲自体验一下

    回答:

    vue实例会有一个use函数,它接受的是一个带有install函数的对象和一个可选的选项对象,当我们使用 vue.use(plugin)或者app.use(plugin)会调用我们插件的install属性的函数,并且将当前组件的实例传进来.所以在插件中就可以对这个实例进行一些操作来实现我们插件的功能

    vue插槽

    插槽slot可以理解为占坑,当使用一个组件的时候,在组件标签里的对应的内容就会替换掉这个组件中的slot标签。

    插槽分为默认插槽具名插槽作用域插槽

    默认插槽子组件中用slot标签来确定渲染位置,父组件使用它时直接在子组件的标签内写入内容即可

    //子组件
    <template>
        <slot />
    </template>
    
    //父组件
    <Child>
      <div>默认插槽</div>  
    </Child>
    로그인 후 복사
    로그인 후 복사

    具名插槽

    顾名思义就是具有名字的插槽,子组件中可以用name熟悉对slot命名,父组件在使用的时候通过template中的v-slot:name或者#name来定义这个插槽中的内容

    //子组件
    <template>
      <slot name="content"></slot>
    </template>
    
    //父组件
    <Child>
        <template v-slot:content>具名插槽内容</template>
    </Child>
    로그인 후 복사

    作用域插槽

    子组件中的slot可以通过类似组件属性传递的方式将子组件的值传递给父组件中这个子组件的插槽内容中(子组件标签内),在父组件使用子组件的时候要用v-slot的值进行接收这些参数,默认插槽可以将其直接写在子组件标签上,具名插槽则写在template上。而传过来的值只能在子组件标签中或者template标签中使用。所以在父组件作用域中获取到了子组件作用域中的变量,可以认为作用域插槽延伸了子组件数据的作用范围,因此叫做作用域插槽

    如果你想详细理解插槽的作用可以阅读这篇文章Vue3中插槽(slot)用法汇总 - 掘金 (juejin.cn)

    组件通信

    这里我大概归纳了一下vue2和vue3的传参方式

    way Vue2 Vue3
    아버지가 아들에게 props props
    아들이 아버지에게 $emit 방출
    아버지가 아들에게 $ attrs attrs
    son to father $listeners None(attrs 방식으로 병합)
    father to son provide/inject provide/inject
    하위 구성 요소 액세스 상위 구성 요소 $parent None
    상위 구성 요소가 하위 구성 요소에 액세스 $children None
    상위 구성 요소가 하위 구성 요소에 액세스 $ref expose&ref
    형제 구성 요소 전달 값 EventBus 미트

    它们的具体用法可以参考我的这篇文章盘点Vue2和Vue3的10种组件通信方式(值得收藏) - 掘金 (juejin.cn)

    除了上面的传参方式你也可以回答Vuex和Pinia,前提你了解这两个状态管理器,因为你说了大概率下个问题就会问你Vuex和Pinia

    vuex

    面试问到这个问题的时候,不要上来就开始说什么state,mutation...。你要先阐述Vuex干嘛用的,什么时候需要用Vuex。

    回答

    • Vuex是Vue中的全局状态管理框架,它可以管理应用的所有组件的状态。并不是每个项目都需要引入Vuex的,当我们的项目有很多个页面,并且这些页面共享着多个数据状态,此时我们可以引入Vuex。

    • Vuex有三个核心的概念,state,mutations,actions,其中state为存放数据的地方,mutations中的函数作用则是用来修改stateactions中一般是用了处理一些异步操作的函数。

    • Vuex除了上面三个概念还有getters,moudlesgetters就像Vue中的计算属性computed一样用来描述依赖响应式状态state中的复杂逻辑。moudles则是可以将store分割成模块(module),每个模块都拥有自己的state,mutations,actions等,在大型应用中经常用到

    • 场景:当我们异步获取结果并赋值给state的时候,比如数据请求,我们可以在actions中进行数据请求,拿到结果通过它的dispatch方法调用mutations中修改state的函数,从而将结果赋值给了state

    pinia

    这个现在问的好像不多,从我最近面试来看只有我提到了才会问一下,但是以后问的肯定会越来越多。关于pinia问的一般是它和Vuex的区别,确切的说应该是它和Vuex4之间的区别

    回答

    pinia其实就是Vuex5,它和Vuex的主要区别有以下几点

    • Pinia使用更简单,更符合开发者的开发习惯

    • pinia中没有了mutations,状态state的修改可以直接进行修改,或者在actions中修改,或者使用它的$patch方法进行修改

    • pinia中没有了modules,如果想使用多个store,直接使用defineStore定义多个store传入不同的id即可

    • 更好的TS支持,不需要创建自定义的复杂包装器来支持TS

    vue自定义指令

    vue 官方提供了v-text、v-for、v-model、v-if 等常用的指令。除此之外vue 还允许开发者自定义指令。面试经常会问什么是自定义指令?你用自定义指令做过哪些功能?

    回答1:什么是自定义指令?

    • 自定义指令包含局部指令和全局指令,在模板中使用指令前必须先使用directives选项注册。局部指令指在某个组件中注册,而全局则是将指令注册到全局,通常在main.js中注册。

    • 自定义指令由一个包含类似组件生命周期钩子的对象来定义。它的生命周期钩子包含created,beforeMount,mounted,beforeUpdate,updated,beforeUnmount,unmounted,

    • 常用的钩子为mounted 和 updated,它接受el,binding等参数.binding参数的值一般包含绑定到这个元素上的信息,比如下面这个指令

    <div v-example:foo.bar="baz">
    로그인 후 복사

    它的binding会是这个对象

     {
        arg: 'foo',
        modifiers: { bar: true },
        value: /* `baz` 的值 */,
        oldValue: /* 上一次更新时 `baz` 的值 */ 
     }
    로그인 후 복사

    回答2:你用自定义指令做过哪些功能?

    • 数据埋点,通过绑定自定义事件传入点击当前元素需要埋点的事件名,在指令中监听当前元素的点击事件后调用后台接口将事件名传入

    • 权限控制,通过绑定自定义事件传入控制当前元素的权限字段,在指令中获取到当前元素根据权限字段来控制该元素的状态(显示,隐藏等)

    • ...

    keep-alive

    官网描述

    <KeepAlive>는 내장 구성 요소이며, 해당 기능은 여러 구성 요소 간에 동적으로 전환할 때 제거된 구성 요소 인스턴스를 캐시하는 것입니다. <KeepAlive> 是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。

    回答

    • 通常我们切换组件的时候,上一个组件就会被销毁,而当我们使用<KeepAlive>将其包裹的话这个组件就会被缓存,当这个组件再一次被显示时就会保留之前的状态。

    • keep-alive接收两个属性include 和 exclude,分别代表哪些组件要用缓存和哪些不需要缓存,它接收组件的名字数组,字符串或者正则,当我们使用动态组件component或者路由router-view的时候可以使用

    • keep-alive还接收max属性表示最大缓存实例数,如果超出这个数则最久没有被访问的缓存实例将被销毁。

    • keep-alive有两个生命周期,分别是activateddeactivatedactivated钩子会在首次挂载或者每次从缓存中被重新插入的时候调用。deactivated钩子则是在组件从DOM上移除或者组件卸载时调用

    vue2混入-Mixin

    vue3中已经没有Mixin这个概念了,所以未来被问到的几率会越来越小,但是目前被问到的频率还是很高的。一般会它的概念以及优缺点,有时还会问它与父组件的生命周期执行顺序

    vue官网描述:

    混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

    回答1.MixinMixin的生命周期会在父组件生命周期之前执行,如果Mixin

    Answer

    보통 컴포넌트를 전환하면 이전 컴포넌트가 소멸되지만 <KeepAlive>를 사용하여 래핑하면 이 컴포넌트가 소멸됩니다. .는 캐시되며 구성 요소가 다시 표시될 때 이전 상태가 유지됩니다.

    keep-alive는 두 가지 속성 includeexclude를 받습니다. 이 속성은 각각 캐시해야 하는 구성 요소와 캐시해야 하는 구성 요소를 나타냅니다. 구성 요소의 이름 배열, 문자열 또는 정규식을 받는 캐시가 아닌 동적 구성 요소인 구성 요소 또는 라우팅 router-view
    • 를 사용할 때 사용할 수 있습니다. keep-alive는 최대 캐시 인스턴스 수를 나타내는 max 속성도 받습니다. 이 숫자를 초과하면 가장 오랫동안 액세스하지 않은 캐시 인스턴스가 삭제됩니다. 의해 파괴됨. Object.defineProperty这个api来对数据进行劫持并结合发布者-订阅者模式实现的

    • 首先会利用Object.defineProperty中的get函数来对vue中的data的所有属性进行访问劫持,中间会涉及到劫持data中更深层次的属性需要递归调用劫持方法。这里是通过一个Observer类实现的

    • 劫持到每一个属性后会给这个属性绑定多个订阅者watcher,因为一个属性可能被用在很多地方;而这个watcher中则包含更新视图的函数update

    • watcher和属性的对应关系以及和视图的联系则是通过编译模板Compile类来实现的。Compile中会拿到整个dom对象,然后遍历元素子节点获取到使用过vue中data属性的则给该属性直接添加一个watcher并赋予一些更新当前视图的方法.

    • 每个属性的多个订阅者watcher都会被添加到对应的数组中,这里则是通过Deps类实现的,初始化watcher的时候会调用Deps中的addSub方法将对应watcher添加该类的Subs数组中

    • 当data中的某个属性发生改变时则会触发Object.defineProperty中的set函数,这时便会调用该属性的Deps类中的notify函数遍历Subs数组中的订阅者watcher并调用其函数update去触发视图的更新

    Object.defineProperty和proxy区别

    一般问完响应式原理可能会问这两者的区别

    回答

    • Object.defineProperty 只能代理属性,Proxy 代理的是对象。

    • 对象上新增属性,Proxy可以监听到,Object.defineProperty

    • 🎜keep-alive에는 두 가지 수명 주기, 즉 활성화비활성화, 활성화 >가 있습니다. 후크는 처음 마운트될 때 또는 캐시에서 다시 삽입될 때마다 호출됩니다. 비활성화 후크는 구성 요소가 DOM에서 제거되거나 구성 요소가 제거될 때 호출됩니다🎜

    🎜vue2 Mixin🎜 🎜🎜Vue3에는 더 이상 Mixin이라는 개념이 없으므로 앞으로 질문을 받을 확률은 점점 줄어들겠지만, 질문을 받는 빈도는 여전히 매우 높습니다. 일반적으로 말하면, 그 개념, 장단점에 대해 배우게 되며 때로는 그것과 상위 구성 요소 사이의 라이프 사이클 실행 순서에 대해서도 질문하게 될 것입니다. 🎜🎜vue 공식 웹사이트 설명: 🎜🎜🎜Mixin은 매우 유연한 방법을 제공합니다. 재사용 가능한 기능으로 구성요소를 배포합니다. 믹스인에는 모든 구성 요소 옵션이 포함될 수 있습니다. 구성 요소가 믹스인을 사용하면 해당 믹스인의 모든 옵션이 구성 요소 자체의 옵션에 "혼합"됩니다. 🎜🎜🎜Answer🎜1. Mixin의 기능은 컴포넌트가 사용해야 할 때 추출된 부분을 컴포넌트에 혼합하는 것입니다. 2. 🎜의 속성이나 메서드가 상위 구성 요소와 충돌하는 경우 상위 구성 요소의 속성이나 메서드가 사용됩니다. 2. 장점: 코드 중복을 줄이고 논리 재사용성을 향상시킬 수 있습니다. 3. 단점: 네이밍 충돌이 쉽고, 소스 추적이 어렵고, 추후 문제 해결이 불편함🎜🎜🎜vue 대응 원칙🎜🎜🎜이 질문은 제가 경험한 거의 모든 인터뷰에서 자주 받는 질문이었습니다. , 그리고 이것은 인터뷰에서 Vue에 대한 시작 질문입니다. 🎜🎜다음은 제가 직접 이해한 답변입니다. vue2를 예로 들어 참고하실 수 있습니다.🎜🎜🎜🎜vue의 반응 원리는 Object.defineProperty API를 기반으로 합니다. 데이터를 하이재킹하여 결합하여 게시합니다. 구독자-구독자 모델로 구현된 🎜🎜🎜는 먼저 Object.definePropertyget 함수를 사용하여 모든 속성에 액세스합니다. vue.의 데이터 중 중간에는 데이터의 더 깊은 속성을 하이재킹하는 작업이 포함되며 하이재킹 메서드를 재귀적으로 호출해야 합니다. 이는 Observer 클래스를 통해 구현됩니다🎜🎜🎜각 속성을 하이재킹한 후 여러 구독자 watcher가 이 속성에 바인딩됩니다. 여러 곳에서 이 watcher에는 뷰를 업데이트하는 update 함수가 포함되어 있습니다. 🎜🎜🎜watcher와 속성 간의 대응 관계 및 뷰와의 연결은 템플릿 Compile 클래스를 컴파일하여 구현됩니다. Compile은 전체 dom 객체를 가져온 다음 요소 하위 노드를 순회하여 vue에서 데이터 속성을 얻은 다음 watcher를 속성에 직접 추가하고 현재 업데이트를 할당합니다. 보기 방법.🎜🎜🎜각 속성에 대한 여러 구독자 watcher가 해당 배열에 추가됩니다. 여기서는 Deps 클래스를 통해 구현됩니다. 예, 초기화할 때 watcher, DepsaddSub 메서드가 호출되어 watcher에 해당하는 이 클래스의 를 추가합니다. Subs array🎜🎜🎜데이터의 속성이 변경되면 Object.definePropertyset 함수가 실행됩니다. 속성의 Deps 클래스에 있는 notify 함수가 호출되어 Subs 배열의 구독자 watcher를 순회합니다. 그리고 해당 함수 update를 호출하여 뷰🎜

    🎜Object.defineProperty와 프록시의 차이점🎜 업데이트를 트리거합니다. 🎜🎜일반적인 질문 반응 원리를 완료한 후 두 가지의 차이점을 물어볼 수 있습니다🎜🎜🎜Answer🎜🎜🎜🎜🎜Object.defineProperty는 프록시 속성만 가능하며 Proxy 객체를 프록시할 수 있습니다. 🎜🎜🎜개체의 새로운 속성은 프록시로 모니터링할 수 있지만 Object.defineProperty로는 모니터링할 수 없습니다. 🎜

  • Object.defineProperty 的代理行为是在破坏原对象的基础上实现的,Proxy 则不会破坏原对象,只是在原对象上覆盖了一层。

  • 数组新增修改,Proxy可以监听到,Object.defineProperty不能。

  • Proxy不兼容IE11及以下

  • vue3内置组件

    vue3新增了两个内置组件分别是TeleportSuspense

    • Teleport组件

    可以称之为传送门,作用将其插槽内容渲染到 DOM 中的另一个位置,接收两个参数to(要去的位置)和disabled(是否留在原位置)。接收比如下面代码

    <teleport to="#popup"> 
        <video src="./my-movie.mp4"> 
    </teleport>
    로그인 후 복사

    video将会被传送到id为popup的元素下。

    • Suspense组件
    • <Suspense> 组件用于协调对组件树中嵌套的异步依赖的处理。

    • 它一般用于包裹多个异步组件处理多个异步组件加载前与完成后的统一状态

    • <Suspense> 组件有两个插槽:#default 和 #fallback,在初始渲染时,<Suspense> 将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起状态等待异步组件加载完毕。在挂起状态期间,展示的是 #fallback插槽内容

    nextTick及原理

    关于nextTick会问到它的用法,然后是它的原理,然后还可能问到JS的时间循环机制。

    问题1:vue中的nextTick是干什么用的?

    这个其实比较简单,用过都知道它是干嘛的,vue官方的解释是:

    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    这是什么意思呢,其实vue中修改data不会立刻触发dom更新;而是把需要更新的Watcher加入到queueWatcher队列中,然后在合适的时机在nextTick中调用这些Watcher的更新函数进行dom更新,所以在data刚被修改的时候,我们是获取不到更新后的dom的,这时候便需要调用nextTick函数在它的回调函数中获取到变化后的dom

    问题2:nextTick原理

    • nextTick原理是借助浏览器事件循环来完成的,因为每次事件循环之间都有一次视图渲染,nextTick尽量在视图渲染之前完成dom更新,所以nextTick优先使用的是promise(微任务)实现

    • 每次执行nextTick时会将传入的回调函数放入一个队列中(callbacks数组),然后当在本次事件循环的同步代码执行完毕后开启一个微任务(promise或者MutationObserver)去依次执行这个callbacks中的回调函数。

    • 但是当浏览器不支持promise的时候在vue2中会进行进行降级处理,依次使用setImmediatesetTimeout开启一个宏任务执行callbacks

    • 当一个data数据更新时对应的watcher便会调用一次nextTick,将它对应的dom更新操作作为回调函数放入callbacks中,所以当我们想获取这个data更新后的dom需要在其值变化后也调用nextTick将回调函数传入排在上个更新dom的回调函数后面,所以我们可以在这个nextTick的回调函数中获取到更新后的data

    问题3:js事件循环机制

    不属于vue,后面文章再介绍

    vue虚拟dom,diff算法

    这题在工作中有用吗是???答案是没有用,但是在面试中有用啊,所以我们要会回答?

    问题1:什么是虚拟dom?

    简单来说就是一个描述dom结构的js对象

    问题2:为什么要用虚拟dom?

    • 每当我们用原生JS或者JQ操作DOM时,浏览器会从头开始进行DOM树的构建,频繁的操作DOM开销是很大的。

    • 而虚拟DOM就是为了减少这些操作的,虚拟DOM首先会通过状态生成一个虚拟节点树(js对象),然后使用虚拟节点树进行渲染。当某些状态发生变更时会生成新的虚拟DOM节点树,然后与上一次虚拟DOM节点树进行比较(diff),从而找到差异的部分,最后渲染到真实的DOM节点上面

    问题3:说一下diff算法

    diff 알고리즘의 본질은 노드를 최대한 재사용하려는 목적으로 두 객체 사이의 차이점을 찾는 것입니다. vue에서는 상태가 변할 때 변경 후의 가상 DOM과 변경 전의 가상 DOM의 차이를 계산하는 데 사용되는 알고리즘입니다.

    구체적인 구현은 몇 문장으로 명확하게 설명할 수 없습니다. 기사를 추천합니다

    Vue의 이중 끝 diff 알고리즘에 대해 이야기해 보겠습니다 - Nuggets(juejin.cn)

    결론

    위 질문은 기본적으로 참고 사항입니다. 부분은 제가 이해한 내용을 바탕으로 정리한 것이므로, 일부 오류나 부족한 부분이 있을 수 있으니 발견하시면 지적해 주시기 바랍니다.

    (학습 영상 공유:

    웹 프론트엔드 개발, 기본 프로그래밍 영상)

    위 내용은 [편집 및 요약] Vue 면접에 자주 나오는 질문 20가지의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:juejin.cn
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿
    회사 소개 부인 성명 Sitemap
    PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!