>웹 프론트엔드 >View.js >[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

青灯夜游
青灯夜游앞으로
2022-07-06 19:55:144297검색

이 기사는 기본 지식을 정리하고 Vue 지식 보유량을 높이는 데 도움이 되는 몇 가지 Vue 인터뷰 질문(답변 분석 포함)을 요약하고 공유합니다.

[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

(학습 동영상 공유: vue 동영상 튜토리얼)

1. Vue.js의 기본 문제

1.1 Vue 반응 원리

[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

핵심 구현 수업:
관찰자: 해당 역할은 종속성 수집 및 업데이트 전달을 위해 개체의 속성에 getter 및 setter를 추가하는 것입니다. Dep: 하위 개체를 포함한 각 응답형 개체에는 Dep 인스턴스( (내부의 하위 항목은 Watcher 인스턴스의 배열입니다.) 데이터가 변경되면 각 감시자는 dep.notify()를 통해 알림을 받습니다.
Watcher: Observer 객체, 인스턴스는 렌더링 감시자(render watcher), 계산된 속성 감시자(computed watcher), 청취자 감시자(user watcher)의 세 가지 유형으로 구분됩니다.

Watcher와 Dep의 관계: watcher는 dep를 인스턴스화합니다. 그리고 dep.subs에 구독자를 추가했고, dep는 노티파이를 통해 dep.subs를 순회하여 각 감시자 업데이트를 알렸습니다.

종속성 컬렉션: initState를 사용하면 계산된 속성이 초기화되고 계산된 감시자 종속성 컬렉션이 트리거됩니다.
initState가 사용되면 수신 속성이 초기화되면 사용자 감시자 종속성 컬렉션이 트리거됩니다. render() 프로세스는 렌더링 감시자 종속성 컬렉션을 트리거합니다.
다시 렌더링할 때 vm.render()가 다시 실행되고 모든 하위 항목의 감시자 구독이 제거되고 다시 할당됩니다.

업데이트 배포:
응답 데이터가 구성 요소에서 수정되어 setter 로직을 트리거합니다. dep.notify() 호출
모든 하위 항목(감시자 인스턴스)을 탐색하고 각 감시자의 업데이트 메서드를 호출합니다.

원리:
Vue 인스턴스를 생성할 때 Vue는 데이터 옵션의 속성을 순회하고 Object.defineProperty를 사용하여 속성에 getter 및 setter를 추가하여 데이터 읽기를 하이재킹합니다(getter는 컬렉션에 의존하는 데 사용됩니다. 업데이트를 전달하는 데 사용되며 내부적으로 종속성을 추적하여 속성에 액세스하고 수정될 때 변경 사항을 알립니다. 각 구성 요소 인스턴스에는 구성 요소 렌더링 프로세스 중에 종속성의 모든 데이터 속성(종속성 수집, 계산된 감시자, 사용자 감시자 인스턴스)을 기록하는 해당 감시자 인스턴스가 있습니다. 나중에 종속성이 변경되면 setter 메서드가 이를 알립니다. 이 데이터에 의존하여 재계산(업데이트 디스패치)하고 관련 구성 요소를 다시 렌더링하는 감시자 인스턴스입니다.

한 문장으로 요약:
vue.js는 게시-구독 모드와 결합된 데이터 하이재킹을 사용하고 Object.defineproperty를 사용하여 각 속성의 setter 및 getter를 하이재킹하고 데이터가 변경되면 구독자에게 메시지를 게시하며 응답 모니터링 콜백

1.2. Vue.js의 특징

사용하기 쉬움: 간단하고, 배우기 쉽고, 빠르게 시작합니다.
유연성: (프로그레시브) 라이브러리와 라이브러리 간에 자유롭게 확장할 수 있는 성장하는 생태계 완전한 프레임워크.

효율성: 20kB min+gzip 실행 크기, 초고속 가상 DOM, 가장 걱정 없는 최적화
양방향 바인딩: 높은 개발 효율성
구성 요소 기반 코드 공유
웹 프로젝트 엔지니어링, 가독성 및 유지 관리 용이성 향상

1.3. Vue.js 양방향 바인딩의 원리

Vue.js 2.0은 게시자-구독자 모드(PubSub 모드)와 결합된 데이터 하이재킹(프록시 모드)을 사용하여 Object.defineProperty()를 통해 각 개별 객체를 하이재킹합니다. setter 및 getter는 데이터가 변경되면 구독자에게 메시지를 게시하여 해당 수신 콜백을 트리거합니다.
각 구성 요소 인스턴스에는 해당 감시자 프로그램 인스턴스가 있습니다. 나중에 종속성 설정자가 호출되면 감시자에게 알림이 전달되어 관련 구성 요소가 렌더링됩니다. 갱신하세요.


Vue.js 3.0, Object.defineProperty를 포기하고 더 빠른 ES6 기본 프록시 사용(프록시라고도 불리는 개체 인터셉터에 액세스)

단계:

1. 관찰해야 할 데이터 객체를 하위 속성 객체의 속성을 포함하여 재귀적으로 순회하며, 이 객체에 값이 할당되면 setter가 트리거됩니다.
2.compile은 템플릿 명령을 구문 분석하고 템플릿의 변수를 데이터로 바꾼 다음 렌더링 페이지 보기를 초기화하고 각 명령에 해당하는 노드를 업데이트 함수에 바인딩하고 구독자를 추가하여 모니터링합니다. 데이터가 변경되면 알림을 받고 뷰를 업데이트합니다.
3. 감시자 구독자는 관찰자와 컴파일 사이의 통신 브리지입니다. 그것이 수행하는 주요 작업은 다음과 같습니다. ① 인스턴스화될 때 속성 구독자(dep)에 자신을 추가합니다. update() 메소드가 있어야 합니다. ③ dep.notice()에 의해 속성 변경이 통지되면 자체 update() 메소드를 호출하고 컴파일에 바인딩된 콜백을 트리거하면 완료됩니다.
4. MVVM은 데이터 바인딩의 입구로서 Observer, Compile 및 Watcher를 통합합니다. Observer를 사용하여 자체 모델 데이터의 변경 사항을 모니터링하고 Compile을 사용하여 템플릿 지침을 구문 분석 및 컴파일하고 마지막으로 Watcher를 사용하여 Observer와 Observer 간의 통신을 설정합니다. 데이터 변경 -> 보기 업데이트, 보기 대화형 변경(입력) -> 데이터 모델 변경의 양방향 바인딩 효과를 달성하기 위해 브리지를 컴파일합니다.

1.4. Vue에서 특정 속성 값의 변경을 모니터링하는 방법은 무엇입니까?

예를 들어, 이제 데이터에서 obj.a의 변경 사항을 모니터링해야 합니다. 다음과 같이 Vue에서 객체 속성의 변경 사항을 모니터링할 수 있습니다.

watch: {
      obj: {
      	handler (newValue, oldValue) {
        console.log('obj changed')
      },
      deep: true
    }

deep 속성은 깊은 순회를 나타내지만 이렇게 작성하면 obj의 모든 속성 변경 사항을 모니터링하게 되는데, 이는 우리가 원하는 효과가 아니므로 몇 가지 수정을 가하세요.

watch: {
   'obj.a': {
      	handler (newName, oldName) {
        console.log('obj.a changed')
      }
   }
  }

계산된 속성을 사용하여 종속성이 변경되면 새 값이 다시 계산됩니다.

1.5. Vue.js 3.0은 DefineProperty를 포기하고 프록시 이유를 사용합니다.

Object.defineProperty 결함

1. 배열 첨자의 변경 사항을 모니터링하는 데 비용이 많이 듭니다. 그래서 Vue.js는 아래 첨자 변경 감지를 포기했습니다.
2.Object.defineProperty는 객체의 속성만 하이재킹할 수 있는 반면 Proxy는 직접 프록시 객체입니다. 3.Object.defineProperty는 객체의 각 속성을 순회해야 합니다. 속성 값도 객체인 경우 심층 순회가 필요합니다. 프록시는 개체를 직접 프록시하며 순회 작업이 필요하지 않습니다.

4. Object.defineProperty에는 새 속성을 수동으로 관찰해야 합니다. vue2는 새 속성도 응답하는지 확인하기 위해 vm.$set를 사용해야 합니다
5. 프록시는 DefineProperty에 없는 13가지 유형의 가로채기 작업을 지원합니다.
6. 프록시는 장기적으로 JS 엔진이 새로운 표준입니다. 프록시는 계속 최적화되지만 getter 및 setter는 기본적으로 더 이상 대상 방식으로 최적화되지 않습니다

1.6 Vue 2의 데이터에 있는 객체 속성에 새 속성이 추가되면 어떻게 되나요? 어떻게 해결하나요?

뷰가 새로 고쳐지지 않습니다. 이는 Vue 인스턴스가 생성될 때 새 속성이 선언되지 않아 Vue에 의해 반응형 속성으로 변환되지 않고, 당연히 뷰 업데이트가 트리거되지 않기 때문입니다. 이 경우 Vue의 전역 속성을 사용해야 합니다. api $set():

computed: {
    a1 () {
      return this.obj.a    
      }
}

1.7 Computed와 Watch의 차이점 및 해당 응용 시나리오

computed attribute:

다른 속성 값에 따라 달라지며 계산된 값만 캐시됩니다. 변경 시 계산된 값은 다음 번에 얻어집니다. 계산된 값은 해당 값에 도달한 경우에만 다시 계산됩니다. 감시 리스너:
이는 특정 데이터의 모니터링 콜백과 유사하게 캐싱이 없는 관찰 기능에 가깝습니다. 모니터링되는 데이터가 변경될 때마다 후속 작업을 위해 콜백이 실행됩니다.

응용 시나리오:

1. 수치 계산을 수행해야 하고 다른 데이터에 의존해야 하는 경우 계산을 사용해야 합니다. 왜냐하면 계산의 캐시 기능을 사용하면 값을 얻을 때마다 재계산을 피할 수 있기 때문입니다.
2. 데이터가 변경될 때 비동기식 또는 비용이 많이 드는 작업을 수행해야 하는 경우 watch 옵션을 사용하면 비동기 작업(API 액세스)을 수행하고 작업 수행 빈도를 제한할 수 있습니다. 최종 결과가 나오기 전에 중간 상태를 설정합니다. 이는 계산된 속성이 수행할 수 없는 작업입니다.

3. 여러 요인이 하나의 디스플레이에 영향을 미치는 경우 계산을 사용하고, 한 요인의 변경이 여러 다른 요인 및 디스플레이에 영향을 미치는 경우 감시를 사용하세요.

1.8 계산과 방법의 차이점

1. 속성은 종속성을 기반으로 한 캐싱은 관련 종속성이 변경될 때만 재평가됩니다. 메서드의 경우 다시 렌더링이 발생하는 한
2. 메서드 호출은 항상 이 함수를 실행합니다

1.9. Virtual DOM, diff 알고리즘

1. DOM 요소를 직접 조작하지 않고, 페이지를 다시 렌더링하기 위해 데이터만 조작하자
2. Virtual DOM은 브라우저 성능 문제를 해결하도록 설계되었습니다
데이터에서 변경된 DOM 요소를 캐시하고 계산 후 비교를 통해 실제 DOM 트리에 매핑합니다
3. diff 알고리즘은 이전 가상 DOM과 새 가상 DOM을 비교합니다. 노드 유형이 동일하면 데이터를 비교하고 데이터를 수정합니다. 노드가 다르면 노드와 모든 하위 노드를 직접 삭제하고 각 노드에 고유 키가 설정되어 있으면 새 노드를 삽입할 수 있습니다. 변경해야 할 사항을 찾으십시오. 그렇지 않으면 한 곳을 수정하면 다른 곳도 변경되는 상황이 발생합니다. 예를 들어 A-B-C-D와 같이 새 노드 A-B-M-C-D를 삽입하려는 경우 C와 D가 실제로 변경됩니다. 그런데 키를 설정하고 나면 B C를 정확하게 찾아 삽입할 수 있습니다

1.10 Virtual DOM이 필요한 이유는 무엇인가요?

1. 크로스 플랫폼 장점이 있습니다
2. DOM 작동 속도는 느리지만 js는 효율적으로 실행됩니다. 효율성을 향상시키기 위해 JS 레이어에 DOM 비교 작업을 넣을 수 있습니다.
3. 렌더링 성능 향상

1.11. 필터

Vue에서 필터를 사용하여 데이터를 필터링(형식화)합니다. 그러나 데이터를 필터링(형식화)하고 변경합니다. 사용자(계산된 속성, 메소드 등)는 모두 데이터를 수정하여 데이터 형식의 출력 표시를 처리합니다.
사용 시나리오: 예를 들어 시간, 숫자 등을 처리해야 하는 표시 형식. . 일반적인 이벤트 수정자 및 해당 기능

1).stop: JavaScript의 event.stopPropagation()과 동일하며 이벤트 버블링을 방지합니다. 2).prevent : JavaScript의 event.preventDefault()와 동일하며 사전 설정된 동작의 실행을 방지합니다(이벤트를 취소할 수 있는 경우 이벤트 전파를 중단하지 않고 이벤트를 취소합니다).

3) .capture : 요소가 버블링되면 이 수정자가 있는 요소가 먼저 트리거됩니다. 수정자가 여러 개 있는 경우 외부에서 내부로 트리거됩니다. 예를 들어, p1이 p2에 중첩되고, p3이 p4에 중첩되고, p3이 p4에 중첩된 경우 실행 순서는 다음과 같습니다. p3=》p4=》p2=》p1
4).self : 자체 범위의 이벤트만 트리거합니다. 하위 요소는 포함하지 않습니다.

5) .once: 한 번만 트리거됩니다. .stop:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;
2).prevent :等同于 JavaScript 中的 event.preventDefault() ,防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);
3).capture :当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由外而内触发。如 p1中嵌套p2中嵌套p3.capture中嵌套p4,那么执行顺序为:p3=》p4=》p2=》p1
4).self :只会触发自己范围内的事件,不包含子元素;
5).once :只会触发一次。

1.13.v-show指令和v-if指令的区别是什么?

v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会控制这个 DOM 节点的存在与否。当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。

1.14.v-model 是如何实现的,语法糖实际是什么

作用在表单元素上v-model="message"等同于v-bind:value=“message” v-on:input="message=e v e n t . t a r g e t . v a l u e " 作 用 在 组 件 上 , 本 质 是 一 个 父 子 组 件 通 信 的 语 法 糖 ,通过prop和.emit实现, 等同于:value="message" @input=" $emit('input', $event.target.value)"

1.13. v-show 명령과 v-if 명령의 차이점은 무엇인가요?

v-show
는 요소의 표시 모드
만 제어하고

block과 none
사이에서 표시 속성을 전환하며, v-if는 이

DOM 노드의 존재를 제어합니다. 요소의 표시/숨기기를 자주 전환해야 하는 경우 v-show를 사용하면 성능 오버헤드가 더 많이 절약됩니다. 한 번만 표시하거나 숨기면 되는 경우 v-if를 사용하는 것이 더 합리적입니다.

1.14. v-model은 실제로 어떻게 구현되나요?

v-model="message"는 v-bind:value="message" v-on과 동일합니다. input ="message=e v e n t . t a r g e t . v a lu e "는 구성 요소에 작용합니다. 이는 본질적으로 prop 및 .emit를 통해 구현되는 상위-하위 구성 요소 통신을 위한 구문 설탕입니다. 이는 value="message" @input과 동일합니다. =" $emit( ​​'input', $event.target.value)"

1.15.데이터가 객체가 아닌 함수인 이유

JavaScript의 객체는 참조 유형 데이터입니다. 동일한 개체를 참조하십시오. 한 인스턴스가 이 개체에 대해 작동하는 한 다른 인스턴스의 데이터도 변경됩니다.
Vue에서는 컴포넌트를 더 많이 재사용하고 싶기 때문에 컴포넌트가 서로 간섭하지 않도록 각 컴포넌트에는 자체 데이터가 있어야 합니다.
따라서 컴포넌트의 데이터는 객체 형태로 작성할 수 없고 함수 형태로 작성해야 합니다. 데이터는 함수 반환 값의 형태로 정의되므로 구성 요소를 재사용할 때마다 새로운 데이터가 반환됩니다. 즉, 각 구성 요소는 고유한 개인 데이터 공간을 가지며 각각 고유한 데이터를 유지할 수 있습니다. 다른 구성 요소의 정상적인 작동을 방해합니다.

🎜🎜🎜1.16. Vue 템플릿에서 렌더링까지의 프로세스🎜🎜🎜🎜1. 템플릿을 ast(추상 구문 트리)로 변환하는 구문 분석 메서드를 호출합니다. 2. 정적 노드를 최적화합니다. 정적 노드인 경우 생성되는 DOM은 절대 변경되지 않으므로 런타임 템플릿 업데이트가 크게 최적화됩니다. 🎜 3. 렌더링 함수 생성. VNode는 Vue의 가상 DOM 노드이며, 여기에는 (레이블 이름, 하위 노드, 텍스트 등) 🎜🎜🎜🎜1.17 Vue 템플릿에서 렌더링까지의 과정이 있습니다. 🎜🎜 🎜템플릿을 ast(추상 구문 트리)로 변환하기 위해 구문 분석 메서드를 호출합니다. 🎜 정적 노드를 최적화합니다. 정적 노드인 경우 생성되는 DOM은 절대 변경되지 않으므로 런타임 템플릿 업데이트가 크게 최적화됩니다. 🎜 렌더링 함수 생성. VNode는 Vue의 가상 DOM 노드이며, 여기에는 (라벨 이름, 하위 노드, 텍스트 등)이 포함됩니다.

1.18.axios是什么

易用、简洁且高效的http库, 支持node端和浏览器端,支持Promise,支持拦截器等高级配置。

1.19.sass是什么?如何在vue中安装和使用?

sass是一种CSS预编译语言安装和使用步骤如下。

1.用npm安装加载程序( sass-loader、 css-loader等加载程序)。
2.在 webpack.config.js中配置sass加载程序。

1.20.Vue.js页面闪烁

Vue. js提供了一个v-cloak指令,该指令一直保持在元素上,直到关联实例结束编译。当和CSS一起使用时,这个指令可以隐藏未编译的标签,直到实例编译结束。用法如下

1.21.如何解决数据层级结构太深的问题

在开发业务时,经常会岀现异步获取数据的情况,有时数据层次比较深,如以下代码: , 可以使用vm.$set手动定义一层数据:

vm.$set("demo",a.b.c.d)

1.22.在 Vue. js开发环境下调用API接口,如何避免跨域

config/ index.js内对 proxyTable项配置代理。

1.23.批量异步更新策略

Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
换句话说,只要观察到数据变化,就会自动开启一个队列,并缓冲在同一个事件循环中发生的所以数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和 DOM 操作。

1.24.vue 的 nextTick 方法的实现原理

1.vue 用异步队列的方式来控制 DOM 更新和 nextTick 回调先后执行
2.microtask 因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕

1.25.Vue 组件 data 为什么必须是函数 ?

因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染。
所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。

1.26.v-if和v-for一起使用的弊端及解决办法

由于v-for的优先级比v-if高,所以导致每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降。

解决办法:

1.在v-for的外层或内层包裹一个元素来使用v-if
2.用computed处理

1.27.vue常用指令

1.v-model 多用于表单元素实现双向数据绑定(同angular中的ng-model)
2.v-bind 动态绑定 作用: 及时对页面的数据进行更改
3.v-on:click 给标签绑定函数,可以缩写为@,例如绑定一个点击函数 函数必须写在methods里面
4.v-for 格式: v-for=“字段名 in(of) 数组json” 循环数组或json(同angular中的ng-repeat)
5.v-show 显示内容 (同angular中的ng-show)
6.v-hide 隐藏内容(同angular中的ng-hide)
7.v-if 显示与隐藏 (dom元素的删除添加 同angular中的ng-if 默认值为false)
8.v-else-if 必须和v-if连用
9.v-else 必须和v-if连用 不能单独使用 否则报错 模板编译错误
10.v-text 解析文本
11.v-html 解析html标签
12.v-bind:class 三种绑定方法 1、对象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、数组型 ‘[{red:“isred”},{blue:“isblue”}]’
13.v-once 进入页面时 只渲染一次 不在进行渲染
14.v-cloak 防止闪烁
15.v-pre 把标签内部的元素原位输出

1.28. 组件传值方式有哪些

1.父传子:子组件通过props[‘xx’] 来接收父组件传递的属性 xx 的值
2.子传父:子组件通过 this.$emit(‘fnName’,value) 来传递,父组件通过接收 fnName 事件方法来接收回调
3.其他方式:通过创建一个bus,进行传值
4.使用Vuex

1.30.vue中 key 值的作用

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM

1.31.为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

Object.defineProperty 本身有一定的监控到数组下标变化的能力,但是在 Vue 中,从性能/体验的性价比考虑,尤大大就弃用了这个特性(Vue 为什么不能检测数组变动 )。为了解决这个问题,经过 vue 内部处理后可以使用以下几种方法来监听数组

push();
pop();
shift();
unshift();
splice();
sort();
reverse();

由于只针对了以上 7 种方法进行了 hack 处理,所以其他数组的属性也是检测不到的,还是具有一定的局限性。

Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x 里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择。
Proxy 可以劫持整个对象,并返回一个新的对象。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。

1.32.谈一谈 nextTick 的原理

JS 运行机制

JS 执行是单线程的,它是基于事件循环的。事件循环大致分为以下几个步骤:

所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
主线程不断重复上面的第三步。

[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)
主线程的执行过程就是一个 tick,而所有的异步结果都是通过 “任务队列” 来调度。 消息队列中存放的是一个个的任务(task)。 规范中规定 task 分为两大类,分别是 macro task 和 micro task,并且每个 macro task 结束后,都要清空所有的 micro task。

for (macroTask of macroTaskQueue) {
  // 1. Handle current MACRO-TASK
  handleMacroTask();

  // 2. Handle all MICRO-TASK
  for (microTask of microTaskQueue) {
    handleMicroTask(microTask);
  }}

在浏览器环境中 :

常见的 macro task 有 setTimeout、MessageChannel、postMessage、setImmediate

常见的 micro task 有 MutationObsever 和 Promise.then

异步更新队列

可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。
然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。
Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。
在 vue2.5 的源码中,macrotask 降级的方案依次是:setImmediate、MessageChannel、setTimeout

vue 的 nextTick 方法的实现原理:

vue 用异步队列的方式来控制 DOM 更新和 nextTick 回调先后执行
microtask 因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕
考虑兼容问题,vue 做了 microtask 向 macrotask 的降级方案

1.33.谈谈 Vue 事件机制,手写on,off,emit,once

Vue 事件机制 本质上就是 一个 发布-订阅 模式的实现。

class Vue {
  constructor() {
    //  事件通道调度中心
    this._events = Object.create(null);
  }
  $on(event, fn) {
    if (Array.isArray(event)) {
      event.map(item => {
        this.$on(item, fn);
      });
    } else {
      (this._events[event] || (this._events[event] = [])).push(fn);
    }
    return this;
  }
  $once(event, fn) {
    function on() {
      this.$off(event, on);
      fn.apply(this, arguments);
    }
    on.fn = fn;
    this.$on(event, on);
    return this;
  }
  $off(event, fn) {
    if (!arguments.length) {
      this._events = Object.create(null);
      return this;
    }
    if (Array.isArray(event)) {
      event.map(item => {
        this.$off(item, fn);
      });
      return this;
    }
    const cbs = this._events[event];
    if (!cbs) {
     return this;
    }
    if (!fn) {
      this._events[event] = null;
      return this;
    }
    let cb;
    let i = cbs.length;
    while (i--) {
      cb = cbs[i];
      if (cb === fn || cb.fn === fn) {
        cbs.splice(i, 1);
        break;
      }
    }
    return this;
  }
  $emit(event) {
    let cbs = this._events[event];
    if (cbs) {
      const args = [].slice.call(arguments, 1);
      cbs.map(item => {
        args ? item.apply(this, args) : item.call(this);
      });
    }
    return this;
  }}

1.34.vue-router有哪几种导航钩子?

三种:

一种是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。第二种:组件内的钩子;第三种:单独路由独享组件

1.35.vuex是什么?怎么使用?哪种功能场景使用它?

vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,…… export 。
场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

1.36. MVVM과 MVC의 차이점은 무엇인가요? 다른 프레임워크(jquery)와 어떻게 다른가요? 어떤 시나리오가 적용되나요?

MVVM과 MVC는 모두 디자인 아이디어입니다. 가장 중요한 점은 MVC의 컨트롤러가 ViewModel로 진화한다는 것입니다. MVVM은 주로 노드를 운영하는 대신 데이터를 통해 뷰 레이어를 표시하므로 많은 수의 DOM 작업 문제가 해결됩니다. MVC에서는 페이지 렌더링 성능이 향상되고 로딩 속도가 느려져 사용자 경험에 영향을 미칩니다. 데이터 작업이 많은 시나리오에서 주로 사용됩니다.
시나리오: 데이터 작업이 많은 시나리오, 더 편리함
[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

1.37 Vue.js

의 템플릿 컴파일에 대한 이해를 이야기해 보겠습니다. 즉, 먼저 AST 트리로 변환한 다음 렌더링 함수는 VNODE(Vue 회사의 가상 DOM 노드)를 반환합니다.
세부 단계:

먼저 템플릿을 다음을 통해 AST 구문 트리(추상 구문 트리는 소스 코드의 추상 구문 구조를 트리 표현한 트리 표현)로 컴파일합니다. Compilation은 컴파일러를 생성하는 데 사용되는 createCompiler의 반환 값입니다. 옵션 병합을 담당합니다.
그런 다음 렌더링 함수를 얻기 위해 AST가 생성됩니다(AST 구문 트리를 렌더링 함수 문자열로 변환하는 과정). 렌더링의 반환 값은 VNode입니다. Vue는 다음을 포함합니다. 라벨 이름, 하위 노드, 텍스트 등)

1.38.의 기능은 무엇이며 어떻게 사용하나요?

동적 구성 요소를 래핑할 때 비활성 구성 요소 인스턴스는 주로 구성 요소 상태를 유지하거나 재렌더링을 방지하는 데 사용됩니다.
사용: 단순 페이지
캐시:
不缓存:

1.39.vue和react区别

相同点:都鼓励组件化,都有’props’的概念,都有自己的构建工具,Reat与Vue只有框架的骨架,其他的功能如路由、状态管理等是框架分离的组件。

不同点:React:数据流单向,语法—JSX,在React中你需要使用setState()方法去更新状态。Vue:数据双向绑定,语法–HTML,state对象并不是必须的,数据由data属性在Vue对象中进行管理。适用于小型应用,但对于对于大型应用而言不太适合。

1.40.vue生命周期的理解?

参照大神文章:vue笔记 - 生命周期第二次学习与理解
[토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)

beforeCreate是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。

created在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。

beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。

mounted在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

destroyed 캐시하지 않음:

1.39 .vue와 React의 차이점

동일한 점: 둘 다 구성 요소화를 장려하고 둘 다 'props' 개념을 가지고 있으며 둘 다 자체 구성 도구를 가지고 있습니다. Reat와 Vue는 프레임워크의 뼈대와 라우팅과 같은 기타 기능만 가지고 있습니다. , 상태 관리 등은 프레임워크 별도의 구성 요소입니다.

차이점: React: 단방향 데이터 흐름, 구문 - JSX, React에서는 상태를 업데이트하려면 setState() 메서드를 사용해야 합니다. Vue: 양방향 데이터 바인딩, 구문 – HTML, 상태 객체가 필요하지 않으며 데이터는 Vue 객체에서 data 속성으로 관리됩니다. 소규모 애플리케이션에는 적합하지만 대규모 애플리케이션에는 적합하지 않습니다.



1.40. Vue 수명주기를 이해하시나요?

🎜훌륭한 기사를 참조하세요: vue Notes - 라이프 사이클에 대한 두 번째 학습 및 이해🎜여기에 이미지 설명 삽입🎜🎜beforeCreate은 new Vue() 이후에 트리거되는 첫 번째 후크입니다. 현재 단계에서는 데이터, 메서드, 계산 및 감시에 대한 데이터 및 메서드 모두 접근이 불가능합니다. 🎜🎜created는 인스턴스가 생성된 후에 발생합니다. 현재 단계에서 데이터 관찰이 완료되었습니다. 즉, 여기에서 데이터를 변경하면 업데이트된 기능이 트리거되지 않습니다. 일부 초기 데이터 수집은 가능합니다. 현재 단계에서는 Dom과 상호 작용할 수 없습니다. 필요한 경우 vm.$nextTick을 통해 Dom에 액세스할 수 있습니다. 🎜🎜beforeMount는 마운트 전에 발생하며 그 전에 템플릿 템플릿을 가져오고 렌더링 기능으로 컴파일했습니다. 현재 단계에서는 가상 Dom이 생성되어 렌더링을 시작하려고 합니다. 이때 데이터를 변경할 수도 있으며 업데이트가 트리거되지 않습니다. 🎜🎜mounted는 마운팅이 완료된 후 발생합니다. 현재 단계에서는 실제 Dom이 마운트되고 데이터가 양방향으로 바인딩되며 Dom 노드에 액세스할 수 있으며 $refs 속성이 사용됩니다. 돔을 운영하게 됩니다. 🎜🎜beforeUpdate는 업데이트 이전에 발생합니다. 즉, 재렌더링 전에 반응형 데이터가 업데이트되고 가상 돔이 트리거되어 재렌더링을 발생시키지 않고 현재 단계의 데이터를 변경할 수 있습니다. 🎜🎜updated는 업데이트가 완료된 후 발생하며 현재 단계 구성 요소 Dom이 업데이트되었습니다. 이 시간 동안 데이터를 변경하지 않도록 주의하세요. 이로 인해 업데이트가 무한 루프될 수 있습니다. 🎜🎜beforeDestroy는 인스턴스가 소멸되기 전에 발생합니다. 현재 단계에서 인스턴스를 완전히 사용할 수 있습니다. 타이머를 지우는 등의 후처리 마무리 작업을 수행할 수 있습니다. 🎜🎜destroyed는 인스턴스가 소멸된 후에 발생합니다. 이때는 DOM 쉘만 남습니다. 구성 요소가 디스어셈블되고, 데이터 바인딩이 제거되고, 리스너가 제거되고, 모든 하위 인스턴스가 삭제되었습니다. 🎜🎜🎜1.41 각각 Vue2.x 및 Vue3.x 렌더러의 diff 알고리즘에 대해 이야기해 보겠습니다.🎜🎜🎜간단히 말하면 diff 알고리즘은 다음과 같은 프로세스를 갖습니다🎜🎜🎜1. 피어를 비교한 다음 하위 노드를 비교합니다🎜 2. 판단 먼저 한 쪽에는 자식 노드가 있고 다른 쪽에는 없는 상황(새 자식에 자식 노드가 없으면 이전 자식 노드를 제거) 🎜 3. 두 자식 모두 자식 노드가 있는 상황을 비교합니다(core diff) 🎜 3. 재귀적으로 하위 노드 비교 🎜

두 트리 사이의 일반 Diff의 시간 복잡도는 O(n^3)이지만 실제 상황에서는 DOM을 여러 레벨로 이동하는 경우가 거의 없으므로 Vue는 O(n^3)에서 Diff를 최적화합니다. ) -> O(n), 이전 자식과 새 자식 노드가 여러 자식 노드인 경우에만 동일 수준 비교에 핵심 Diff 알고리즘을 사용해야 합니다. O(n^3),但实际情况下我们很少会进行跨层级的移动DOM,所以Vue将Diff进行了优化,从O(n^3) -> O(n),只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。

Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。

Vue3.x借鉴了
ivi算法和 inferno算法

在创建VNode时就确定其类型,以及在 mount/patch 的过程中采用位运算来判断一个VNode的类型,在这个基础之上再配合核心的Diff算法,使得性能上较Vue2.x有了提升。(实际的实现可以结合Vue3.x源码看。)

该算法中还运用了动态规划的思想求解最长递归子序列。

1.42.你都做过哪些Vue的性能优化?

编码阶段

1.尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的2.watcher
3.v-if和v-for不能连用
4.如果需要使用v-for给每项元素绑定事件时使用事件代理
5.SPA 页面采用keep-alive缓存组件
6.在更多的情况下,使用v-if替代v-show
7.key保证唯一
8.使用路由懒加载、异步组件
9.防抖、节流
10.第三方模块按需导入
11.长列表滚动到可视区域动态加载
12.图片懒加载

SEO优化

1.预渲染
2.服务端渲染SSR

打包优化

1.压缩代码
2.Tree Shaking/Scope Hoisting
3.使用cdn加载第三方模块
4.多线程打包happypack
5.splitChunks抽离公共文件
6.sourceMap优化

用户体验

1.骨架屏
2.PWA

还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。

1.43.hash路由和history路由实现原理说一下

location.hash的值实际就是URL中#后面的东西。

history实际采用了HTML5中提供的API来实现,主要有history.pushState()history.replaceState()

1.44.SPA 单页面的理解,它的优缺点分别是什么

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS
一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转
取而代之的是利用路由机制实现 HTML 内容的变换, UI 与用户的交互,避免页面的重新加载
优点:

1、用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
2、基于上面一点,SPA 相对对服务器压力小
3、前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理

缺点:

1、初次加载耗时多:为实现单页 Web 应用功能及显示效果,
需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载
2、前进后退路由管理:由于单页应用在一个页面中显示所有的内容,
所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理
3、SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势

1.45.vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?

第一步:在components目录新建你的组件文件(indexPage.vue),script一定要export default {}
第二步:在需要用的页面(组件)中导入:import indexPage from ‘@/components/indexPage.vue’
第三步:注入到vue的子组件的components属性上面,components:{indexPage}
第四步:在template视图view中使用,
例如有indexPage命名,使用的时候则index-page

1.46.vue如何实现按需加载配合webpack设置

webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。
不进行页面按需加载引入方式:import home from '../../common/home.vue'
进行页面按需加载的引入方式:const home = r => require.ensure( [], () => r (require('../../common/home.vue')))

Vue2의 핵심 Diff 알고리즘은 이중 끝 비교 알고리즘을 채택함과 동시에 이전 자식과 새 자식의 양쪽 끝에서 비교를 시작하고 키 값을 사용하여 재사용 가능한 노드를 찾은 다음 관련 작업을 수행합니다. . React의 Diff 알고리즘과 비교하여 동일한 상황에서 모바일 노드 수를 줄이고 불필요한 성능 손실을 줄일 수 있으며 더 우아합니다. 🎜🎜Vue3.x는 ivi 알고리즘과 inferno 알고리즘을 기반으로 합니다.🎜🎜VNode 유형은 생성 시 결정되며, 이를 기반으로 마운트/패치 프로세스 중에 VNode 유형을 결정하는 비트 연산이 사용됩니다. 핵심 Diff 알고리즘으로 인해 Vue2.x에 비해 성능이 향상되었습니다. (실제 구현은 Vue3.x 소스 코드와 함께 볼 수 있습니다.) 🎜🎜이 알고리즘도 동적 프로그래밍 아이디어를 사용하여 가장 긴 재귀 부분 수열을 해결합니다. 🎜

1.42. Vue에 대해 어떤 성능 최적화를 수행했나요?

🎜인코딩 단계🎜
🎜1. 데이터의 데이터를 줄이면 getter 및 setter와 해당 2.watcher
3.v-가 추가됩니다. if와 v-for를 함께 사용할 수 없습니다.
4. v-for를 사용하여 각 요소에 이벤트를 바인딩해야 하는 경우 이벤트 프록시를 사용하세요.
5. SPA 페이지는 연결 유지 캐시 구성 요소를 사용합니다.
6. v-show 대신 v-if를 사용하는 경우가 더 많습니다
7. 키의 고유성이 보장됩니다
8. 라우팅 지연 로딩, 비동기 구성요소 사용
9. 흔들림 방지, 제한
/> 10. 요청 시 타사 모듈을 가져옵니다.
11. 긴 목록이 표시 영역으로 스크롤되고 동적으로 로드됩니다.
12. 이미지의 지연 로딩🎜🎜 🎜SEO 최적화🎜
🎜1. 사전 렌더링
2. 서버 측 렌더링 SSR🎜🎜🎜패키징 최적화🎜
🎜1. 트리 쉐이킹/스코프 호이스팅
3. cdn을 사용하여 타사 모듈 로드
4 .멀티 스레드 패키징 happypack
5.splitChunks 공개 파일 추출
6.sourceMap 최적화🎜🎜🎜사용자 경험🎜🎜1.스켈레톤 화면
2.PWA🎜🎜🎜Alright 캐시(클라이언트 캐시, 서버 캐시) 최적화 사용, 서버에서 gzip 압축 활성화 등 🎜

1.43. 해시 라우팅 및 히스토리 라우팅의 구현 원칙에 대해 이야기해 보겠습니다.

🎜 location.hash의 값은 실제로 # 이후의 값입니다. URL. 🎜🎜history는 실제로 HTML5에서 제공하는 API, 주로 history.pushState()history.replaceState()를 사용하여 구현됩니다. 🎜

1.44. SPA 단일 페이지의 이해, 장점과 단점

🎜SPA(단일 페이지 애플리케이션)는 웹 페이지가 초기화될 때 해당 HTML 및 JavaScript만 로드합니다. . 및 CSS
페이지가 로드되면 SPA는 사용자 작업으로 인해 페이지를 다시 로드하거나 점프하지 않습니다.
대신 라우팅 메커니즘을 사용하여 HTML 콘텐츠 변환 및 UI와 사용자 간의 상호 작용을 실현합니다. 페이지 다시 로드 방지
장점: 🎜
🎜1. 콘텐츠 변경 시 전체 페이지를 다시 로드할 필요가 없으므로 불필요한 점프 및 반복 렌더링이 필요하지 않습니다.
2. 기반 위와 같은 점에서 SPA는 서버에 부담을 덜 줍니다.
3. 프런트엔드와 백엔드 책임이 분리되어 있고, 프런트엔드가 대화형 로직을 수행하고 백엔드가 담당하는 구조가 명확합니다. 단점: 🎜
🎜1. 초기 로딩 시간이 오래 걸립니다. : 단일 페이지 웹 애플리케이션의 기능 및 표시 효과를 구현하려면
JavaScript와 CSS를 균일하게 로드해야 합니다. 2. 순방향 및 역방향 라우팅 관리 : 단일 페이지 애플리케이션이므로 모든 콘텐츠가 한 페이지에 표시되므로
브라우저의 순방향 및 역방향 기능 모든 페이지 전환에는 자체 스택 관리 구축이 필요합니다.
3. SEO가 어렵습니다. 모든 콘텐츠가 한 페이지에 있기 때문에 디스플레이를 동적으로 교체하므로 SEO에는 자연스러운 약점이 있습니다🎜🎜1.45. vue.cli에서 사용자 정의 구성요소를 사용하는 방법은 무엇입니까? 어떤 문제가 발생했나요?
🎜1단계: 구성 요소 디렉터리에 새 구성 요소 파일(indexPage.vue)을 생성합니다. 스크립트는 export default{}
여야 합니다. 단계: 필요한 페이지(구성 요소)로 가져오기: '@/comComponents/indexPage.vue'에서 indexPage 가져오기
3단계: 하위 구성 요소의 구성 요소 속성에 삽입 vue ,comComponents:{indexPage}
4단계: 템플릿 보기에서 사용합니다.
예를 들어 indexPage라는 이름을 사용하면 index- page🎜🎜

1.46. vue가 웹팩 설정으로 주문형 로딩을 구현하는 방법

🎜webpack은 require.ensure()를 제공합니다. - 수요 로딩. 과거에는 import를 통해 경로가 도입되었지만 이제는 const 정의를 통해 도입됩니다.
주문형 페이지 로딩이 없는 도입 방법: '../../common/home.vue'에서 home 가져오기
주문형 페이지 도입 방법 로딩: const home => require.ensure( [], () => r (require('../../common/home.vue')))🎜

二、组件 Component

2.1.vue中如何编写可复用的组件 (编写组件的原则)

以组件功能命名
只负责ui的展示和交互动画,不要在组件里与服务器打交道(获取异步数据等)
可复用组件不会因组件使用的位置、场景而变化。尽量减少对外部条件的依赖。

2.2.如何让CSS只在当前组件中起作用?

在每一个Vue.js组件中都可以定义各自的CSS、 JavaScript代码。如果希望组件内写的CSS只对当前组件起作用,只需要在Style标签添加Scoped属性即可

2.3.keep-alive是什么?

如果需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。

两个重要属性,include 缓存组件名称,exclude 不需要缓存的组件名称。

2.4.如何在 Vue. js动态插入图片

对“src”属性插值将导致404请求错误。应使用 v-bind:src (简写:src)格式代替。

2.5.父子组件的生命周期顺序(可参照上方图解)

加载渲染过程:
beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子组件更新过程:父beforeUpdate->子beforeUpdate->子updated->父updated
父组件更新过程:父beforeUpdate->父updated
销毁过程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

三、Vuex

3.1.vuex的核心概念

1.state => 基本数据
2.getters => 从基本数据派生的数据
3.mutations => 修改数据,同步
4.actions => 修改数据,异步 (Action 提交的是 mutation,而不是直接变更状态)
5.modules => 模块化Vuex

3.2.vuex是什么?怎么使用?哪种功能场景使用它?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理器,采用集中式存储管理应用的所有组件的状态,主要是为了多页面、多组件之间的通信。
Vuex有5个重要的属性,分别是 State、Getter、Mutation、Action、Module,由 view 层发起一个 Action 给 Mutation,在 Mutation 中修改状态,返回新的状态,通过 Getter暴露给 view层的组件或者页面,页面监测到状态改变于是更新页面。如果你的项目很简单,最好不要使用 Vuex,对于大型项目,Vuex 能够更好的帮助我们管理组件外部的状态,一般可以运用在购物车、登录状态、播放等场景中。

3.3.多个组件之间如何拆分各自的state,每块小的组件有自己的状态,它们之间还有一些公共的状态需要维护,如何思考这块

1.公共的数据部分可以提升至和他们最近的父组件,由父组件派发
2.公共数据可以放到vuex中统一管理,各组件分别获取

3.4.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

1.如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。

2.如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便

3.5.Vuex中如何异步修改状态

actions与mutations作用类似,都是可以对状态进行修改。不同的是actions是异步操作的。

actions是可以调用Mutations里的方法的。

const actions={
	addActions(context){
		context.commit('add',10);//调用mutations中的方法
		setTimeout(()=>{context.commit('reduce')},5000)
	//	setTimeOut(()=>{context.commit('reduce')},3000);
		console.log('我比reduce提前执行');
	},
	
	reduceActions({commit}){
		commit('reduce');
	}}

3.6.Vuex中actions和mutations的区别

Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }})

Action Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }})

3.7.怎么在组件中批量使用Vuex的state状态?

使用mapState辅助函数, 利用对象展开运算符将state混入computed对象中

import {mapState} from 'vuex' export default{ computed:{ ...mapState(['price','number']) } }

3.8.Vuex中状态是对象时,使用时要注意什么?

对象是引用类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许,所以先用深度克隆复制对象,再修改。

四、Router

4.1.vue-router 路由模式有几种

1.Hash: 使用 URL 的 hash 值来作为路由。支持所有浏览器。 带#。如:http://localhost:8080/#/pageA。改变hash,浏览器本身不会有任何请求服务器动作的,但是页面状态和url已经关联起来了。
2.History: 以来 HTML5 History API 和服务器配置。参考官网中 HTML5 History 模式,不带#, 如:http://localhost:8080/ 正常的而路径,并没有#。基于HTML5的 pushState、replaceState实现
3.Abstract: 支持所有 javascript 运行模式。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

4.2.vue-router如何定义嵌套路由

通过children 数组:

const router = new VueRouter({
  routes: [
    {
      path: "/parentPage",
      component: testPage,
      children: [
        {
          path: "/childrenA",
          component: childrenComponentA,
        },
        {
          path: "/childrenB",
          component: childrenComponentB,
        },
      ],
    },
    {
      // 其他和parentPage平级的路由
    },
  ],});

4.3.vue-router有哪几种导航钩子?

1.全局导航钩子:router.beforeEach(to,from,next)
2.组件内的钩子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)
3.单独路由独享组件 beforeEnter: (to, from, next)

参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种

4.4. $ route和$ router的区别

1、$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

1.$route.path 字符串,对应当前路由的路径,总是解析为绝对路径如"/foo/bar"。
2. $route.params 一个 key/value 对象,包含了 动态片段 和 全匹配片段, 如果没有路由参数,就是一个空对象。
3. $route.query 一个 key/value 对象,表示 URL 查询参数。 例如,对于路径 /foo?user=1,则有$route.query.user == 1, 如果没有查询参数,则是个空对象
4. $route.hash 当前路由的hash值 (不带#) ,如果没有 hash 值,则为空字符串
5. $route.fullPath 完成解析后的 URL,包含查询参数和hash的完整路径。
6. $route.matched 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
7. $route.name 当前路径名字
8. $ route.meta 路由元信息

2、$router是“路由实例”对象包括了路由的跳转方法,钩子函数等

实例方法:

1)、push

1.字符串this.$router.push('home')
2. 对象this.$router.push({path:'home'})
3. 命名的路由this.$router.push({name:'user',params:{userId:123}})
4.带查询参数,变成 /register?plan=123this.$router.push({path:'register',query:{plan:'123'}})
push方法其实和是等同的。
注意:push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。

2)、go
页面路由跳转
前进或者后退this.$router.go(-1) // 后退

3)、replace
push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,
不会向 history 栈添加一个新的记录

4.5.路由之间跳转的方式

1.声明式(标签跳转)
2.编程式( js跳转)

4.6.active-class是哪个组件的属性

vue-router 模块 的router-link组件

4.7.vue-router实现路由懒加载(动态加载路由)

把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件即为路由的懒加载,可以加快项目的加载速度,提高效率

const router = new VueRouter({
  routes: [
    {
      path: '/home',
      name: 'Home',      
      component:() = import('../views/home')
	}
  ]})

4.8.怎么定义vue-router的动态路由以及如何获取传过来的动态参数?

在router目录下的index.js文件中,对path属性加上/:id
使用router对象的params id

面试官:我难道问不倒这小子了?(面试官持续懵逼中) 对大家有帮助的话三连呀~ 持续更新

【추천 관련 동영상 튜토리얼: vuejs 입문 튜토리얼, 웹 프론트엔드 시작하기

위 내용은 [토혈] Vue.js 면접 질문 요약 및 답변 분석 (오셔서 수집하세요)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제