current position:Home>Vue interview questions

Vue interview questions

2021-08-27 11:21:07 Ka Ka 999

keep-alive What does a component do ?

keep-alive yes vue Built in components of , In general , When switching components , It will be destroyed by default , If we want to not destroy a component after switching , It's about preserving the state before , Then we can use keep-alive To achieve .

keep-alive It's an abstract component : It doesn't render a DOM Elements , It also doesn't appear in the parent component chain ; Use keep-alive When wrapping dynamic components , An inactive component instance is cached , Instead of destroying them .

scene :

The user selects the filter criteria on a list page to filter out a data list , Enter the data details page from the list page , Return to the list page ,

We hope : The list page can keep the user's filter ( Or select ) state . keep-alive To solve this kind of situation . Of course keep-alive It's not just being able to save pages / The state of the component is so simple , It also prevents components from repeatedly creating and rendering , Effectively improve system performance . in general ,keep-alive Used to save the rendering state of the component . include and exclude A component whose value matches a string or regular expression name Will it be cached .

  path: '/',
  name: 'xxx',
  component: ()=>import('../src/views/xxx.vue'),
    keepAlive: true //  Need to be cached 
 Copy code 

(exclude first ) There are two independent life cycles actived and deactived, Use keep-alive The components of the package will not be destroyed during switching , Instead, cache into memory and execute deactived Hook function , Execute after hit cache rendering actived Hook function .

vue Life cycle

In the life cycle function this The point is vm or Component instance object . image.png


About VueComponent



vue In the component data It has to be a function ?

If data It's an object , When reusing components , because by data Will point to the same reference type address , Of one of the components data Once modified , In other components data It will also be modified . If data Is a function that returns an object , Because every time a component is reused, a new object is returned , The reference address is different , There will be no such problem .

Vue in v-if and v-show What's the difference? ?

v-if When switching , The label will be directly Create or destroy , Labels that are not displayed will not be loaded in DOM In the tree . v-show When switching , Will be on the label display Property to switch , adopt display Do not show to hide elements . Generally speaking ,v-if The performance overhead will be lower than v-show Big , Labels that switch frequently are more suitable for use v-show.

Vue in computed and watch What's the difference? ?

 Supports caching , Only when the dependent data changes , Will recalculate the function ;
 Asynchronous operations are not supported within calculated properties ;
 There is one in the function that calculates the attribute  get and set
 Calculating properties automatically listens for changes in dependency values , So we can dynamically return the content . 
 Copy code 


get When to call ?1. First read fullName when .2. When the dependent data changes .

 Caching is not supported , As long as the data changes , Will execute the listening function ; 
 Asynchronous operation is supported in the listening attribute ,
 The value of the listening property can be an object , receive  handler  Callback ,deep,immediate 
 Monitoring is a process , When the monitored value changes , You can operate some methods in it ,compute Can not be , For example, add a timer .
 Copy code 


Vue-router What are the routing modes ?

hash Pattern

hinder hash Change in value , The browser makes no requests to the server , The browser will not refresh , Every time hash A change in value triggers hashchange event .

history Pattern

Take advantage of HTML5 In the new pushState() and replaceState() Method .

These two methods apply to the browser's history stack , Existing back、forward、go Based on , they It provides the function of modifying history .

vue Of $forceUpdate and $set

$forceUpdate( Used to force global refresh , High performance consumption )

force VUE Instance re rendering . Be careful : It only affects the instance itself and the subcomponents that insert the contents of the slot , Instead of all the sub components . Use scenarios : 1. During route switching , The page data is complex 2. Change the data in the multidimensional array The variables in are arrays or objects , Let's just add properties to an object or array , The page is unrecognized


Vue.prototype.$forceUpdate = function () {
    const vm: Component = this
    if (vm._watcher) {
 Copy code 

The instance needs to be re rendered , It will notify when the dependency changes watcher, And then inform watcher To call update Method .

this.set(object, index, new) ,this.set() The method is vue Self contained , You can assign values to arrays and objects , And trigger the method of listening .( Used to force directional refresh , Low performance consumption )

Pay attention to item : Attention object cannot be Vue example , perhaps Vue The root data object of the instance .

this.$set(this.$data, 'age', 24) // You can't give vue Set the root data object of the instance , Will report a mistake 
 Copy code 

Add a property to the responsive object , And make sure that the new attribute is also responsive , At the same time, the update of the corresponding view is triggered .$set Must be used to add new properties to the responsive object , because Vue Can't detect normal new properties .

diff Algorithm

What is virtual DOM

One is used to represent reality DOM The object of


fictitious DOM More real DOM fast , This is not true .

fictitious DOM Algorithm operation is real DOM, Performance is higher than direct operation DOM.

fictitious DOM And the virtual DOM Algorithms are two concepts . fictitious DOM Algorithm = fictitious DOM + Diff Algorithm

What is? Diff Algorithm

summary :Diff The algorithm is a comparison algorithm . Compared with the old virtual DOM And new virtual DOM, Find the changed virtual node , And only the real node corresponding to the virtual node is updated , Do not update other nodes whose data has not changed , Achieve accurate update of real DOM, And then improve efficiency .

Use virtual DOM Loss calculation of the algorithm :

Total loss = fictitious DOM Additions and deletions +( And Diff Algorithm efficiency is related to ) real DOM To add, delete, or modify differences +( Fewer nodes ) Typesetting and redrawing

Direct operation is real DOM Loss calculation of :

Total loss = real DOM Complete addition, deletion and modification +( There may be more nodes ) Typesetting and redrawing

Diff Principle of algorithm


New and old virtual DOM When comparing ,Diff Algorithm comparison Only at the same level , No cross level comparison .

Diff Compare the process


When data changes , Trigger setter, And pass Dep.notify To inform all subscribers Watcher, Subscribers will call patch Method , To be true DOM patch up , Update the corresponding view .

patch Method

effect : Compare whether the virtual nodes in the same layer are the same type of labels yes : Carry on patchVnode Methods deep comparison no : There's no need to compare , Directly replace the entire node with a new virtual node

function patch(oldVnode, newVnode) {
  //  Compare whether it is a type of node 
  if (sameVnode(oldVnode, newVnode)) {
    //  yes : Continue to make deep comparison 
    patchVnode(oldVnode, newVnode)
  } else {
    //  no 
    const oldEl = oldVnode.el //  The real of the old virtual node DOM node 
    const parentEle = api.parentNode(oldEl) //  Get parent node 
    createEle(newVnode) //  Create the real node corresponding to the new virtual node DOM node 
    if (parentEle !== null) {
      api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) //  Add a new element to the parent element 
      api.removeChild(parentEle, oldVnode.el)  //  Remove previous old element nodes 
      //  Set up null, Free memory 
      oldVnode = null

  return newVnode
 Copy code 

sameVnode Method

patch The key step is sameVnode Method to determine whether it is a node of the same type Compare key, Tag name , Whether they are all annotation nodes , Is there a definition of data, The label is input when ,type It has to be the same

function sameVnode(oldVnode, newVnode) {
  return (
    oldVnode.key === newVnode.key && // key Is it worth the same 
    oldVnode.tagName === newVnode.tagName && //  Whether the tag names are the same 
    oldVnode.isComment === newVnode.isComment && //  Whether they are all annotation nodes 
    isDef( === isDef( && //  Is it all defined data
    sameInputType(oldVnode, newVnode) //  When the label is input when ,type Must be the same 
 Copy code 

patchVnode Method

Find the truth DOM, be called el

Judge newVnode and oldVnode Whether to point to the same object , If it is , So directly return If they all have text nodes and are not equal , It will be el The text node of is set to newVnode Text node of . If oldVnode There are child nodes and newVnode No, , Delete el Child nodes of If oldVnode There are no child nodes and newVnode Yes , Will newVnode The child nodes of are added to el If both have children , execute updateChildren Function compare child node , This is an important step

function patchVnode(oldVnode, newVnode) {
  const el = newVnode.el = oldVnode.el //  Get real DOM object 
  //  Get the child node array of old and new virtual nodes 
  const oldCh = oldVnode.children, newCh = newVnode.children
  //  If the old and new virtual nodes are the same object , Then terminate 
  if (oldVnode === newVnode) return
  //  If the old and new virtual nodes are text nodes , And the text is different 
  if (oldVnode.text !== null && newVnode.text !== null && oldVnode.text !== newVnode.text) {
    //  Then it will be true DOM The Chinese text is updated to the text of the new virtual node 
    api.setTextContent(el, newVnode.text)
  } else {
    //  otherwise 

    if (oldCh && newCh && oldCh !== newCh) {
      //  Both old and new virtual nodes have child nodes , And the child nodes are different 

      //  Compare child nodes , And update the 
      updateChildren(el, oldCh, newCh)
    } else if (newCh) {
      //  The new virtual node has child nodes , The old virtual node does not 

      //  Create a child node of the new virtual node , And update to real DOM Up 
    } else if (oldCh) {
      //  The old virtual node has child nodes , No new virtual node 

      // Delete Real directly DOM Corresponding child nodes in 
 Copy code 

updateChildren Method ( important )

Comparison of child nodes of old and new virtual nodes , It happened in updateChildren In the method

image.png Head and tail pointer method , New child node set and old child node set , There are two pointers at the beginning and end , A combination of two , Compare , There are four situations .

There are five comparisons :

1、oldS and newS Use sameVnode Methods for comparison ,sameVnode(oldS, newS)

2、oldS and newE Use sameVnode Methods for comparison ,sameVnode(oldS, newE) 3、oldE and newS Use sameVnode Methods for comparison ,sameVnode(oldE, newS) 4、oldE and newE Use sameVnode Methods for comparison ,sameVnode(oldE, newE) 5、 If none of the above logic matches , Put all the old child nodes  key  Make a map to the old node subscript  key -> index  surface , Then use new  vnode  Of  key  To find out where the old nodes can be reused .

The final rendering results should be newVDOM Subject to

** use index do key Why not ? **

In the process of child node diff In the process of algorithm , The old first node and the new first node will be sameNode contrast .

If you put a label in front of a list , Lead to the same key The node will go patchVnode Update text , And the last node that existed , As a new node . All the previous are patchVnode Update text , The last one is added . This reduces efficiency .

vue The core (MVVM)

Just focus on the trial layer Data driven , Componentization

Data bidirectional binding core :MVVM

『View』: View layer (UI The user interface )

『ViewModel』: Business logic layer ( everything js It can be seen as business logic ) 『Model』: The data layer ( Data storage and data processing, such as adding, deleting, modifying and querying )


Model and ViewModel The interaction is two-way , therefore View The changes will be automatically synchronized to Model, and Model Changes in will also be immediately reflected in View Displayed on the .

When the user operates View,ViewModel Perceive change , And then inform Model Change accordingly ; On the other hand when Model Change ,ViewModel Can also sense change , send View Update accordingly . ### sketch MVVM

MVVM yes Model-View-ViewModel Abbreviation .

MVVM It's a design idea . Model The layer represents the data model , It can also be in Model Business logic for defining data modifications and operations View representative UI Components , It is responsible for transforming the data model into UI show , ViewModel It's a synchronization View and Model The object of .

stay MVVM Under the architecture ,View and Model There is no direct connection , But through ViewModel Interact ,Model and ViewModel The interaction is two-way , therefore View The changes in the data will be synchronized to Model in , and Model Changes in the data are also immediately felt View On .

ViewModel Through two-way data binding View Layer and the Model The layers are connected .

View and Model The synchronization between the two works completely automatically , Without human intervention .

So developers just need to focus on the business logic , No manual operation is required DOM, There is no need to focus on synchronization of data state , Complex data state maintenance completely by MVVM To unify management .

sketch Vue.js The advantages of

1 Low coupling .

View (View) Can be independent of Model Changes and modifications , One ViewModel Can be bound to different "View" On , When View When it changes Model It can be the same , When Model When it changes View It can be the same .

2 Reusability .

You can put some view logic in one ViewModel Inside , Let a lot of View Reuse this view logic .

3 Independent development .

Developers can focus on the development of business logic and data (ViewModel, Designers can focus on page design .

4 Convenient test .

The interface is always more difficult to test , Most of the development Bug As for logical processing , because ViewModel Separated a lot of logic , It can be done to ViewModel Construct unit tests . Easy to use flexible Efficient .

Vue Not exactly following MVVM Thought

Strict MVVM requirement View Unable to join Model Direct communication , and Vue Provides $refs This attribute , Give Way Model Can be operated directly View, In violation of this rule , So Vue Not fully following MVVM

vue Configure reverse proxy to solve cross domain problems

To configure :config/index.js Medium proxyTable

	proxyTable: {
      '/api': {
        target: '', //  The domain name to be represented 
        changeOrigin: true,// Allow cross-domain 
        pathRewrite: {
          '^/api': '' //  This is to define the path to access , Write your name casually 
 Copy code 
// /api/getMenu amount to *
 // /api amount to
 this.$http.get("/api/getMenu", {
 .then(res => {
 .catch(function(error) {
 Copy code 

Be careful : Take the code set above as an example , All requests with /api Replace all of the fields , for example api/getMenu/api, The first two will be replaced , Lead to 404 Such mistakes , This problem is easy to occur when there are a large number of agents .

The above configuration is only in the development environment (dev) Solve cross domain problems in . To solve the cross domain problem of production environment , It's in config/dev.env.js and config/prod.env.js That is, development / Configure the requested addresses in the production environment API_HOST. In the development environment, we use the proxy address configured above api, Use the normal interface address in the production environment . The configuration code is as follows :

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',     // development environment 
 Copy code 
module.exports = {
  NODE_ENV: '"production"',      // Production environment 
 Copy code 

principle Browsers are forbidden to cross domain , But the server does not prohibit , Run locally npm run dev When you wait for a command, you actually use node Running a server ,IP Inconsistent with the back end , So there will be cross domain problems , Need to use such as JSONP、 Cross domain proxy and other means to make cross domain requests . and vue It has been configured for us , Just set it up proxyTable Just go . therefore proxyTable In fact, it sends the request to its own server , Then the server forwards it to the background server , I've done a layer of agency ,so There's a cross domain problem .

Bottom vue-cli use http-proxy-middleware Plug in to configure the proxy server .

Vue There are several ways of component communication

props and $emit The parent component passes data to the child component through prop Delivered , The child component passes the data to the parent component through $emit Trigger events to do **

$parent,$children Get the parent component of the current component and the child component of the current component

$attrs and $listeners A->B->C.Vue 2.4 Began to offer $attrs and $listeners To solve this problem

First look $attrs and $listeners In the definition of Vue In the document :

vm.$attrs Contains inaction in the parent scope prop Be identified ( And get ) Of attribute binding (class and style With the exception of ). When a component does not declare anything prop when , This will include all bindings for the parent scope (class and style With the exception of ), And through v-bind="$attrs" Incoming internal components —— Useful when creating high-level components .

$listeners Contains... In the parent scope ( Not included .native Decorator's ) v-on Event listener . It can go through v-on="$listeners" Incoming internal components —— Useful for creating higher-level components .





You can see the parent component App.vue Pass through v-bind to Child1 Three values were passed , Not used in subcomponents Props The values received are in a t t r s in , It can also be through v b i n d Pass the value to C h i l d 1 The internal components of C h i l d 2 , It can also be used attrs in , It can also be through v-bind Pass the value to Child1 The internal components of Child2, It can also be used listeners Add... In the parent scope v-on Event listener , Pass in child2

inheritAttrs Properties and functions

When a component is set inheritAttrs: false after ( The default is true), Then the non of the component props attribute ( That is to say, it has not been props Received properties ) Will not generate on the component root node html attribute , Think it's a comparison chart Pass... In the parent component provide To provide variables , And then in the subcomponent through inject To inject variables .( The official does not recommend using it in actual business , But it's very common to write component libraries )



$refs Get component instance

envetBus Brother component data transfer In this case, you can use the event bus approach

vuex State management

At which step is the asynchronous request initiated ?

You can use the hook function created、beforeMount、mounted Make asynchronous requests in , Because in these three hook functions ,data Created , You can assign values to the data returned by the server .

If asynchronous requests don't need to rely on Dom Recommended in the created The asynchronous request is invoked in the hook function , Because in created In the hook function, calling asynchronous requests has the following advantages :

Can get the server data faster , Reduce pages loading Time ;

ssr I won't support it beforeMount 、mounted Hook function , So put it in created For consistency ;

vue Built in instructions

image.png v-cloak It can solve the interpolation flicker problem ( Prevent code from being seen ), Add... To the element v-cloak that will do

<p v-cloak>{{msg}}</p>
  display: none;
 Copy code 

### How to understand Vue One way data flow of Data is always passed from parent component to child component , The child component has no right to modify the data passed by the parent component , Only the parent component can be requested to modify the original data . This prevents accidental changes to the state of the parent component from the child component , This causes your application's data flow to be difficult to understand .

If you really want to change the parent component prop value You can do it again data It defines a variable , And use prop Initialize it with the value of After use $emit Inform the parent component to modify

Vue How to detect array changes

push,shift,pop,unshift,splice,sort,reverse Method

So in Vue Modifying the index and length of an array in is not monitored . Need to pass the above 7 Only by modifying the array with two mutation methods can the corresponding array be triggered watcher updated

Overriding the native methods in the array , First, we get the Observer object , If there's a new value , Just call observeArray Continue to observe the change for the new value ( That is, through target__proto__ == arrayMethods To change the type of array instances ), Then call it manually notify, Notification rendering watcher, perform update.


1 Multiple root nodes are supported , Change to use fragment, 2 Composition API

setup Within the assembly as Composition API Entrance ,

The timing of execution is beforeCreate Before execution

Use setup when , It takes two arguments :

props: Properties passed in by the component context: Provides this Three of the most commonly used properties in :attrs、slot and emit

setup What we accept in the world props It's reactive , When a new props when , Will be updated in time . Because it's responsive , So you can't use ES6 deconstruction , Deconstruction eliminates its response . use toRefs() solve

ref Can deal with js Basic types , such as ref It can also define the bidirectional binding of objects . Take it worth writing .value however reactive Functions can indeed delegate an object , But you can't delegate basic types , Like strings 、 Numbers 、boolean etc. .

toRefs Used to put a reactive Objects are converted to attributes, all of which are ref Ordinary objects of objects .



modify :setup stay beforeCreate Before , Add... To all life cycle names on,beforeDestory

Change to onBeforeUnmount,destory Change to onUnmounted

watch And watchEffect Usage of

watch(source, callback, [options])

Parameter description :

source: Can support string,Object,Function,Array; Used to specify the responsive variable to listen on callback: Callback function executed options: Support deep、immediate and flush Options .

When you need to listen to multiple data sources , You can merge , Listen to multiple data at the same time

watch([() => state.age, year], ([curAge, newVal], [preAge, oldVal]) => {
console.log(" The new value :", curAge, " Old value :", preAge); console.log(" The new value :", newVal,
" Old value :", oldVal); });
 Copy code 

Listen for complex nested objects

const state = reactive({
  room: {
    id: 100,
    attrs: {
      size: "140 Square meters ",
      type: " Three rooms and two halls ",
  () =>,
  (newType, oldType) => {
    console.log(" The new value :", newType, " Old value :", oldType);
  { deep: true }
 Copy code 

By default ,watch It's inert. , Under what circumstances is not inert , The callback function can be executed immediately ? Set... In the third parameter immediate: true that will do .

stop Stop listening

const stopWatchRoom = watch(() =>, (newType, oldType) => {
    console.log(" The new value :", newType, " Old value :", oldType);
}, {deep:true});

    //  Stop listening 
}, 3000)
 Copy code 

Object.defineProperty And Proxy

Object.defineProperty Only the properties of the object can be hijacked , and Proxy It's a direct proxy

because Object.defineProperty Can only hijack object properties , You need to traverse every property of the object , If the property value is also an object , You need recursive depth traversal . however Proxy Direct proxy object , No traversal operation is required

Object.defineProperty New attributes need to be added manually Observe

because Object.defineProperty Hijacking is the property of the object , So when adding properties , The object needs to be traversed again , Use the new attribute again Object.defineProperty Hijack . That is to say Vue2.x When adding properties to arrays and objects in , Need to use $set To ensure that the new properties are also responsive , $set The internal is also through the call Object.defineProperty To deal with .

Teleport What is it? ? The style is in the outer layer , Can be subject to internal control

I want to continue to use it inside the component Dialog, And hope to render DOM Structure is not nested in the DOM

  <div id="app"></div>
  <div id="dialog"></div>
 Copy code 
  <teleport to="#dialog">
    <div class="dialog">

 Copy code 
<div class="header">
    <navbar />
    <Dialog v-if="dialogVisible"></Dialog>
 Copy code 

Suspense Display the style when there is data and there is no data

Suspense Just a component with slots , It's just that its slot specifies default and fallback Two kinds of state .

        <template #default>
        <template #fallback>
 Copy code 





Data brokers

	1.Vue Data brokers in :
		 adopt vm Object to represent data Operation of properties in object ( read / Write )
	2.Vue Benefits of data brokers in :
		 More convenient operation data Data in 
    3. The basic principle :
		 adopt Object.defineProperty() hold data All properties in the object are added to vm On .
		 Add to... For each vm Properties on , All specify a getter/setter.
		 stay getter/setter Operate inside ( read / Write )data The corresponding attribute in .
 Copy code 


v-html,v-text Will replace the value in the node ,{{XX}} Can't

Custom instruction



v-modal Can it be used on custom components ?

Sure image.png


vue The principle of template compilation

1 Template compilation , Convert template code to AST;

2 Optimize AST, Convenient follow-up virtual DOM to update ; 3 The generated code , take AST Into executable code ;

const baseCompile = (template, options) => {
  //  analysis  html, Turn into  ast
  const ast = parse(template.trim(), options)
  //  Optimize  ast, Tag static nodes 
  optimize(ast, options)
  //  take  ast  Convert to executable code 
  const code = generate(ast, options)
  return {
    render: code.render,
    staticRenderFns: code.staticRenderFns
 Copy code 

vue Use mock.js Switch with real back-end data

mock The method name of the data is the same as the background interface , In this way, when transitioning to the background interface, you only need to change the place of the guide package .

eg: stay index.vue in

//import { fetchQueryLog } from ‘@/api/system/logmanage‘ //-- Background interface 
  import { fetchQueryLog } from ‘../../api/api‘    //---mock The interface of 
 Copy code 
import axios from ‘axios‘;

export const fetchQueryLog = params => { return`/log/query`, { params: params }); };

// --  ‘/log/query‘  by mock The address of the data    params Is the parameter , Available when there are no parameters () Instead of    export const  Is named Export 
 Copy code 

perhaps modify vue.config.js In the document devServer Of proxy To configure

devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    proxy: {
      // change xxx-api/login => mock/login
      // detail:
      [process.env.VUE_APP_BASE_API+'/user/info']: {
        target: `http://localhost:${port}/mock`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        target: process.env.BACKGROUND_APPLICATION_URL,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
    after: require('./mock/mock-server.js')
 Copy code 

.env.development In file , Add a new one BACKGROUND_APPLICATION_URL Variable

# just a flag
ENV = 'development'

# base api
VUE_APP_BASE_API = '/dev-api'

# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail:


# Background application url
BACKGROUND_APPLICATION_URL = 'http://localhost:8080'
 Copy code 

The main idea is through the agent , yes '/user/info' The request is forwarded to mock in , Other requests are forwarded to the background , So you can use mock And the data of the background interface .

Be careful :

  1. vue-cli 3 The project configuration uses vue.config.js file , Instead of using webpack.config.js The file , So when searching for information, pay attention to the version and difference . 2. In the end , hold proxy and after Comment out the whole , It won't be used again mock Data. .

copyright notice
author[Ka Ka 999],Please bring the original link to reprint, thank you.

Random recommended