The most complete Vue interview questions + detailed answers

preface

This article sorted out the frequent occurrence of Vue related interview questions and with detailed answer difficulty is divided into three types of simple medium difficulty we can first look at the answer to test their own Vue level ha if interested in the principle of students welcome to view small series of handwritten Vue source articles If you have different views on the answer, welcome to add the discussion in the comment area. Finally, welcome to click the link to join the shark brother’s front group push discussion technology to touch fish for help.

If you think this article is helpful, please remember to like three lian Oh, thank you very much!

simple

1 The difference between MVC and MVVM

MVC

MVC full name is Model View Controller, is the abbreviation of Model – View – Controller, a Model of software design

  • Model: Is the part of the application that handles the application’s data logic. Typically, model objects are responsible for accessing data in a database
  • View: Is the part of the application that handles the display of data. Views are usually created from model data
  • Controller: Is the part of the application that handles user interaction. Typically the controller is responsible for reading data from the view, controlling user input, and sending data to the model

The idea of MVC is that the Controller is responsible for displaying the Model’s data in the View. In other words, the Controller assigns the Model’s data to the View.

MVVM

The VM class is added to MVVM

  • The ViewModel layer: it does two things to achieve bidirectional binding of data. One is to convert the [model] into the [view], which is to convert the data passed by the back end into the page to be seen. This is done by data binding. The second is to transform [view] into [model], that is, to see the page into back-end data. This is done by DOM event listening.

The biggest difference between MVVM and MVC is: It realizes automatic synchronization between View and Model, that is, when the Model property changes, we no longer need to manually manipulate Dom elements to change the display of View, but after changing the property, the corresponding View layer display will automatically change (corresponding to the Vue data-driven idea).

Overall, MVVM is much simpler than MVC. It not only simplifies business and interface dependencies, but also solves the problem of frequent data updates, eliminating the need to manipulate DOM elements with selectors. Because in MVVM, the View is unaware of the Existence of the Model, and the Model and ViewModel cannot observe the View, this low-coupling pattern improves code reusability

Note: Vue does not follow MVVM’s ideas exactly as the official website explains

So why is it official to say that Vue doesn’t fully follow MVVM?

  • The strict MVVM requirement that the View not communicate directly with the Model is violated by the $refs attribute, which allows the Model to manipulate the View directly, so Vue is not fully compliant with MVVM.

2 Why is data a function

The data in the component is written as a function, and the data is defined as the return value of the function. In this way, each time the component is reused, a new data is returned, similar to creating a private data space for each component instance and letting each component instance maintain its own data. However, simply writing in object form makes all component instances share a copy of data, which will cause a result that all changes will change

3 What are the communication modes of Vue components

  1. The props and EMIT parent components pass data to the child components via prop, the child components pass data to the parent components via PROP, the child components pass data to the parent components via prop, and the emit parent components pass data to the child components via prop, The child component passes data to the parent component by emitting an event

  2. The parent, the parent, the parent and children takes the current components of the parent component and the current component child components

  3. Attrs and listeners A->B->C Vue 2.4 starts with attrs and attrs and attrs and Listeners to address this problem

  4. Variables are provided by provide in the parent component and injected by inject in the child component. (Officially not recommended for use in real business, but commonly used when writing component libraries)

  5. $refs gets the component instance

  6. The envetBus sibling can use the event bus approach for data transfer in this case

  7. Vuex status management

4 What are the lifecycle methods of Vue

BeforeCreate is called after instance initialization and before data Observer and Event/Watcher event configuration. In the current phase, data and methods on Data, methods, computed, and Watch cannot be accessed

Called after the created instance has been created. In this step, the instance completes the configuration of data Observer, property and method operations, and Watch/Event event callbacks. There’s no EL, so if you really want to interact with the Dom, you can use vm.el, if you really want to interact with the Dom, you can use vm.el, if you really want to interact with the Dom, you can access the Dom through vm.nextTick

BeforeMount is called before the mount begins: the associated render function is called for the first time.

Mounted Occurs after the Dom is mounted. In this stage, the REAL Dom is mounted, data is bound, and Dom nodes can be accessed

BeforeUpdate is called when data is updated and occurs before the virtual DOM is re-rendered and patched. You can further change the state in this hook without triggering additional rerendering

Updated occurs after the update is complete, and the component Dom is updated in the current phase. Care should be taken to avoid changing the data during this time, as this may result in an infinite loop of updates, and the hook is not called during server-side rendering.

BeforeDestroy Called before instance destruction. At this step, the instance is still fully available. This is where we can clean up the mess, like clearing timers.

Called after the Destroyed Vue instance is destroyed. When called, everything indicated by the Vue instance is unbound, all event listeners are removed, and all subinstances are destroyed. This hook is not called during server-side rendering.

Activated keep-alive Is used when the component is activated

Deactivated keep-alive Is exclusive and is invoked when a component is destroyed

At what stage is the asynchronous request initiated?

Asynchronous requests can be made in hook functions created, beforeMount, and Mounted because in these three hook functions data is already created and can be assigned to the data returned by the server.

If an asynchronous request does not need to rely on Dom, it is recommended to call an asynchronous request in a Created hook function, because calling an asynchronous request in a Created hook function has the following advantages:

  • The server data can be obtained faster, reducing page loading time.
  • SSR does not support beforeMount and Mounted hook functions, so creating helps consistency.

5 Differences between V-IF and V-show

V-if is converted to a ternary expression during compilation, and the node is not rendered if the condition is not met.

V-show will be compiled into instructions, control style will hide the corresponding node if the condition is not met (display:none)

Usage scenarios

V-if is suitable for scenarios where conditions are rarely changed at run time and do not need to be switched frequently

V-show is suitable for scenarios that require very frequent switching of conditions

Opacity :none, opacity: hidden, and opacity:0

Talk about vUE built-in instructions

7 How to understand one-way data flow of Vue

Data is always passed from the parent to the child. The child has no right to modify the data passed by the parent, but can only request the parent to modify the original data. This prevents accidental changes in the state of the parent component from the child, which can make the data flow of your application difficult to understand.

Note: the development environment will warn against using a v-model to bind prop passed by the parent component directly to the child component

If you really want to change the prop value of the parent component, you can define a variable in data and initialize it with the prop value and then use $emit to notify the parent component to modify it

8 Differences between computed and Watch and application scenarios

Computed is a computed property that relies on other properties to compute values, and computed values are cached and return only when computed values change. It can set getters and setters.

Watch listens for a change in the value and executes a callback, in which logical operations can be performed.

Computed attributes are usually used in template rendering, where a value is computed depending on other responsive objects or even computed attributes; The listening attribute is suitable for observing changes in a value to complete a complex piece of business logic

The principle of calculating properties explains the portal

The principle of listening properties explains the portal

9 Why not use v-IF and V-for together

Do not use v-for and V-if in the same tag, because v-for is resolved before V-if. If you need to use it at the same time, you can consider writing it in the way of calculating attributes.

medium

Principle of Vue2.0 responsive data

The whole idea is data hijacking + observer mode

Attributes are internally hijacked using object.defineProperty (only existing attributes are hijacked) via the defineReactive method, while arrays are done by overriding array methods. When a page uses a corresponding attribute, each attribute has its own DEP attribute, which stores the watcher it depends on (dependent collection). When the attribute changes, the corresponding Watcher will be notified to update (distributed update).

The relevant codes are as follows

Class Observer {// Constructor (value) {this.walk(value); } walk(data) {let keys = object.keys (data); for (let i = 0; i < keys.length; i++) { let key = keys[i]; let value = data[key]; defineReactive(data, key, value); Function defineReactive(data, key, value) {observe(value); function defineReactive(data, key, value) {observe(value); // Recursion key // -- if the value is still an object, the odefineReactive loop continues until the value is not an object. Object.defineproperty (data, key, {get() {console.log(" get value "); Return value; return value; }, set(newValue) { if (newValue === value) return; Console. log(" Set value "); Value = newValue; }}); } export function observe (value) {/ / and if the Object or array of attributes to hijack the if (Object. The prototype. ToString. Call (value) = = = "[Object Object]" || Array.isArray(value) ) { return new Observer(value); }} Copy the codeCopy the code

The principle of responsive data explains the portal

11 How does Vue detect array changes

Array considering performance reasons not defineProperty an array of each item to intercept, choosing instead to seven kinds of array (push, shift, pop, splice, unshift, sort, reverse) method rewrite (AOP sliced thought)

So changing the index and length of an array in Vue is unmonitored. You need to modify the array through the above 7 variation methods to trigger the watcher of the array to update

The relevant codes are as follows

// SRC /obserber/array.js // arrayProto = array.prototype; Export const arrayMethods = object.create (arrayProto); // arrayProto (arrayProto); let methodsToPatch = [ "push", "pop", "shift", "unshift", "splice", "reverse", "sort", ]; methodsToPatch.forEach((method) => { arrayMethods[method] = function (... Const result = arrayProto[method]. Apply (this, args); // this represents the data itself. For example, if the data is {a:[1,2,3]} then we use a.paush (4) this is a. Ob is a.__ob__ Const ob = this.__ob__; const ob = this.__ob__; // Let inserted; switch (method) { case "push": case "unshift": inserted = args; break; case "splice": inserted = args.slice(2); default: break; } // Call the observeArray of the Observer instance to observe each item in the array if (inserted) ob.observearray (inserted); Return result; return result; return result; }; }); Copy the codeCopy the code

The principle of array observation explains the portal

Have you used Vue3.0

  • Vue3.x uses Proxy instead of Object. DefineProperty in vue2. x

  • Vue3.x Using Composition API Setup is a new option for vue3.x, which is the entry point for using Composition API within components.

  • Template syntax changes slot Named slot Syntax custom instruction V-model upgrade

  • Suspense supports fragments (multiple root nodes) and Protal (rendering components in other parts of the DOM) components, which are handled for specific scenarios. Based on Treeshaking optimization, more built-in features are provided.

New Vue3.0 features and use of the experience summary portal

13 The responsivity principle difference between Vue3.0 and 2.0

Vue3. X uses Proxy instead of Object.defineProperty. Because proxies can listen directly for changes in objects and arrays, there are as many as 13 interception methods.

The relevant codes are as follows

import { mutableHandlers } from "./baseHandlers"; Import {isObject} from "./util"; Function reactive(target) {return createReactiveObject(target, mutableHandlers); } function createReactiveObject(target, baseHandler) { if (! isObject(target)) { return target; } const observed = new Proxy(target, baseHandler); return observed; } const get = createGetter(); const set = createSetter(); Function createGetter() {return function get(target, key, receiver) {// Const res = reflect.get (target, receiver) key, receiver); Console. log(" property fetch ", key); If (isObject(res)) {return reactive(res) if (isObject(res)) {return reactive(res); } return res; }; } function createSetter() { return function set(target, key, value, receiver) { const oldValue = target[key]; const hadKey = hasOwn(target, key); const result = Reflect.set(target, key, value, receiver); if (! HadKey) {console.log(" attributes added ", key, value); } else if (hasChanged(value, oldValue)) {console.log(key, value); } return result; }; } export const mutableHandlers = {get, call this method set when fetching attributes, call this method when modifying attributes}; Copy the codeCopy the code

Vue parent component lifecycle hook function execution sequence

  • Loading the rendering process

Parent beforeCreate-> Parent created-> parent beforeMount-> child beforeCreate-> child created-> child beforeMount-> Child Mounted -> parent Mounted

  • Child component update process

Parent beforeUpdate-> Child beforeUpdate-> Child updated-> Parent updated

  • Parent component update process

Father father beforeUpdate – > updated

  • Destruction of the process

Parent beforeDestroy-> Child beforeDestroy-> Child destroyed-> Parent destroyed

What is the virtual DOM and what are its advantages and disadvantages

Because DOM manipulation in a browser is expensive. Frequent DOM manipulation can cause performance problems. This is where the virtual Dom comes in. Vue2’s Virtual DOM is based on the open source library SNabbDOM. The essence of Virtual DOM is to use a native JS object to describe a DOM node, which is a layer of abstraction of the real DOM.

Advantages:

  1. Lower performance: The framework’s virtual DOM needs to accommodate any operations that the upper-level API may produce, and some of its DOM operations must be implemented in a universal way, so its performance is not optimal; But performance is much better than rough DOM manipulation, so the framework’s virtual DOM can at least guarantee decent performance without having to manually optimize it.

  2. No need to manually manipulate the DOM: We no longer need to manually manipulate the DOM, just need to write the code logic of the View-Model, the framework will help us update the View in a predictable way according to the virtual DOM and data two-way binding, greatly improving our development efficiency;

  3. Cross-platform: The virtual DOM is essentially a JavaScript object, and the DOM is platform-dependent. In contrast, the virtual DOM can be more easily cross-platform, such as server rendering, WEEX development, and so on.

Disadvantages:

  1. Extreme optimization cannot be carried out: Although reasonable optimization of virtual DOM + is sufficient to meet the performance requirements of most applications, targeted extreme optimization cannot be carried out in some applications with extremely high performance requirements.

  2. When rendering a large number of DOM for the first time, it is slower than innerHTML insertion due to the extra layer of virtual DOM computation.

16 v – model principle

V-models are just syntactic sugar

Internally, the V-Model uses different properties for different input elements and throws different events:

  • Text and Textarea elements use value property and input events;
  • Checkbox and radio use checked Property and change events;
  • The SELECT field takes value as prop and change as an event.

Note: For languages that require input methods (such as Chinese, Japanese, Korean, etc.), you will find that the V-Model is not updated during the input method composition process.

On a regular label

<input v-bind:value=" STH "V-on :input=" STH = $event.target.value" /> Copy the codeCopy the code

On the components

<currency-input v-model="price"></currentcy-input> <! <currency input :value="price" @input="price = arguments[0]"></currency input> --> <! Vue.component('currency-input', {template: ` <span> <input ref="input" :value="value" @input="$emit('input', $event.target.value)" > </span> `, props: ['value'],}) copies the codeCopy the code

17 V-for why add key

If keys are not used, Vue uses an algorithm that minimizes dynamic elements and tries to modify/reuse the same type of elements in place whenever possible. The key is a unique token for a Vnode in a Vue. With this key, our diff operation can be more accurate and faster

The sameNode function a. keey === B. Keey can be compared with the sameNode function a. keey === B. So it’s more accurate.

Faster: Using the uniqueness of keys to generate map objects to obtain corresponding nodes, faster than traversal

The relevant codes are as follows

Function isSameVnode(oldVnode, newVnode) { return oldVnode.tag === newVnode.tag && oldVnode.key === newVnode.key; } function makeIndexByKey(children) {makeIndexByKey(children) {makeIndexByKey(children) {makeIndexByKey(children) {makeIndexByKey(children) map = {}; children.forEach((item, index) => { map[item.key] = index; }); return map; } let map = makeIndexByKey(oldCh); Copy the codeCopy the code

The diff algorithm solves the portal

18 Principle of Vue event binding

Native event bindings are bound to real elements via addEventListener, and component event bindings are implemented via Vue’s custom $on. If you want to use native events on a component, you need to add a. Native modifier, which is equivalent to adding native events to the parent component by treating the child component as a normal HTML tag.

On, ON, ON and EMIT are based on the publish-subscribe model. They maintain an event center. When on, the events are stored in the event center by name and called as subscribers, and then emit the corresponding events to execute the corresponding listeners in the event center

Handwritten publish subscribe principle portal

19 Vue-router What are the vue-router hook functions and in what order are they executed

The execution flow of the route hook, the hook function types are: global guard, route guard, component guard

Complete navigation parsing flow:

  1. Navigation is triggered.
  2. Call the beforeRouteLeave guard in the deactivated component.
  3. Call the global beforeEach guard.
  4. Call the beforeRouteUpdate guard (2.2+) in the reused component.
  5. Call beforeEnter in routing configuration.
  6. Parse the asynchronous routing component.
  7. Call beforeRouteEnter in the activated component.
  8. Call the global beforeResolve guard (2.5+).
  9. Navigation confirmed.
  10. Call the global afterEach hook.
  11. Trigger a DOM update.
  12. Call the callback passed to Next in the beforeRouteEnter guard, and the created component instance is passed in as an argument to the callback.

20 What is a vue-router dynamic route? What is the problem

We often need to map all the routes that a pattern matches to the same component. For example, we have a User component that is used to render for all users with different ids. We can use dynamic segments on vue-router routes to achieve this effect:

const User = { template: "<div>User</div>", }; Const router = new VueRouter({routes: [// Dynamic route parameter starts with a colon {path: "/user/:id", Component: user},],}); Copy the codeCopy the code

Question: What should I do if route parameters fail due to vue-Router component reuse?

Solutions:

1. Use watch to listen to route parameters and send a request

"$route": function(){this.getData(this.$route.params.xxx); }} Copy the codeCopy the code

2. Use :key to prevent “reuse”

<router-view :key="$route.fullPath" /> Copy the codeCopy the code

21. Talk about my personal understanding of VUex

Vuex is a global status management system for VUE. It is used for data sharing and data caching among multiple components. (Non-persistent, internal core principle by creating a global instance new Vue)

It mainly includes the following modules:

  • State: Data structure that defines the State of the application, where the default initial State can be set.
  • Getter: Allows the component to get data from the Store. The mapGetters helper function simply maps the getters in the Store to local computed properties.
  • Mutation: is the only method that changes the state in the store, and must be a synchronization function.
  • Action: Used to commit mutation rather than directly change the state, and can include any asynchronous operation.
  • Module: Allows you to split a single Store into multiple stores and Store them simultaneously in a single state tree.

22 What can I do if Vuex Page refresh Data Is Lost

Vuex data persistence is required. Generally, local storage schemes are used to store data. You can design your own storage schemes or use third-party plug-ins

It is recommended to use the vuex-Persist plug-in, which is designed for vuex persistent storage. You do not need to manually access the storage, but directly save the state to a cookie or localStorage

Why is Vuex divided into modules and namespace

Module: Because of the use of a single state tree, all the states of the application are grouped into one large object. When the application becomes very complex, the Store object can become quite bloated. To solve these problems, Vuex allows us to split the Store into modules. Each module has its own state, mutation, action, getter, and even nested submodules.

Namespaces: By default, actions, mutation, and getters inside a module are registered in the global namespace — this enables multiple modules to respond to the same mutation or action. If you want your modules to be more wrapped and reusable, you can make them namespaced by adding namespaced: True. When a module is registered, all its getters, actions, and mutations are automatically named according to the path the module was registered with.

24 Have you used Vue SSR? Tell me something about the SSR

SSR is server side rendering, which means Vue renders the tags into HTML on the server side, and then returns the HTML directly to the client side.

Advantages:

SSR has better SEO and faster first screen loading

Disadvantages: the development conditions are limited. Server-side rendering only supports beforeCreate and Created hooks, which need special processing when we need some external extension libraries. Server-side rendering applications also need to run in node.js environment.

There will be more load demands on the server

25 What design patterns are used in vUE

1. Factory mode – Create instance by passing in parameters

The virtual DOM returns the Vnode of the base tag and the component Vnode depending on the parameter

2. Singleton mode – There is only one instance of the entire program

The vuex and VUE-Router plug-in registration method install determines if there is an instance of the system directly return to the system

3. Publish-subscribe (VUE event mechanism)

4. Observer mode (Responsive data Principle)

5. Decorator mode: (@ decorator usage)

A policy pattern is when an object has a behavior that can be implemented differently in different scenarios – for example, a merge strategy of options

. Other modes are welcome

What Vue performance optimizations have you done

This is just a list of performance optimizations for Vue. Performance optimizations for the whole project is a big project. You can write another article on performance optimizations

  • Do not make the object hierarchy too deep, or performance will be poor
  • Do not place data in data that does not require responsiveness (you can use Object.freeze() to freeze data)
  • V-if and V-show are used in different scenarios
  • Computed and Watch distinguish usage scenarios
  • V-for traversal must include a key, preferably an ID value, and do not use v-if at the same time
  • Big data list and table performance optimization – virtual list/virtual table
  • To prevent internal leaks, destroy global variables and events after component destruction
  • Lazy loading of images
  • Route lazy loading
  • The introduction of third-party plug-ins on demand
  • Use the keep-alive cache component as appropriate
  • Anti – shake, throttling application
  • Server render SSR or prerender

difficult

27 Vue.mixin usage scenarios and working principles

In daily development, we often encounter some same or similar codes in different components. The functions of these codes are relatively independent, and they can be separated from the common business logic through the mixin function of Vue. The principle is similar to “object inheritance”. The mergeOptions method is called when the component is initialized to merge, using the policy pattern to merge for different properties. When components and mixins have options with the same name, those options are “merged” in the appropriate way.

The relevant codes are as follows

Export default function initMixin(Vue){vue. mixin = function (mixin) {// Merge objects this.options=mergeOptions(this.options,mixin) }; }}; // SRC /util/index.js export const LIFECYCLE_HOOKS = ["beforeCreate", "created", "beforeMount", "mounted", "beforeUpdate", "updated", "beforeDestroy", "destroyed", ]; // merge policy const strats = {}; // mixin core method export function mergeOptions(parent, child) {const options = {}; For (let k in parent) {mergeFiled(k); } for (let k in child) {if (! parent.hasOwnProperty(k)) { mergeFiled(k); Function mergeFiled(k) {if (strats[k]) {options[k] = strats[k](parent[k], child[k]); } else {// Default policy options[k] = child[k]? child[k] : parent[k]; } } return options; } Duplicate codeCopy the code

The Vue. Mixin principle explains the portal

28 Application scenarios and working principles of nextTick

The callbacks in nextTick are deferred callbacks that are executed after the next DOM update cycle ends. Use this method immediately after modifying the data to get the updated DOM. The main idea is to invoke asynchronous methods to execute nextTick wrapped methods in a microtask-first manner

The relevant codes are as follows

let callbacks = []; let pending = false; function flushCallbacks() { pending = false; For (let I = 0; i < callbacks.length; i++) { callbacks[i](); } } let timerFunc; // Define asynchronous methods that gracefully degrade if (typeof Promise! Const p = promise.resolve (); timerFunc = () => { p.then(flushCallbacks); }; } else if (typeof MutationObserver ! == "undefined") {// let counter = 1; const observer = new MutationObserver(flushCallbacks); const textNode = document.createTextNode(String(counter)); observer.observe(textNode, { characterData: true, }); timerFunc = () => { counter = (counter + 1) % 2; textNode.data = String(counter); }; } else if (typeof setImmediate ! Setimerfunc = () => {setImmediate(flushCallbacks); }; } else {setTimeout timerFunc = () => {setTimeout(flushCallbacks, 0); }; } export function nextTick(cb) {// In addition to rendering watcher, the nextTick is collected in the array callbacks.push(cb); if (! Pending) {// If the nextTick is called multiple times, it will only execute one async call until the async queue is empty and then change the flag to false pending = true; timerFunc(); }} Copy the codeCopy the code

NextTick principle explains the portal

29 Keep-alive application scenarios and working principles

Keep-alive is a built-in component of Vue. It can cache components and will not uninstall the current component when the component is switched.

  • Two commonly used attributes include/exclude allow components to cache conditionally.

  • Two life cycles, activated/deactivated, are used to determine whether the component is active.

  • Keep-alive also uses LRU(least recently used) algorithm to select the most recently unused components for elimination.

The relevant codes are as follows

Export default {name: "keep-alive", abstract: true, // Abstract component props: {include: patternTypes, // Exclude: PatternTypes, // Components to exclude Max: [String, Number], // Max cache Number}, created() {this.cache = object.create (null); {a:vNode,b:vNode} this.keys = []; Destroyed () {for (const key in this.cache) {pruneCacheEntry(this.cache, key, this.keys); }}, mounted() {// Exclude this.$watch("include", (val) => {pruneCache(this, (name) => matches(val); name)); }); this.$watch("exclude", (val) => { pruneCache(this, (name) => ! matches(val, name)); }); }, render() { const slot = this.$slots.default; Const vNode: vNode = getFirstComponentChild(slot); // Get the first child const componentOptions:? VNodeComponentOptions = vnode && vnode.componentOptions; if (componentOptions) { // check pattern const name: ? string = getComponentName(componentOptions); const { include, exclude } = this; If (// not included include && (! name || ! Matches (include, name))) | | / / excluded out inside (exclude && name && matches (exclude, name))) {/ / return the virtual node return vnode. } const { cache, keys } = this; const key: ? string = vnode.key == null ? // same constructor may get registered as different local components // so cid alone is not enough (#3269) componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : "") : vnode.key; Vnode.componentinstance = cache[key]. ComponentInstance; // make current key freshest remove(keys, key); Key.push (key); // Delete key.push (key); } else {cache[key] = vnode; Key.push (key); key.push (key); If (this.max && keys.length > parseInt(this.max)) {// Select * from prune's list if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode); } } vnode.data.keepAlive = true; / / tag virtual node is cached} / / return return virtual node vnode | | (slot && slot [0]). }}; Copy the codeCopy the code

What is the LRU algorithm?

The core idea of LRU is that if the data has been accessed recently, it has a higher chance of being accessed in the future, so we insert the component key that hit the cache back into the tail of this.keys. In this way, the further to the head of this.keys, the lower the chance of being accessed in the future. We remove the data least likely to be accessed in the future, which is the first cached component in this.keys.

30 Principle of vue. set method

Those of you who know about Vue responsiveness know that the Vue does not trigger view updates in either case

1. Add new attributes to the instance after the instance is created (add new attributes to the responsive object)

2. Modify the array value by directly changing the array subscript

Vue. Set or $set works as follows

For reactive data we add an __ob__ attribute to both the object and the array itself, which represents an Observer instance. When adding nonexistent attributes to an object, the new attributes will be tracked in a responsive manner first, and then the watcher collected by the deP of __ob__ will be triggered to update. When modifying the array index, we call the splice method of the array itself to update the array

The relevant codes are as follows

export function set(target: Array | Object, key: any, val: any): If (array.isarray (target) &&isValidArrayIndex (key)) {target.length = Math.max(target.length, key); target.splice(key, 1, val); return val; } // If (key in target &&! (key in Object.prototype)) { target[key] = val; return val; } const ob = (target: any).__ob__; // If it is not reactive, you do not need to define it as reactive if (! ob) { target[key] = val; return val; } // Define attributes as reactive defineReactive(ob.value, key, val); // Update the notification view ob.dep.notify(); return val; } Duplicate codeCopy the code

The principle of responsive data explains the portal

31 Vue.extend Functions and principles

Official explanation: Vue.extend creates a “subclass” using the base Vue constructor. The parameter is an object that contains component options.

A subclass constructor is the core API of the Vue component. The implementation idea is to use the method of prototype inheritance to return the Vue subclass and use mergeOptions to merge the options passed into the component and the options of the parent class

The relevant codes are as follows

export default function initExtend(Vue) { let cid = 0; Extend = function (extendOptions) {// Create a constructor for the subclass and call the initialization method const Sub = function VueComponent(options) { this._init(options); // Call Vue initializer}; Sub.cid = cid++; Sub.prototype = Object.create(this.prototype); / / subclass prototype points to the parent class Sub. The prototype. The constructor = Sub; //constructor points to yourself sub. options = mergeOptions(this.options, extendOptions); // merge your own options with your parent's Options Return Sub; }; } Duplicate codeCopy the code

Vue components explain the principle of the portal

Have you ever written a custom instruction? How does it work

Directives are essentially decorators that are vUE extensions to HTML elements, adding custom capabilities to HTML elements. When VUE compiles the DOM, it finds the instruction object and executes the methods associated with the instruction.

A custom directive has five lifecycles (also called hook functions), namely bind, INSERTED, Update, componentUpdated, and unbind

1. Bind: Called only once, when the directive is first bound to an element. This is where you can perform one-time initialization Settings. 2.inserted: Called when the bound element is inserted into a parent (the parent is guaranteed to exist, but not necessarily already inserted). Update: Called when the template to which the element is bound is updated, regardless of whether the binding value changes. Unnecessary template updates can be ignored by comparing the binding values before and after the update. 4. ComponentUpdated: Called when the template to which the bound element belongs completes an update cycle. 5. Unbind: Called only once, when an instruction is unbound from an element. Copy the codeCopy the code

The principle of

1. When generating the AST syntax tree, directives are encountered to add the cache attribute to the current element

2. Generate instruction code by genDirectives

3. Extract the hook of the instruction to CBS before patch, and invoke the corresponding hook during patch

4. When executing the corresponding hook function, invoke the method defined by the corresponding instruction

33 What are the Vue modifiers

Event modifier

  • .stop Prevents the event from spreading
  • . Prevent Prevents the default behavior of labels
  • .capture uses the event capture mode, where events triggered by elements themselves are processed here before they are processed by internal elements
  • .self fires the handler only if the event.target is the current element itself
  • The.once event will be raised only once
  • .passive Tells the browser that you do not want to block the event’s default behavior

Modifier for v-model

  • .lazy is converted to resynchronization at the change event via this modifier

  • .number Automatically converts user input values to numeric types

  • . Trim Automatically filters the first and last Spaces entered by users

Modifier for keyboard events

  • .enter
  • .tab
  • .delete (capture the delete and backspace keys)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

System modifier key

  • .ctrl
  • .alt
  • .shift
  • .meta

Mouse button modifier

  • .left
  • .right
  • .middle

34 Principles of Vue Template Compilation

The Vue compilation process converts the template into the render function in three steps

The first step is to convert the template strings to the Element ASTs (parsers). The second step is to tag the AST with static nodes, The third step is to use the Element ASTs to generate the render function code string (code generator) and copy the codeCopy the code

The relevant codes are as follows

Export function compileToFunctions(template) {// We need to change the HTML string to render function // 1. The ast is used to describe the code itself, forming a tree structure that not only describes HTML but also CSS and JS syntax // Many libraries use ast such as Webpack Babel ESLint and let AST = parse(template); // optimize static nodes // If (options.optimize! == false) { // optimize(ast, options); // we need to generate the same code as the render function Similar _c (' div '{id: "app"}, _c (' div', undefined, _v (" hello "+ _s (name)), _c (' span, undefined, _v (" world")))) / / _c _v create elements represented create text _s stands for text json.stringify -- parse an object into text let code = generate(ast); RenderFn = new Function(' with(this){return '){renderFn = new Function(' with(this){return ') ${code}}`); return renderFn; } Duplicate codeCopy the code

The template compiler principle explains the portal

How are lifecycle hooks implemented

The lifecycle hook core implementation of Vue uses a published-subscription model to subscribe to the lifecycle hook passed in by the user (stored in an array internally) and then execute the corresponding hook method (published) once during the creation of the component instance.

The relevant codes are as follows

$handlers = vm.$options[hook]; export function callHook(vm, hook) { if (handlers) { for (let i = 0; i < handlers.length; i++) { handlers[i].call(vm); }} // call vue.prototype. _init = function (options) {const vm = this; vm.$options = mergeOptions(vm.constructor.options, options); callHook(vm, "beforeCreate"); // initState initState(vm); callHook(vm, "created"); $options.el) {vm.$mount(vm.$options.el); }}; Copy the codeCopy the code

The life cycle implements the detail portal

36 Application scenarios and principles of functional Components

Differences between functional components and normal components

1. You need to specify functional:true in the declaration component. No instantiation is required, so there is no this, which replaces 3 with context, the second argument to the render function. There are no lifecycle hook functions, no calculation properties can be used, watch 4. Events cannot be exposed via $emit, and events can only be called via context.listeners. Click from external events. Because functional components are not instantiated, when a component is referenced externally via ref, HTMLElement 6 is actually referenced. Functional components don't need to be declared, so properties that aren't declared in props are automatically resolved implicitly to prop, while ordinary components resolve all undeclared properties into $attrs and automatically mount copied code to the component root element (which is disallowed by the inheritAttrs attribute)Copy the code

Advantages 1. Because functional components do not require instantiation, are stateless, and have no life cycle, rendering performance is better than normal components 2. The functional component structure is simpler and the code structure is clearer

Usage Scenarios:

A simple presentation component, used as a container component such as router-View is a functional component

“Higher-order component” – used to take a component as a parameter and return a wrapped component

The relevant codes are as follows

If (isTrue (Ctor. Options. The functional)) {/ / with the functional properties of return is a functional component createFunctionalComponent (Ctor, propsData, data, context, children); } const listeners = data.on; data.on = data.nativeOn; installComponentHooks(data); // Install component-related hooks (functional components do not call this method and thus perform better than normal components) to copy the codeCopy the code

37 Can you explain the implementation principle of the common routing mode in vue-router

Hash pattern

  1. The value of location.hash is exactly what comes after the # in the URL. It’s nice to see that the hash appears in the URL, but it’s not included in the HTTP request. It doesn’t affect the back end at all, so changing the hash doesn’t reload the page.

  2. You can add listening events for changes to the hash

    window.addEventListener(“hashchange”, funcRef, false); Copy the code

Each change to the hash (window.location.hash) adds a record to the browser’s access history. Using the above features of the hash, we can implement the front-end routing “update the view without rerequesting the page” function

Features: Good compatibility but not beautiful

The history mode

Takes advantage of the new pushState() and replaceState() methods in the HTML5 History Interface.

These two methods apply to the browser’s history station and provide the ability to modify the history in addition to the existing back, Forward, and Go methods. The two methods have a common feature: when they are called to modify the browser history stack, the browser does not refresh the page even though the current URL has changed, which provides the basis for single-page application front-end routing “update the view without rerequesting the page.”

Features: Although beautiful, but refresh will appear 404 needs to be configured on the back end

Do you know diff algorithm

It is recommended to look directly at the DIff algorithm to solve the portal

Series of links (will be updated later)

  • Handwritten Vue2.0 source code (a) – responsive data principle
  • Handwritten Vue2.0 source code (two) – template compilation principle
  • Handwritten Vue2.0 source code (three) – initial rendering principle
  • Handwritten Vue2.0 source code (four) – rendering update principle
  • Handwritten Vue2.0 source code (five) – asynchronous update principle
  • Handwritten Vue2.0 source code (six) – DIff algorithm principle
  • Handwritten Vue2.0 source code (seven) -Mixin mixed principle
  • Handwritten Vue2.0 source code (eight) – component principle
  • Handwritten Vue2.0 source code (nine) – listening attribute principle
  • Handwritten Vue2.0 source code (ten) – calculation of attribute principle
  • Handwritten Vue2.0 source code (eleven) – global API principle
  • The most complete Vue interview questions + detailed answers
  • Handwritten vue-Router source code
  • Handwritten vuex source code
  • Handwritten VUe3.0 source code