Self-organized front-end development interview questions

Front-end development interview questions

Article directory

JavaScript Interview Questions

1-JavaScript Data Types

basic type

Five types of ES5: Null, undefined, Boolean, Number, String, ES6 new: Symbol represents a unique value ES10 new: BigInt represents any large integer

reference type

Object object, array array, date date, function function, regular RegExp

The difference between null and undefined

The same point in the if statement, both null and undefined will be converted to false. Both use the equality operator == to be equal

The difference is that undefined means that undefined null means an empty object

ES10 adds BIgInt to represent arbitrarily large integers

The purpose of the bigint data type is to have a larger range of integer values ​​than the number data type

Data Type Storage and Stack Memory

Basic data type: directly stored in the stack memory, occupying a small space, belonging to frequently used data

Reference data type: stored in the stack and heap memory at the same time, occupying a large space, the size is not fixed

What is the difference between stack and heap

Stack: It is a continuous storage data structure with the nature of first-in, last-out and last-in-first-out

Heap: It is a non-continuous tree storage data structure with queue priority, first in first out

2-JavaScript data type judgment, conditional branch

if statement and logical operations

There are only 6 Boolean values ​​in all basic types that are false, namely: 0, null, undefined, false, NaN, empty

Logical Operators

&& Logic and both sides are true, and the condition is true, it will return true, otherwise it will be false

|| If one of the two sides of the logic or is true, and one of the conditions is true, it returns true, and if both are false, it returns false

! Logical NOT, negates a Boolean value

Data type judgment

typeof is fine for judging basic data types, but it does not work when encountering reference data types

		console.log(typeof 2); //number
        console.log(typeof 'str'); //string
        console.log(typeof null); //object
        console.log(typeof undefined); //undefined
        console.log(typeof []);//object 
        console.log(typeof function fn() {
    
    }); //function

instanceof can only correctly judge the reference data type but not the basic data type. Its internal operation mechanism is to judge whether the prototype of this type can be found in its prototype chain

      console.log([] instanceof Array)//true
      console.log(function () {} instanceof Function)//true
      console.log({} instanceof Object)//true
      console.log(new Date() instanceof Date)//true

The constructor seems to be able to deal with basic data types and reference data types, but if a constructor is declared and its prototype points to the prototype of Array, in this case, the constructor also seems powerless

  		 // 以下全为true
        console.log('str'.constructor === String) 
        console.log(true.constructor === Boolean)
        console.log([].constructor === Array)
        console.log(function() {}.constructor === Function)
        console.log({}.constructor === Object)
        console.log((2).constructor === Number)

JavaScript data type conversion

There are three cases of type conversion in JavaScript

1. Convert to numbers and call number(), parseint(), paraseFloat() methods

number method

 		Number('1') //1
        Number(true) //1
        Number(false)//0
        Number('12m')//NaN
        Number({})//NaN
        Number(null)//0
        Number(undefined)//NaN

parseint method

        parseInt('2') //2
        parseInt('2',10) // 2
        parseInt('2',2)  // NaN
        parseInt('a123')  // NaN  如果第一个字符不是数字或者符号就返回NaN
        parseInt('123a')  // 123

parsefloat method

        parseFloat('123a')//123
        parseFloat('123a.01')//123
        parseFloat('123.01')//123.01
        parseFloat('123.01.1')//123.01

2. Implicit conversion

Implicit conversion: When one of the two sides of + is a string and the other is another type, the other type will be converted to a string first, and then the string will be concatenated, and the string will be returned

        let str = '123'
        let res = str - 1 //122
        str+1 // '1231'
        +str+1 // 124

3, converted to a string

toString() method null and undefined cannot call this method

 		Number(1).toString()//'1'
        [1,2].toString()//'1','2'
        true.toString()//'true'

The string() method can be transferred

  		String(123) //'123'
        String(true) //'true'
        String([]) //''
        String(null) //'null'
        String(undefined) //'undefined'
        String({}) //'[object Object]'

Data type comparison object.is, == and ===

=== belongs to strict judgment and directly judges whether the two types are the same

== means the value is equal

Object.is() specially handles NaN, -0, +0 on the basis of ===, guaranteeing that -0 is not equal to +0, but NaN is equal to NaN

        '1' == 1 // true
        '1' === 1 // false
        NaN == NaN //false
        +0 == -0 //true
        +0 === -0 // true
        Object.is(+0,-0) //false
        Object.is(NaN,NaN) //true

what is the result of typeof null and why

The result is object

In the first version of JavaScript, all values ​​were stored in 32-bit units, and each unit contained a small type tag (1-3 bits), as well as the actual data of the value currently being stored. The type label is stored in the lower bits of each cell, and there are five data types:

        000: object   - 当前存储的数据指向一个对象。
          1: int      - 当前存储的数据是一个 31 位的有符号整数。
        010: double   - 当前存储的数据指向一个双精度的浮点数。
        100: string   - 当前存储的数据指向一个字符串。
        110: boolean  - 当前存储的数据是布尔值

        null的类型标签也是000,和Object的类型标签一样,所以会被判定为Object

3-JavaScript Events

What are events (bubbling and default events)

Event capture, the event flow proposed by Netscape is called the event capture flow, from the outside to the inside, starting from the vertex where the event occurs, and searching down step by step until the target element

Event bubbling, the event flow proposed by IE is called event bubbling, which is triggered from the inside to the outside, from the specific target node element, and passed up step by step until the root node.

Event delegation, also known as event proxy. Event delegation is to use event bubbling, that is, to bind the events of child elements to the parent element. If the child element prevents the event from bubbling, then the delegation cannot be realized

Prevent event bubbling, event.stopPropagation() .stop modifier. addEventListener('click', function name, true/false) The default value is false (that is, use event bubbling) true event capture

Benefits: Improved performance, reduced event binding, and thus reduced memory footprint


<body>
    <div class="yeye">
        <div class="baba">
            <div class="erzi"></div>
        </div>
    </div>
    <script>
        var yeye = document.querySelector('.yeye')
        var baba = document.querySelector('.baba')
        var erzi = document.querySelector('.erzi')
        erzi.onclick = function(e) {
            alert('儿子')
                // e.stopPropagation() //第一种
                // e.cancelBubble = true//第二种
        }
        baba.onclick = function() {
            alert('爸爸')
        }
        yeye.onclick = function() {
            alert('爷爷')
        }
    </script>
</body>

block default event

 		 <a href="http://www.baidu.com">跳转百度</a>
  
        let a = document.querySelector('a')
        a.onclick = function(e) {
            e.preventDefault() //第一种
            e.returnValue = false //第二种
            return false//第三种
        }

JavaScript scope and scope chain

Scope, scope is the scope that a variable can use, mainly divided into global scope and function scope

The global scope is the outermost scope in Js, which can be accessed anywhere

Function scope is an independent scope created by js through functions, which can only be accessed inside the function. Functions can be nested, so scopes can also be nested

Es6 has added block-level scope (wrapped by braces, such as: if(){}, for(){}, etc.)

Anti-shake throttling

Anti-shake: The so-called anti-shake means that after the event is triggered, the function can only be executed once within n seconds. If the event is triggered again within n seconds, the function execution time will be recalculated (assistantly understood as the elevator entering, when you sit In the elevator, when people have been entering the elevator (continuous trigger), the elevator door will not close, and no one enters within a certain time interval (stop continuous trigger) to close)

Throttling: The so-called throttling refers to triggering events continuously but executing a function only once in n seconds. There are two ways to implement it, namely the timestamp version and the timer version.

The anti-shake function is: when you trigger it frequently, it will only be executed once in n seconds.

Function throttling is: trigger an event within a fixed time, every n seconds.

The difference between the mouse event mouseenter and mouseover

mouseenter: Triggered once when the mouse enters the bound event listening element node, and triggered again when the mouse moves out of the bound element and enters again. However, when the mouse enters the bound element node and is triggered once, it does not move out, even if the mouse moves, it will no longer be triggered.

mouseover: Triggered once when the mouse enters the bound event listening element node. If the target element contains child elements, it will also trigger when the mouse moves out of the child element to the target element.

mouseenter does not support event bubbling mouseover will bubbling

4-JavaScript application data type Object

method of object

Object.is() 是一种判断两个值是否相同的方法。
语法:Object.is(value1, value2);
参数:value1:要比较的第一个值。value2:要比较的第二个值。
返回值:一个布尔表达式,指示两个参数是否具有相同的值。
 
Object.assign() 方法用于将所有可枚举的自身属性从一个或多个源对象复制到目标对象。
语法:Object.assign(target, ...sources)
参数:target:目标对象——应用源属性的对象,修改后返回。sources:源对象——包含你要应用的属性的对象。
返回值:修改后的目标对象。
 
 
Object.entries() ES8的Object.entries是把对象转成键值对数组, [key, value] 对的数组。
语法:Object.entries(obj)
参数:obj:要返回其自己的可枚举字符串键属性 [key, value] 对的对象。返回值:给定对象自己的可枚举字符串键属性 [key, value] 对的数组。
Object.fromEntries则相反,是把键值对数组转为对象
 
Object.values() 方法返回给定对象自己的可枚举属性值的数组,其顺序与 for...in 循环提供的顺序相同。
语法:Object.values(obj)
参数:obj:要返回其可枚举自身属性值的对象。返回值:包含给定对象自己的可枚举属性值的数组。
 
Object.prototype.hasOwnProperty()
hasOwnProperty() 方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性。
如果指定的属性是对象的直接属性,则该方法返回 true — 即使值为 null 或未定义。如果该属性是继承的或根本没有声明,则返回 false。
语法:hasOwnProperty(prop)
参数:prop:要测试的属性的字符串名称或符号。
返回值:如果对象将指定的属性作为自己的属性,则返回true;否则为false。
 
Object.keys()
Object.keys() 方法用于返回给定对象自己的可枚举属性名称的数组,以与普通循环相同的顺序迭代。
语法:Object.keys(obj)
参数:obj:要返回可枚举自身属性的对象。
返回值:表示给定对象的所有可枚举属性的字符串数组。
 
Object.prototype.toString()
toString() 方法返回一个表示对象的字符串。当对象将被表示为文本值或以期望字符串的方式引用对象时,将自动调用此方法 id。默认情况下,toString() 方法由从 Object 继承的每个对象继承。
语法:toString()
返回值:表示对象的字符串。
 
Object.freeze()
Object.freeze() 方法冻结一个对象,这意味着它不能再被更改。冻结对象可防止向其添加新属性,防止删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。它还可以防止其原型被更改。
语法:Object.freeze(obj)
参数:obj:要冻结的对象。返回值:传递给函数的对象。
 
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)
语法:const me = Object.create(person);
参数:
proto:新创建对象的原型对象。
propertiesObject
可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。
返回值
一个新对象,带着指定的原型对象和属性。

deep copy and shallow copy

Deep copy and shallow copy are for complex data types. Shallow copy only copies one layer, while deep copy is layer-by-layer copy

1 - shallow copy

  • Copy the reference of the original object or the original array directly to the new object or the new array. The new object is just a reference to the original object instead of copying the object itself. The old and new objects share a memory
  • If the attribute is a basic data type, the value of the data type is copied; if the attribute is a reference type, the memory address is copied

2- deep copy

  • Create a new object or array, copy the value of each property of the original object,
  • Deep copy is to completely copy the object from the memory, open up a new area from the heap memory to store the new object, and modify the new object without affecting the original object

3- Assignment

  • When we assign an object to a new variable, we assign the memory address of the object in the stack memory, not the data in the heap memory, that is, two objects
	浅拷贝的实现方式:
   1、object.assign()
   2、lodash 里面的 _.clone 
   3、...扩展运算符
   4、 Array.prototype.concat 
   5、 Array.prototype.clice
 
    深拷贝的实现方式
    1、JSON.parse(JSON.stringify())
    2、递归操作
    3、cloneDeep
    4、Jquery.extend()   

5-JavaScript array

array method

  1. sort(): sorting, if the following parameters are positive and negative, control, ascending order, descending order, return the original array re-sorted, there is an optional parameter (you can specify the sorting condition), if it is not written, it will be sorted by the Unicode position of each character by default

  2. splice(): insert at the index specified by the array, and return the set of deleted array elements, the first parameter indicates the index bit to start intercepting, the second parameter indicates the length of the interception, returns the intercepted array, the original array Change; three or more parameters, the third and subsequent parameters indicate the value to be inserted from the interception bit, which will change the original array

    		let arr = [1, 2, 3, 4, 5]
         	//参数2为从下标为2开始,第二个参数为截取几个   
            let cutArr = arr.splice(2, 2, '我是被插入的数据')
            console.log(arr)//[1, 2, '我是被插入的数据', 5]
            console.log(cutArr)//[3, 4]
    
  3. pop(): Delete a piece of data from the end of the array, return the deleted element, and change the original array

  4. push(): Add data from the end of the array, return the new array length, and change the original array

  5. shift(): Delete an element from the head of the array, return the deleted element, and change the original array

  6. unshift(): Add data from the head of the array, return the new array length, and change the original array

  7. reverse(): reverse the array without changing the original array

  8. concat(): array merge

  9. slice(): Intercept the array and return the newly intercepted array without changing the original array

     		 let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let newArr = arr.slice(1, 3) //[2,3] 从第一位开始,但不包括第一位,从第三位结束
            console.log(newArr)
    
  10. join(): splits the array into strings, the return value is the string and the added content, only one layer can be split, and the original array will not be changed

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.join('-')
            console.log(res)//1-2-3-4-5-6-7-8-9
    
  11. filter(): Runs the given function on each item in the array, returning an array of items that satisfy the function. filter

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.filter(i => i > 4)
            console.log(res) //[5, 6, 7, 8, 9]
    
  12. every(): returns true when every element in the array is returned true on the callback

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.every(i => i > 0)
            console.log(res) //true
    
  13. some(): returns true when there is an element in the array that is returned true on the callback.

     		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.some(i => i > 3)
            console.log(res) //true
    
  14. reduce( ): There are 4 parameters in the callback function. prev (previously calculated value), next (previously calculated next value), index, arr. Computes the list of arrays into a

  15. isArray(): Determine whether it is an array

  16. The IndexOf method returns the position of the first occurrence of a specified string value in the string, or -1 if no matching string is found

       		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.indexOf(4)
            let res1 = arr.indexOf(21)
            console.log(res) //3
            console.log(res1) //-1
    
  17. lastIndexOf It searches forward from the last value. If it is found, it will return the current subscript. If it is not found, it will return -1.

  18. Array.of(), fills a single value

  19. find(): Find the first number that meets the conditions in this group of numbers and return it to him

  20. forEach(): traverse the original array

  21. map():

6 - JavaScript strings

string method

  1. chartAt( ): returns the character at the specified position;

  2. concat( ): returns a new string**, concatenates one or more strings with the original string

  3. indexOf( ): Retrieves a string, returns the index of the first occurrence, or -1 if it does not appear

  4. lastIndexOf(searchValue[fromIndex]) Returns the index of the first occurrence from the end of the string, if not -1, the value of fromIndex is relative to the index from the end

  5. split( ): Returns an array separated by the position where the specified delimiter appears, and the array elements do not contain delimiters

    		let str = '李-育-狗-是-个-狗'
            let res = str.split('-', 6)
            console.log(res)//[ '李', '育', '狗', '是', '个', '狗' ]
    
  6. substr( ): extracts the specified number of characters in the string from the starting index number

    		let str = 'hello'
            console.log(str.substr(1, 3))//ell
    
  7. substring( ): Extract the characters between two specified index numbers in the string

    		let str = 'hello'
            console.log(str.substring(1, 3)) //el
    
  8. toLowerCase( ): string to lowercase;

  9. toUpperCase( ): string to uppercase

  10. valueOf( ): returns the original value of a string object

  11. trim( ): removes spaces from both sides of the string

  12. trimState removes the leading spaces

  13. trimEnd remove trailing spaces

  14. includes(searchString[, position]) returns boolean, to determine whether a string is included in another string, start searching from postition index, default 0

     		let str = '张三李四王五'
            alert(str.includes('李四'))//true
    
  15. slice( ): extracts a string slice and returns the extracted part in a new string

            let str = '张三李四王五'
            console.log(str.slice(2, 6)) //李四王五,从第二位截到第六位 但是不包含第二位
    
  16. search(regexp) returns the index of the first match, if not -1, perform a search match between the regular expression and the String object

  17. toString() returns a string representing the calling object, this method returns the string form of the specified object

  18. replace() replaces the specified string with other characters

7-JavaScript function

Several ways of function declaration

        函数声明
        function 函数名(参数1,参数2,...){   //要执行的语句 } 
        函数表达式
        var func2=function(b){}//函数表达式
        var func3=function func4(c){}//命名式函数表达式
        var func5=(function(n1,n2){})();//立即执行的函数表达式
        return function(){ };//作为返回值的函数表达式
        Function构造器
        var 变量名 = new Function("参数1","参数2",...,"参数n","函数体");  
        立即执行函数
        var func5=(function(n1,n2){})();//立即执行的函数表达式 ()()

Difference between function declaration and function expression

A function declaration will hoist that function to the front (even if you write the function at the end of the code block when you write the code), making it a global function.

The function declaration needs to specify the function name, but the function expression does not need to be used as an anonymous function.

this points to the question

In the global environment, this points to window

This in normal function calls points to window, in strict mode this points to undefined, self-executing functions point to window, timer points to window

Calling this in an object points to the object that called the function

The constructor is used with new to point to the instantiated object

The arrow function does not have its own this and will inherit the this of the first normal function in the outer layer

call,apply,bind

They are all used to modify what this points to, and the first parameter of the three is the object to be pointed to by this

The difference between call and apply is that the parameter of call is a list of parameters directly put in and apply is an array

Except that bind returns a function, its parameters are the same as call, but it must be called before it is executed. The function returned by bind cannot be used as a constructor

Closure

The concept of closures, functions that can read variables inside other functions

Disadvantages of closures: Because closures will cause variables in the function to be stored in memory, the memory consumption is large, so closures cannot be abused, otherwise it will cause performance problems on web pages, and may cause memory leaks in IE. The solution is to delete all unused local variables before exiting the function.

8-JavaScript scope, mechanism

Garbage collection mechanism and memory mechanism

Garbage collection: The garbage collection mechanism is also an automatic memory management mechanism. The garbage collector will regularly find out the variables that are no longer in use, and then release the memory

Memory leak: If the memory occupied by variables that are no longer used is not cleared, it will cause memory leaks, such as closures and times timer leaks

scope

Scope is the scope in which a variable can be used, mainly divided into global scope and function scope

The global scope is the outermost scope in Js

Function scope is an independent scope created by js through functions. Functions can be nested, so scopes can also be nested

Es6 has added block-level scope (wrapped by braces, such as: if(){}, for(){}, etc.)

free variable

Variables outside the current scope are free variables. If a variable is not defined in the current scope but is used, it will go to the upper scope and search layer by layer until it is found. If the global scope does not find this variable variable will report an error. This free variable lookup process is the scope chain

A Brief Discussion on the Operating Mechanism of JavaScript

Single-threaded: A major feature of the JavaScript language is single-threaded, that is, only one thing can be done at the same time

JS event loop and execution order

js code execution will have many tasks, these tasks are divided into two categories

  • sync task
  • asynchronous task
  • Tasks can be further subdivided into microtasks and macrotasks, and the js engine will give priority to executing microtasks

Microtasks include promise callbacks, process.nextTick in node

​ Macro tasks include script script execution, setTimeout, setInterval, etc.

order of execution

  1. First of all, js runs on a single thread. When the code is executed, the execution context of different functions is pushed into the execution stack to ensure the orderly execution of the code.

  2. When executing synchronous code, if an asynchronous event is encountered, the js engine will not wait for the return result, but will suspend the event and continue to execute other tasks in the execution stack

  3. After the execution of the synchronous event is completed, the callback corresponding to the asynchronous event is added to another task queue different from the current execution stack to wait for execution.

  4. The task queue can be divided into a macro task queue and a micro task queue. When the events in the current execution stack are executed, the js engine will first judge whether there is a task in the micro task queue that can be executed. Events are pushed onto the stack for execution.

  5. When the tasks in the micro-task pair are all executed, the tasks in the macro-task pair are judged.

8-BOM Browser Object Model

JavaScript operation BOM

window : alert() , prompt() , confirm() , setInterval() , clearInterval() , setTimeout() , clearTimeout() ;

window.location.href = 'the page you want to jump to'; 2. window.open('the page you want to jump to'); 3. window.history.back(-1): return to the previous page4 , window.history.go(-1/1): return to the previous or next page 5, 5, history.go("baidu.com");

Members of the Math object

  • Math.PI pi

  • Math.floor() rounds down

  • Math.ceil() Round up

  • Math.round() rounded version to the nearest integer

  • Math.abs() absolute value

  • Math.max()/Math.min() Find the maximum and minimum values

            console.log(Math.max(2, 3, 5)) //5
    
  • Math.random() Gets a random value in the range [0,1)

The difference and mechanism between setTimeout and setInterval

setTimeout() and setInterval() are often used to handle delays and timing tasks.

The setTimeout() method is used to call a function or calculate an expression after a specified number of milliseconds, executed once

setInterval() can call a function or expression every specified number of milliseconds until clearInterval clears it

The difference between cookies, sessionStorage and localStorage

cookie: A small text data with a size of no more than 4K, generally generated by the server, and the expiration time can be set; if the time is not set, the cookie will be invalid when the browser is closed. Every time an http request is made, the header carries a cookie

localStorage: 5M or larger, permanently valid, and will always be saved when the window or browser is closed, unless it is permanently cleared manually or by js code, so it is used as persistent data and does not participate in communication with the server

sessionStorage is cleared after closing the page or browser. The size of the stored data is generally 5MB, and it is only saved in the client (ie browser), and does not participate in the communication with the server.

9-ES6 partial interview questions

ES6 new features

  1. Added block-level scope (let const)

  2. Provides syntactic sugar for defining classes (class)

  3. Added a new basic data type (Symbol)

  4. Destructuring assignment of new variables

  5. Added arrow functions

  6. Added some APIs, such as isArray / from / of methods; added methods such as entries(), keys() and values() for array instances

  7. New spread operator for objects and arrays

  8. Added modularity

  9. Added set and map data structures

  10. Added proxy constructor to generate proxy instance

  11. New generator (Generator) and traverser (iterator)

The difference and usage method between require and import

import is the grammatical standard of ES6 and is also used to load modules. The import function can read and execute a JavaScript file, and then return the code output by the export command of the modified file. Both export and export default can export constants, functions, files, modules, and export There can be multiple, export default can only have one

require defines a module: the module variable represents the current module, and its exports attribute is an external interface. The module can be exported from the module through exports, and other files load the module to actually read the modules.exports variable. They can be quantities, functions, object etc. In node, if you use exports to export, the system will help you convert it to module.exports, but the export needs to define the export name

the difference between the two

require is the modular syntax of the commonJS specification, and import is the modular syntax of the ECMAScript6 specification

require is loaded at runtime, and import is loaded at compile time

require can be written anywhere in the code, import can only be written at the top of the file and cannot be used in conditional statements or function scopes

The value exported by require through modules.exports cannot be changed, and the value exported by import through export can be changed

require exports the exports object through modules.exports, and import exports the specified output code through export

The attributes of the module are introduced only when require is running, and all performance is low. The module attributes introduced during import compilation have slightly higher performance.

arrow function

  1. Arrow functions are anonymous functions, cannot be used as constructors, and cannot use new
  2. Arrow functions do not bind arguments, instead use rest parameters to resolve
  3. The this point is different, the this of the arrow function is inherited from the this of the first ordinary function of the outer layer when it is defined
  4. Arrow functions have no prototype, and all arrow functions have no this
  5. Arrow functions cannot be used as Generator functions, and the yield keyword cannot be used
  6. Arrow function omits function, use =>, you can also omit return
  7. Arrow functions cannot change the direction of this through call(), apply(), bind()

Briefly describe the difference between var let const and usage scenarios

was

The variable declared by var has variable promotion, that is, the variable can be called before the declaration, and the value is undefined

A variable can be declared multiple times, the latter will override the former

Use var to declare a variable in a function. The variable is a local scope, and it is a global variable only in the function and outside the function.

let

variable hoisting does not exist

let is valid at the block-level scope, and the scope is curly braces

let does not allow repeated declarations in the same scope

const

Declare a read-only constant. After the declaration, the value cannot be changed, but for reference types such as objects and data, the memory address cannot be modified, and the value inside can be modified.

Others are the same as let

Notice

Try to use const when you can use const, use let in most cases, and avoid using var. The benefits of the const > let > var const declaration, one let people who read the code know that the variable cannot be modified, and the other is to prevent the variable from being accidentally modified during the code modification process and cause errors, reducing the occurrence of bugs

The difference between map and forEach

The same point is to loop through each item in the array and support 3 parameters, (item, index, arr)

forEach will not call the callback function for an empty array

The map method also does not check for empty arrays

difference

A new array returned by the map method. The elements in the array are the processed values ​​of the original array, and the original array will not be changed.

The forEach method is used to call each element of the array to pass the element to the callback function, without return, the return value is undefined

promise definition

  1. Promise is a solution for asynchronous programming. It is mainly used for asynchronous computing. It supports chain calls and can solve the problem of callback hell. It has all, reject, resolve, race and other methods on its own. There are then and catch methods on the prototype
  2. 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
  3. promise有三种状态,pending(待定)初始状态,fulfilled(实现)操作成功,rejected(被否定)操作失败
  4. promise对象状态改变,从pending变为fulfilled,或者从pending变为rejected,只有这两种状态 状态凝固就不会发生变化了
  5. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部,但是写了then 和 catch ,会被then的第二个参数 或 catch所捕获

promise的then为什么可以支持链式调用

promise 的then会返回一个新的 promise 对象,能保证 then 方 可以进行链式调用

async与await的原理

  • async与await是一种同步写法,但是是异步操作,两个必须配合一起使用

  • 函数前面的async关键字表明内部有异步操作,调用该函数时,会返回一个promise对象

  • await是运算符,用于组成表达式,

  • await 能够获取promise执行的结果 await必须和async一起使用才行,async配合await使用是一个阻塞的异步方法

  • 如果await后面不是Promise对象, 就直接返回对应的值,只能在async函数中出现, 普通函数直接使用会报错

  • await语句后的Promise对象变成reject状态时,那么整个async函数会中断,后面的程序不会继续执行

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值

常用的几种方式有

  1. 默认值
  2. 交换变量
  3. 将剩余数组赋给一个变量

element-Ui按需引入就使用了解构赋值

for…in 迭代和 for…of 有什么区别

  1. 推荐在循环对象属性的时候使用for…in,在遍历数组的时候使用for…of

            let arr = [1, 2, 3, 4, 5]
            let obj = {
                name: '张三',
                age: 20
            }
            for (k of arr) {
                console.log(k) //1,2,3,4,5
            }
    		for (i in arr) {
                console.log(i) //0,1,2,3,4,
            }
            for (v in obj) {
                console.log(v) //name,age
            }
    
  2. for in 便利的是数组的索引 而for of遍历的是数组元素值

  3. for…of 不能循环普通的对象,需要通过和 Object.keys()搭配使用

  4. The order of convenience for...in is number first, and the symbol attribute cannot be conveniently enumerated in the public

  5. From the perspective of traversing objects, for···in will traverse the key of the object, but for···of will directly report an error

generator

  • The Generator generator is also an asynchronous programming solution provided by ES6, and its grammatical behavior is completely different from traditional functions function *(){}

  • The Generator function is a state machine that encapsulates multiple internal states. In addition to the state machine, it is also a traverser object generation function.

  • Generator is executed in segments, yield (again) can be paused, and the next method can be started. Each return is the result of the expression after yield, which makes the Generator function very suitable for synchronizing asynchronous tasks

  • Generator is not designed to be asynchronous, it has other functions (object iteration, control output, deploy Interator` interface...)

  • The Generator function returns an Iterator object, so we can also traverse it through for...of. The native object does not have a traversal interface. By adding this interface to it through the Generator function, we can use for...of to traverse

Promise, Generator, async/await for comparison

  • Both promise and async/await are used to handle asynchronous operations
  • Generator is not designed for asynchronous, he has other functions (object iteration, control output, deployment interface)
  • Compared with generator, promise is more complex and less readable than async/await
  • async is essentially the syntactic sugar of generator
  • Async is more concise in use, and writing asynchronous code in a synchronous form is the ultimate solution for asynchronous programming

The execution process of the constructor to generate an instance: What does the new keyword do when using object-oriented programming?

  1. Created a new Object object
  2. Modify the pointer of the constructor this to point to the newly created Object object, and execute the constructor
  3. A proto attribute is added to the Object object , which points to the prototype attribute of the constructor
  4. Return this Object object

What are the common properties and methods of set and map data structures?

The characteristic of set data is that the data is unique

const set1 = new Set()
 
增加元素 使用 add
set2.add(4)
 
是否含有某个元素 使用 has
console.log(set2.has(2)) 
     
查看长度 使用 size
console.log(set2.size) 
 
删除元素 使用 delete
set2.delete(2)
 
size: 返回Set实例的成员总数。
add(value):添加某个值,返回 Set 结构本身。
delete(value):删除某个值。
clear():清除所有成员,没有返回值。

Set non-repeatability

传入的数组中有重复项,会自动去重
const set2 = new Set([1, 2, '123', 3, 3, '123'])
 
Set`的不重复性中,要注意`引用数据类型和NaN
两个对象都是不用的指针,所以没法去重
const set1 = new Set([1, {name: '孙志豪'}, 2, {name: '孙志豪'}])
 
如果是两个对象是同一指针,则能去重
const obj = {name: '我们一样'}
const set2 = new Set([1, obj, 2, obj])
 
NaN !== NaN,NaN是自身不等于自身的,但是在Set中他还是会被去重
const set = new Set([1, NaN, 1, NaN])

map data structure

The biggest advantage of Map over object is that the key is not limited by type

 
定义map
const map1 = new Map()
 
新增键值对 使用 set(key, value)
map1.set(true, 1)
 
判断map是否含有某个key 使用 has(key)
console.log(map1.has('哈哈')) 
 
获取map中某个key对应的value
console.log(map1.get(true)) 
 
删除map中某个键值对 使用 delete(key)
map1.delete('哈哈')
 
 
定义map,也可传入键值对数组集合
const map2 = new Map([[true, 1], [1, 2], ['哈哈', '嘻嘻嘻']])
console.log(map2) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }

proxy understanding

The Proxy object is used to create a proxy of an object, so as to realize the interception and customization of basic operations (such as attribute lookup, assignment, enumeration, function call, etc.).

Proxy can be understood as setting up a layer of "interception" before the target object. External access to the object must first pass through this layer of interception. Therefore, a mechanism is provided to filter and rewrite external access. The original meaning of the word Proxy is proxy, and it is used here to indicate that it will "proxy" certain operations, which can be translated as "agent".

The new data type symbol in s6

Symbol is added by es6, it is a basic data type, it represents a unique value, SYMBOL value is generated by SYMBOL function

Symbol cannot be used for four arithmetic operations, otherwise an error will be reported, and it can only be converted into a string by display

If you compare it with symbol, it will return false

Symbol is a primitive type of value, so the new keyword cannot be used. Symbol is not an object without an iterator interface and cannot add attribute values. It is a type similar to a string

The a in the symbol parameter represents a modification of a modifier to the currently created symbol, as a distinction, otherwise it will be confused

iterator == iteration (concept of traverser)

Iterator is such a mechanism. It is an interface that provides a unified access mechanism for various data structures. Any data structure can complete the traversal operation as long as it deploys the Iterator interface

Iterator has three functions: one is to provide a unified and convenient access interface for various data structures; the other is to enable the members of the data structure to be arranged in a certain order; the third is that ES6 creates a new traversal command for ...of cycle, the Iterator interface is mainly for consumption of for...of.

In fact, iteration == iterator has three functions:

  1. Provide a unified and convenient access interface for various data structures;

  2. Allows the members of the data structure to be arranged in a certain order;

  3. Mainly for…of consumption

Object.assign

object.assign can realize the merging of objects, and its syntax is as follows:Object.assign(target, ...sources)

Object.assign will copy the enumerable properties in the source to the target. If it has the same name as the existing attribute of target, it will be overwritten. At the same time, the subsequent source will overwrite the same name attribute of the previous source

Object.assign copies the attribute value. If the attribute value is a reference type, then what is copied is actually the reference address, and there will be a problem of reference sharing.

Object.assign can implement shallow copy

Array.from()

The Array.from() method is to convert an array-like object or traversable object into a real array.

So what is an array-like object? The so-called array-like object, the most basic requirement is an object with a length property

        let arrayLike = {
            0: 'tom', 
            1: '65',
            2: '男',
            3: ['jane','john','Mary'],
            'length': 4
        }
        let arr = Array.from(arrayLike)
        console.log(arr) // ['tom','65','男',['jane','john','Mary']]

What if the length attribute in the above code is removed? Practice has proved that the answer will be an empty array of length 0

Change the code here to have a length attribute, but the attribute name of the object is no longer a number type, but another string type, the code is as follows

        let arrayLike = {
            'name': 'tom', 
            'age': '65',
            'sex': '男',
            'friends': ['jane','john','Mary'],
            length: 4
        }
        let arr = Array.from(arrayLike)
        console.log(arr)  // [ undefined, undefined, undefined, undefined ]

It will be found that the result is an array with a length of 4 and elements of undefined

It can be seen that to convert an array-like object into a real array, the following conditions must be met:

1. This type of array object must have a length attribute, which is used to specify the length of the array. If there is no length attribute, then the converted array is an empty array.

2. The attribute name of this type of array object must be a numeric or string number

Talk about your understanding of modular development

A module is a set of methods that implement a specific function. At the beginning, js only implemented some simple functions, so there was no concept of modules, but as the program became more and more complex, the modular development of the code became more and more important.

Since functions have the characteristics of independent scope, the most original way of writing is to use functions as modules, and several functions as a module, but this method is easy to cause pollution of global variables, and there is no connection between modules

The object writing method was proposed later, by using the function as an object to realize **, ** this solves some shortcomings of directly using functions as modules, but this method will expose all module members, and external code can be modified The value of the internal property.

Several module specifications of js

There are currently four mature module loading schemes in js:

  • The first is the CommonJS solution, which imports modules through require and defines the output interface of modules through module.exports. This module loading solution is a server-side solution. It introduces modules in a synchronous manner. Because the files on the server side are stored on the local disk, the reading is very fast, so there is no problem in loading them in a synchronous manner. But if it is on the browser side, since the loading of modules uses network requests, it is more appropriate to use asynchronous loading.
  • The second is the AMD scheme. This scheme uses asynchronous loading to load modules. The loading of modules does not affect the execution of subsequent statements. All statements that depend on this module are defined in a callback function, and the callback is executed after the loading is complete. function. require.js implements the AMD specification.
  • The third is the CMD solution. Both this solution and the AMD solution are designed to solve the problem of asynchronous module loading. sea.js implements the CMD specification. The difference between it and require.js lies in the different handling of dependencies during module definition and the different handling of execution timing of dependent modules.
  • The fourth solution is the solution proposed by ES6, which uses import and export to import and export modules.

VUE interview questions

1- Core Principles

MVVM

MVVM is the abbreviation of Model-View-ViewModel, MVVM separates the view from the business logic

View: view layer, Model: data model, ViewModel is the bridge between the two to establish communication

Under the MVVM framework, there is no direct connection between View and Model, but interacts through ViewModel. The interaction between View and ViewModel and between Model and ViewModel is bidirectional, so changes in view data will be synchronized to Model, and changes in Model data will be immediately reflected on View. It can be said that both of them are updated in real time and affect each other. ViewModel connects the View layer and the Model layer through two-way data binding, and the synchronization between View and Model is completely automatic, so developers only need to pay attention to business logic, and do not need to manually manipulate DOM or data State synchronization issues, which are all managed by MVVM

The underlying implementation principle of VUE

Vue.js uses data hijacking combined with publisher-subscriber mode, hijacks the setter and getter of each property through Object.defineProperty(), publishes a message to the subscriber when the data changes, and triggers the corresponding monitoring callback. Vue is A typical MVVM framework,

Observer (data listener) : The core of the observer is to monitor data changes through object.defineProperty. This function can define setters and getters inside. Whenever the data changes, the setter will be triggered. At this time, the observer will notify the subscribers, subscribe watcher

Compile (instruction parser) : The main thing that Compile does is to parse the template instructions, replace the variables in the template with data, then initialize and render the page view, bind the node corresponding to each instruction with an update function, and add subscribers for identification data , once the data changes, receive a notification and update the view

Watcher (subscriber) : watcher subscribers serve as a communication bridge between Observer and compile, the main thing to do is

  1. Add yourself to the property subscriber when instantiating itself
  2. itself must have an update() method
  3. When the attribute change is notified by dep.notice(), it can call its own update method and trigger the callback bound in Compile

VUE template compilation principle

The template in vue cannot be parsed and rendered by the browser, because it does not belong to the browser standard and is not correct HTML syntax, so the template needs to be converted into a JavaScript function, so that the browser can execute this function and render the corresponding HTML element, you can make the view run. This conversion process becomes template compilation

The compilation process of VUE is the process of converting the template into a render function, which is divided into the following three steps

Step 1: Convert template string to element ASTS (parser)

Step 2: Mark static nodes on AST, mainly for virtual DOM rendering optimization (optimizer)

The third step: is to use element ASTS to generate the render function code string (code generator)

VUE virtual DOM, diff algorithm

Virtual DOM, in fact, replaces real DOM operations with objects, puts real DOM operations in memory, and performs virtual operations on objects in memory. When the page is opened, the browser will parse HTML elements and build a DOM tree , compare the two DOM trees, compare the difference between the two DOM trees according to the diff algorithm, and only render the difference once

(Personal understanding) Virtual DOM is not really DOM, it is a js object generated according to a template (using the CreteElement method), and then a real DOM is generated according to this js object, and a convenient tool is provided for deconstructing complex document DOM. Minimized DOM operations can quickly render and update elements efficiently, improving browser performance.

When we render the page, we will compare the new virtual dom with the old virtual dom and only render the different places, instead of re-rendering all the real dom as long as there is a change before, so the rendering efficiency is improved.

Disadvantages When rendering a large amount of DOM for the first time, due to the calculation of an additional layer of virtual DOM, it will be slower than innerHTML insertion

diff algorithm

The diff algorithm is an efficient algorithm for comparing tree nodes on the same layer. The comparison method: the overall strategy of diff is: depth-first, same-layer comparison

The diff algorithm will generate a new virtual dom according to the new data when the data changes, and compare the new virtual dom with the old virtual dom. This comparison process is the diff algorithm, which will find different places and only render different places. In general, it is to reduce DOM, redraw and reflow.

Why use virtual DOM to describe real DOM

The cost of creating a real DOM is relatively high. If you use a js object to describe a dom node, the cost is relatively low. In addition, it is a relatively large overhead for us to frequently operate dom, so it is recommended to use virtual dom to describe the real dom

Responsive principle

What is responsive, "responsive" means that when the data changes, Vue will notify the code that uses the data. For example, data is used in view rendering, and the view is automatically updated when the data changes.

Vue's responsive principle is that the core is through the get and set methods in the accessor properties in Object.definedProperty of ES5's protected objects. The properties declared in data are all added with accessor properties. When reading the data in data Automatically call the get method. When the data in data is modified, the set method is automatically called. When the data change is detected, the observer Wacher will be notified, and the observer Wacher will automatically trigger the re-render of the current component (subcomponents will not be re-rendered), and generate a new one. The virtual DOM tree, the Vue framework will traverse and compare the difference between each node in the new virtual DOM tree and the old virtual DOM tree, and record it. Finally, the loading operation will locally modify the differences of all records to the real DOM tree .


	Object.defineProperty怎么用, 三个参数?,有什么作用啊?
    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回		此对象。
     Object.defineProperty(obj, prop, {})
     obj:需要定义属性的对象
     prop:需要定义的属性
     {}:要定义或修改的属性描述符。
     value: "18",         // 设置默认值得
     enumerable: true,    //这一句控制属性可以枚举 enumerable 改为true 就可以参与遍历了,默认值false
     writable: true,      // 控制属性可以被修改   默认值false
     configurable: true,  // 控制属性可以被删除   默认值false
      get // 当有人读取 prop 的时候  get函数就会调用,并且返回就是 sss 的值
      set // 当有人修改 prop 的时候  set函数就会调用, 有个参数这个参数就是修改后的值
      
      
Object.defineProperty 能定义symbol类型吗? 
       在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定        义key为Symbol的属性的方法之一。
    
vue2和vue3的响应式原理都有什么区别呢?
vue2 用的是 Object.defindProperty 但是vue3用的是Proxy 
Object.defindProperty虽然能够实现双向绑定了,但是还是有缺点,只能对对象的属性进行数据劫持,所以会深度遍历整个对象,不管层级有多深,只要数组中嵌套有对象,就能监听到对象的数据变化无法监听到数组的变化,Proxy就没有这个问题,可以监听整个对象的数据变化,所以用vue3.0会用Proxy代替definedProperty。
上面就是一个典型的例子,当我们点击按钮想要根据数组 arr 的下标改变其元素的时候,你会发现 data 中的数据改变了,但是页面中的数据并没有改变。
         我会用  this.$set( target, key, value ) 来解决
       参数:
         {Object | Array} target
         {string | number} propertyName/index
         {any} value 
         第一参数时指定要修改的数据 (target)
         第二个参数就是你要设置数据的下标或者是属性名
         第三个参数就是现在要修改的数据 (重新赋的值)
改变/添加 对象属性的时候:this.$set(data 实例,"属性名(添加的属性名)","属性值(添加的属性值)")
改变/添加 数组属性的时候:this.\$set(data 实例,数组下标,"改变后的元素(添加的元素)")
​
原因 : vue在创建实例的时候把data深度遍历所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。让 Vue 追踪依赖,在属性被访问和修改时通知变化。所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
​
为什么要用  this.$set  呢? this.$set是干什么的?
      当你发现你给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this.$set()这个方法了,简单来说this.$set的功能就是解决这个问题的啦。官方解释:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi'),你会发现vue官网是vue.set,vue.set的用法
​
​
       
那 Vue.set 和 this.$set 有什么区别 ?
    Vue.set( ) 是将 set 函数绑定在 Vue 构造函数上,this.$set() 是将 set 函数绑定在 Vue原型上

Vue two-way data binding principle

It uses data hijacking combined with publisher-subscriber mode, hijacks the setter and getter of each property through Object.defineProperty(), publishes a message to the subscriber when the data changes, and triggers the corresponding monitoring callback to achieve data and view synchronization .

Mainly divided into four parts

  1. The observer is mainly responsible for the recursive convenience of Vue data, so that the data has get and set methods. When there is data to assign a value to an object, the setter is triggered to monitor the change of the data. (If there is any change, you can get the latest value and notify subscribers)

  2. The compile directive parser is responsible for binding data and directive parsing. Replace the variables in the template with data, then initialize and render the page view, and bind the update function to the node corresponding to each instruction. Once the data changes, receive a notification and update the view

  3. Subscriber watcher: Watcher subscribers are the communication bridge between Observer and Compile. The main thing to do is to monitor data. When the data changes, it can call its own update() method and trigger the update function bound in Compile.

  4. Implement a subscriber dep: adopt the publisher-subscriber mode to collect subscriber watchers, and manage the listener observer and subscriber watcher in a unified manner

Advantages of vue3's Proxy over vue2's defineProperty

在vue3 中
Vue3是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,因为 Proxy 是 ES6 的语法
​
Vue3.0 摒弃了 Object.defineProperty,改为基于 Proxy 的观察者机制探索。
首先说一下 Object.defineProperty 的缺点:
① Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。 this.$set()解决
② Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue2.X 里,是通过递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象才是更好的选择。


而要取代它的 Proxy 有以下两个优点
可以劫持整个对象,并返回一个新对象。有多种劫持操作(13 种)
补充:
Proxy 用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。 mdn
Proxy 是 ES6 新增的一个属性,翻译过来的意思就是代理,用在这里表示由它来“代理”某些操作。Proxy 让我们能够以简洁易懂的方式控制外部对象的访问,其功能非常类似于设计模式中的代理模式。


​
1、vue 中数组中的某个对象的属性发生变化,视图不更新如何解决?
 Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。 this.$set()解决
 问题原因:因为 vue 的检查机制在进行视图更新时无法监测 数组中的对象的某个属性值的变化。解决方案如下
方案一:利用  this.set(this.obj,key,val)
例:this.set(this.obj,‘k1’,‘v1’)
方案二:就利用 Object.assign({},this.obj)创建新对象  
如果是数组就 Object.assign([],this.obj)
如果是对象就 Object.assign({},this.obj)。

vue.js core

Flexible component application, efficient data binding

Understanding of progressive framework, understanding of vue data-driven

The meaning of progressive is: the least assertion - it is a lightweight framework that only does what it should do, and does not do what it should not do

Each framework will inevitably have its own characteristics, which will have certain requirements for users. These requirements are propositions. The strength of the proposition will affect the way it is used in business development.

The vue data here drives the view, that is, the DOM element, which refers to the understanding that the content of the DOM changes with the change of the data.

What is Vue's SSR? what is the benefit?

SSR stands for Server Side Render

Good for SEO: Because it is on the server side, the data is filled into HTML and then pushed to the browser, so it is good for SEO crawling

First screen rendering is fast

Disadvantages of SSRs:

Development conditions will be limited, and server-side rendering only supports two hooks, beforeCreate and created;

Special processing is required when some external extension libraries are required, and the server-side rendering application also needs to be in the Node.js operating environment;

More server load.

The difference between vue2.0 and vue3.0

1.性能提升

更小巧,更快速;支持摇树优化。支持 Fragments (支持多个根节点)和跨组件渲染;支持自定义渲染器。

2.API 变动

Vue2使用 选项类型API(Options API) 对比Vue3 合成型API(Composition API)

optionsApi 使用传统api中,新增一个需求,要在data,methods,computed中修改

compositionApi 我们可以更加优雅的组织我们的代码,函数,让我们的代码更加有序的组合在一起

3.重写虚拟 DOM (Virtual DOM Rewrite)

随着虚拟 DOM 重写,减少 运行时(runtime)开销。重写将包括更有效的代码来创建虚拟节点。

vue3 没有了过滤器

双向数据绑定 从 Object.defineProperty() 变成了 proxy,通过下标修改数组变化了试图数据没发生变化 this.$set() vue3不需要

双向数据绑定原理发生了改变,使用proxy替换Object.defineProerty,使用Proxy的优势:

可直接监听数组类型的数据变

监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升

可直接实现对象属性的新增/删除

setup 函数

3.0新加入了TypeScript以及PWA支持

默认使用懒加载

可以不用加上key

vue3 的watch监听可以进行终止监听

生命周期有了一定的区别 Vue2--------------vue3
beforeCreate  -> setup()    开始创建组件之前,创建的是data和method
created    -> setup()
beforeMount  -> onBeforeMount   组件挂载到节点上之前执行的函数。
mounted    -> onMounted 组件挂载完成后执行的函数
beforeUpdate  -> onBeforeUpdate 组件更新之前执行的函数。
updated    -> onUpdated 组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount    组件挂载到节点上之前执行的函数。
destroyed   -> onUnmounted  组件卸载之前执行的函数。
activated   -> onActivated  组件卸载完成后执行的函数
deactivated  -> onDeactivated

2-vue life cycle (11 extensions)

How many statement cycles? The characteristics of each life cycle, what can be done

beforeCreate() 创建前,这个时候data中的数据,还未定义,所以不能使用
created()创建后 最早开始使用 data和methods中数据的钩子函数
​
beforeMount()挂载前 指令已经解析完毕内存中已经生成dom树,但是尚未挂载到页面中去,此时页面还是旧的。
mounted()挂载后 dom已经渲染完毕,此时页面和内存中都是最新的数据,最早可以操作DOM元素钩子函数
​
 beforeUpdate()更新前 当视图层的数据发生改变会执行这个钩子 内存更新,但是DOM节点还未更新,数据没有与页面同步
 updated()更新后 数据更新完成以后触发的方法,DOM节点已经更新
​
 beforeDestroy()即将销毁 data和methods中的数据此时还是可以使用的,可以做一些释放内存的操作
 destroyed()销毁完毕  组件已经全部销毁,Vue实例已经被销毁,Vue中的任何数据都不可用
 
 其他三个:
activated  被 keep-alive 缓存的组件激活时调用。
deactivated 被 keep-alive 缓存的组件停用时调用。
errorCaptured 2.5.0+ 新增当捕获一个来自子孙组件的错误时被调用
​
Vue3.0中的生命周期做了一些改动:
beforeCreate  -> setup()    开始创建组件之前,创建的是data和method
created       -> setup()
beforeMount   -> onBeforeMount  组件挂载到节点上之前执行的函数。
mounted       -> onMounted  组件挂载完成后执行的函数
beforeUpdate  -> onBeforeUpdate 组件更新之前执行的函数。
Update        - > onUpdated组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount    组件挂载到节点上之前执行的函数。
destroyed     -> onUnmounted    组件卸载之前执行的函数。
​
​
- vue的实例加载完成是在哪个声明周期完成呢
beforeCreate
- vue的dom挂载完成是在哪个声命周期里呢
mounted
​
1、created mounted 的区别?
created 模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
​
​
2、怎么在created里面操作dom?
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
可以根据打印的顺序看到,在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作并无作用,而在created()里使用this.$nextTick()可以等待dom生成以后再来获取dom对象,而通过this.$nextTick()获取到的值为dom更新之后的值
​
 setTimeout(() => {
      console.log(this.$refs.button);
 });
 
 
3、那 setTimeout this.$nextTick 什么区别呢?
setTimeout 将同步转换为异步 this.$nextTick 
​
 this.$nextTick 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,
​
4、this.$nextTick()是宏任务还是微任务啊? 
 优先是Promise.then方法,是个微任务,这样可以避免多一次队列,进而少一次UI渲染,节省性能
​
​
5、a页面跳转到b页面周期执行
页面a----beforeCreate undefined
页面a----created 1
页面a----beforeMount 1
页面a----mounted 1
页面b----beforeCreate undefined
页面b----created 1
页面b----beforeMount 1
页面a----beforeDestroy 1
页面a----destroyed 1
页面b----mounted 1
​
​
6、组件 和 页面周期 的执行顺序
- 页面beforeCreate undefined
- 页面created 1
- 页面beforeMount 1
- 组件beforeCreate undefined
- 组件created 5555
- 组件beforeMount 5555
- 组件mounted 5555
- 页面mounted 1
​
7、父子组件生命周期执行顺序
加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
代码更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
代码销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
代码常用钩子简易版
父create->子created->子mounted->父mounted
​
​
8、补充单一组件钩子执行顺序
​
activated, deactivated 是组件keep-alive时独有的钩子
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
errorCaptured
​
​
watch
仅仅是数据发生改变的时候会侦听到;
只是会检测到你写在watch里的那些属性,没写的就不会触发。
​
updated
执行到它的时候时候是数据发生变化且界面更新完毕;
不能监听到路由数据(例如网址中的参数);
所有的数据发生变化都会调用(消耗性能);
每次触发的代码都是同一个
​
computed
1、监控自己定义的变量,不用再data里面声明,函数名就是变量名
2、适合多个变量或对象进行处理后返回一个值(结果)。若这多个变量发生只要有一个发生变化,结果都会变化。
3、计算的结果具有缓存,依赖响应式属性变化,响应式属性没有变化,直接从缓存中读取结果。
4、在内部函数调用的时候不用加()。
5、必须用return返回
6、不要在computed 中对data中的数据进行赋值操作,这会形成一个死循环。
​
methods不会被缓存:方法每次都会去重新计算结果。methods 方法表示一个具体的操作,主要书写业务逻辑;
使用 methods 方法编写的逻辑运算,在调用时 add() 一定要加“()”,methods 里面写的多位方法,调用方法一定要有()。methods方法页面刚加载时调用一次,以后只有被调用的时候才会被调用。我们在长度框和宽度框的值输入完以后,点击“+” methods 方法调用一次。这里很明显我们采用 methods 会更节省资源。
​
​
使用场景?
​
watch:
1、watch 函数是不需要调用的。
2、重点在于监控,监控数据发生变化的时候,执行回调函数操作。
3、当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch
4、函数名就是你要监听的数据名字
5、监控一些input框值的特殊处理,适合一个数据影响多个数据。
6、数据变化时,执行一些异步操作,或开销比较大的操作
​
computed:
在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式
一个需要的结果受多个数据影响的时候,比如购物车结算金额(受到很多处的价格结算)。
操作某个属性,执行一些复杂的逻辑,并在多处使用这个结果。
内部函数中多处要使用到这个结果的。
1、监控自己定义的变量,不用再data里面声明,函数名就是变量名
2、适合多个变量或对象进行处理后返回一个值(结果)。若这多个变量发生只要有一个发生变化,结果都会变化。
3、计算的结果具有缓存,依赖响应式属性变化,响应式属性没有变化,直接从缓存中读取结果。
4、在内部函数调用的时候不用加()。
5、必须用return返回
6、不要在computed 中对data中的数据进行赋值操作,这会形成一个死循环。

Generally in which life cycle to request asynchronous data

It can be called in created, beforeMount, and mounted in the hook function, because in these three hook functions, data has already been created, and the data returned by the server can be assigned.

best in created

Can get server data faster, reduce page loading time, and better user experience;

SSR does not support beforeMount and mounted hook functions, and putting them in created will help consistency.

mounted can be used when the dom needs to be manipulated after the data is requested

The difference between methods, computed and watch in vue

Computed is a computed attribute in Vue, which is cacheable and will be called again when its dependent value changes.

methods are not cached, as long as they are called, they will be executed, and are generally used in conjunction with events

Watch has no caching to listen to the attribute value in data, and it will be executed as long as the attribute value changes. You can use its characteristics to do some asynchronous operations.

What is the difference between created and mounted?

created: Called before dom rendering, that is, usually initializes some attribute values

mounted: Called after dom rendering, usually after the initialization page is completed, and then perform some required operations on the dom node of html

How lifecycle hooks are implemented

The core implementation of Vue's life cycle hook is to use the publish and subscribe mode to first subscribe the life cycle hook passed in by the user (internal storage is in the form of an array), and then execute the corresponding hook method (publish) once in the process of creating a component instance

3-VUEX Frequently Asked Questions

vuex strict mode

开启严格模式,仅需在创建 store 的时候传入 strict: true:
 
const store = new Vuex.Store({
  // ...
  strict: true
})
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

what is vuex,

Vuex is a state management tool. The so-called state is data. The centralized storage is used to manage the state of all components to solve the problem of data sharing in medium and large projects. Vuex can save data locally, the data is responsive, and can keep data pages shared, improving development efficiency

benefit

Can centrally manage shared data in vuex, easy for development and later maintenance Can do state management, use localstorage to save information, and data is always stored in the user's client The data stored in vuex is responsive and can keep data in real time Synchronization with the page can efficiently realize data sharing between components and improve development efficiency

vuex-core

  1. state: the basic data of vuex, the data source storage location, used to define shared data
  2. getter: Data derived from basic data, equivalent to the computed property of state
  3. mutation: The method for submitting updated data, the only method that can operate the data in the state, must be synchronous. The first parameter is state, and the second parameter is the data passed by commit
  4. Action: used for asynchronous operations, generally used to send requests, write functions in the action, and then dispatch calls in the page, and then call the mutation through commit in the action, and manipulate the state through the mutation
  5. modules, modular vuex, allows each module to have its own state, mutation, action, getters, making the structure clear and easy to manage

vuex operating mechanism

Operating mechanism: Vuex provides data (state) to drive the view (here refers to the Vue component), the view dispatches Action through Dispatch, and some asynchronous operations can be further performed in the Action (such as requesting backend interface data through ajax), and then Submit to Mutations through Commit, and Mutations will finally change the state. So why go through Mutations? This is because we need to record data changes in the Vue debugging tool (Devtools), so that further debugging can be performed through plug-ins. Therefore, there can only be purely synchronous operations in Mutations. If there are asynchronous operations, then they need to be processed in Actions. If there is no asynchronous operation, then the Commit operation Mutations can be performed directly by the component.

Advanced usage helper functions (mapState, mapActions, mapMutations, mapGetters)

mapState,mapActions,mapMutations,mapGetters

Auxiliary functions can map data and methods in vuex to vue components. To achieve the purpose of simplifying the operation

how to use:

Import { mapActions, mapGetters, mapMutations, mapState } from ‘vuex’

computed(){ ...mapState(['data name'])}

How to solve Vuex page refresh data loss

Need to do vuex data persistence, generally use a local storage solution to save data, you can design your own storage solution or use a third-party plug-in

It is recommended to use the vuex-persist plugin, which is a plugin for Vuex persistent storage. You don't need to manually access storage, but directly save the state to cookie or localStorage

Why does Vuex divide modules and add namespaces

Module: Due to the use of a single state tree, all the state of the application will be concentrated into a relatively large object. When the application becomes very complex, the store object can become quite bloated. To solve the above problems, Vuex allows us to split the store into modules. Each module has its own state, mutation, action, getter, and even nested submodules. Easy to manage

4-routing vue-router

vue-router (routing principle? routing guard?)

Due to the lack of routing support for Vue during development, the official vue-router plug-in was added. Vue's single-page application is based on routing and components. Routing is used to set access paths and map paths and components. Traditional page applications use some hyperlinks to switch and jump pages. In the vue-router single-page application, it is the switching between paths, which is actually the switching of components. Routing is the path manager for SPA (Single Page Application). In layman's terms, vue-router is the link path management system of our WebApp.

Principle In the general source code, window.history and location.hash are used. Principle: By changing the browser address URL, without re-requesting the page, update the page view, through the location object in the BOM, where the location. The hash stores the address of the route, the address that can be assigned to change its URL. And this will trigger the hashchange event, and listen to the hash value through window.addEventListener and then match the corresponding route to render the component of the page. One is # hash, add # to the address to deceive the browser, the change of the address is due to In-page navigation 2. One is the history of h5, which uses the Hash of the URL to simulate a complete URL

Routing has two modes: hash and history mode, the default is hash

The implementation principle of vue-router (core): update the view without re-requesting the page.

1. hash——that is, the # symbol in the URL in the address bar. Its characteristic is that although the hash appears in the URL, it will not be included in the HTTP request and has no effect on the backend at all, so changing the hash will not reload the page .

2. History - using the HTML5 History api, there is no # in the browser, there are browser compatibility issues

3. In history mode, the front-end URL must be consistent with the URL that actually initiates the request to the back-end, otherwise a 404 error will be returned.

Global Route Guard

router.beforeEach 全局前置守卫 进入路由之前

router.beforeResolve 全局解析守卫,在beforeRouteEnter调用之后调用

同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用

router.afterEach 全局后置钩子 进入路由之后

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

Component-level routing guards are placed in the component to be guarded, at the same level as data and methods

  • BeforeRouteEnter enters the route, the instance has not been created at this time, and the zhis cannot be obtained
  • beforeRouteUpdate (2.2) when routing reuses the same component
  • beforeRouteLeave leaves the current route, which can be used to save data, or initialize data, or turn off timers, etc.
//在组件内部进行配置,这里的函数用法也是和beforeEach一毛一样
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

The exclusive guard of a single routing rule is written in the routing configuration. Only when this path is accessed can the hook function be triggered

beforeEnter:(to,from,next)=>{ alert("欢迎来到我的界面") next() }

parameter

  • to: Route: The target routing object to be entered
  • from: Route: The route object that the current navigation is leaving
  • next: Function: Be sure to call this method to resolve this hook. The execution effect depends on nextthe calling parameters of the method.

Which attribute to use for redirection ?

redirect:"/path"

There are several jumping methods for vue routing

1、<router-link to="需要跳转到页面的路径"> 2、this.$router.push()跳转到指定的url,并在history中添加记录,点击回退返回到上一个页面

3、this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面

4、this.$touter.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数

What is the difference between router.push, router.replace, router.go, and router.back?

router.push:跳转,并向history栈中加一个记录,可以后退到上一个页面

router.replace:跳转,不会向history栈中加一个记录,不可以后退到上一个页面

router.go:传正数向前跳转,传负数向后跳转

router.back 返回到上一级页面

How to implement vue routing parameters, query and params

Mainly through query and params to achieve

(1) query can use name and path but params can only use name

(2) It will not be saved after refreshing with params, but it can be saved after refreshing with query.

(3) Params will not be displayed in the address bar, but query will be displayed

(4) Params can be used with dynamic routing, query cannot

(5) to=”/goods?id=1001”this. Then receive it through $route.query.id on the receiving page

The difference between routing object route and router

route is a "routing information object", including routing information parameters such as path, params, hash, query, fullPath, matched, and name.

router is a "routing instance object", including routing jump methods (push, go), hook functions, etc.

What is the execution order of the vue-router routing hook function?

一、打开页面的任意一个页面,没有发生导航切换。
全局前置守卫beforeEach (路由器实例内的前置守卫)
路由独享守卫beforeEnter(激活的路由)
组件内守卫beforeRouteEnter(渲染的组件)
全局解析守卫beforeResolve(路由器实例内的解析守卫)
全局后置钩子afterEach(路由器实例内的后置钩子)

二、如果是有导航切换的(从一个组件切换到另外一个组件)
组件内守卫beforeRouteLeave(即将离开的组件)
全局前置守卫beforeEach (路由器实例内的前置守卫)
组件内守卫beforeRouteEnter(渲染的组件)
全局解析守卫beforeResolve(路由器实例内的解析守卫)
全局后置钩子afterEach(路由器实例内的后置钩子)


完整的导航解析流程
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

dynamic routing

Dynamic routing means that the router can automatically build its own routing table, which can be adjusted in real time according to changes in actual conditions. Use the beginning, followed by the value is uncertain. This value is the parameter we want to pass. Dynamic routing matching is essentially passing parameters through url.

    比如在写一个商品详情页面的时候,我们的页面结构都一样,只是渲染的数据不同而已,这时候就可以根据商品的不同id去设置动态路由,只需要写一个组件,就可以把每个商品的商品详情映射到同一个组件上去。
    { 
        path: '/Jqxq/:id', // 路由配置拼接
        name: 'Jqxq',
        component: Jqxq
    }
    跳转 this.$router.push('/Jqxq/'+ item.id)
    接收  : this.$route.params.id

nested routes

In a vue project, the interface is usually composed of multiple nested components. It must be clear that one corresponding display is a component. Therefore, there are two key points to implement nested routing: Define sub-routes in the routing object and use children to implement nesting Sets the usage inside the routing component.

Routing configuration and parameters

export default new Router({
    mode: 'history', //路由模式,取值为history与hash
    base: '/', //打包路径,默认为/,可以修改
    routes: [
    {
        path: string, //路径
        ccomponent: Component; //页面组件
        name: string; // 命名路由-路由名称
        components: { [name: string]: Component }; // 命名视图组件
        redirect: string | Location | Function; // 重定向
        props: boolean | string | Function; // 路由组件传递参数
        alias: string | Array<string>; // 路由别名
        children: Array<RouteConfig>; // 嵌套子路由
        // 路由单独钩子
        beforeEnter?: (to: Route, from: Route, next: Function) => void; 
        meta: any; // 自定义标签属性,比如:是否需要登录
        icon: any; // 图标
        // 2.6.0+
        caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false)
        pathToRegexpOptions: Object; // 编译正则的选项
    }
    ]
})

How to define the dynamic routing of vue-router? How to get the passed value

In the index.js file under the router directory, add /:id to the path attribute, and use the params.id of the route object to get it

Routing lazy loading

Reasons for use: In a single-page application, if there is no application lazy loading, the file packaged by webpack will be abnormally large, resulting in too much content to be loaded when entering the home page, and the delay is too long, which is not conducive to user experience. The use of lazy loading can divide the page and load the page when needed, which can effectively share the loading pressure of the home page and reduce the loading time of the home page Principle: vue asynchronous component technology: asynchronous loading, vue-router configuration routing, using vue Asynchronous component technology realizes on-demand loading.

{ path: '/home', component: () => import('@/views/home/home.vue') } // lazy loading

Can you talk about the implementation principle of the commonly used routing mode in vue-router?

The value of hash mode
location.hash is actually the thing after # in the URL. Its characteristic is that although the hash appears in the URL, it will not be included in the HTTP request and has no effect on the backend at all, so changing the hash will not reload page.

You can add listener events for hash changes
window.addEventListener(“hashchange”, funcRef, false);

Every time you change the hash (window.location.hash), a record will be added in the browser's access history. Using the above characteristics of hash, you can realize the function of "updating the view without re-requesting the page" in the front-end routing Features:
Compatible Sexy but ugly

The history mode
takes advantage of the new pushState() and replaceState() methods in the HTML5 History Interface.
These two methods are applied to the history record station of the browser. Based on the existing back, forward and go, they provide the function of modifying the history record. These two methods have a common feature: when they are called to modify the browser history stack, although the current URL has changed, the browser will not refresh the page, which is the front-end route of the single-page application "update the view but do not re-request page" provides the basis.

5-Common commands

Vue common modification and common instructions

修饰符
.stop  阻止事件冒泡
.cpture 设置事件捕获
.self  只有当事件作用在元素本身才会触发
.prevent 阻止默认事件,比如超链接跳转
.once 事件只能触发一次
.native 触发js原生的事件
.number 把文本框的内容转换为数字
.trim  去除文本框左右空格
常见指令
⑴v-bind:给元素绑定属性
⑵v-on:给元素绑定事件
⑶v-html:给元素绑定数据,且该指令可以解析 html 标签
⑷v-text:给元素绑定数据,不解析标签
⑸v-model:数据双向绑定
⑹v-for:遍历数组
⑺v-if:条件渲染指令,动态在 DOM 内添加或删除 DOM 元素
⑻v-else:条件渲染指令,必须跟 v-if 成对使用
⑼v-else-if:判断多层条件,必须跟 v-if 成对使用
⑽v-cloak:解决插值闪烁问题
⑾v-once:只渲染元素或组件一次
⑿v-pre:跳过这个元素以及子元素的编译过程,以此来加快整个项目的编译速度
⒀v-show:条件渲染指令,将不符合条件的数据隐藏(display:none)

v-if and v-for priority

v-for is preferred over v-if. If you need to traverse the entire array every time, it will affect the speed, especially when it needs to render a small part.

The role of key in vue

"key value: used to manage reusable elements. Because Vue renders elements as efficiently as possible, it usually reuses existing elements instead of rendering from scratch. This makes Vue very fast, but it's not always It meets the actual needs. In version 2.2.0+, when using v-for in components, key is required."

The key is the unique id for each vnode, and it is also an optimization strategy for diff. According to the key, the corresponding vnode node can be found more accurately and faster, and it is more efficient to compare whether each node in the virtual DOM is the same node, the same Just reuse, if not the same, delete the old one and create a new one

key use index or id

When Vue.js uses v-for to update the list of rendered elements, it uses the "in-place reuse" strategy by default. If the order of the data items is changed, Vue will not move the DOM elements to match the order of the data items, but simply reuse each element here, and make sure it displays each element that has been rendered at a specific index. The role of key is mainly to update the virtual DOM efficiently.

Example: Add to write a list with checkboxes

Select the check box of the first node, click delete, this is how it works in vue, the new data after deletion will be compared at this time, the label of the first node is the same, but the value is different, and the original position will be reused The label will not be deleted or created. The check box is selected in the first node. When we see that the first node seems to be deleted, but when we click to see the check box, it is still selected in the first node. If the first node is deleted directly, the check box will not be selected.

Vue initialization page flickering problem.

To solve the flickering problem of interpolation expressions, you need to set the style [v-clock]{display:none} in the style

The difference and usage scenarios of v-if and v-show?

v-if dynamically creates or destroys elements, it is displayed when it is true, and it is not displayed when it is false. To use v-else, it must be next to v-if

v-show is to control the display or hiding of elements, and we will see display: block, none on our label

v-if has higher switching consumption, and v-show has higher initialization rendering consumption. It is generally recommended to use v-show when switching frequently. When we have more judgment branches, and when rendering for the first time use v-if

custom directives, custom filters

In addition to the specification that comes with vue, if we need to perform low-level operations on dom, we use custom instructions here, which are divided into

Global: vue.directive: {"", {}} Local: directives: {directive name: {hook function}}

  1. bind: Called only once, when the directive is bound to the element for the first time. One-time initialization settings can be performed here.

  2. inserted: Called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but not necessarily inserted into the document).

  3. update: Called when the VNode of the component is updated, but it may happen before the update of its child VNode. The value of the directive may or may not have changed. But you can ignore unnecessary template updates by comparing the values ​​before and after the update (see below for detailed hook function parameters).

  4. componentUpdated: Called after the VNode of the component where the command is located and its child VNodes are all updated.

  5. unbind: Called only once, when the instruction is unbound from the element.

parameter

el: the element to which the directive is bound

binding: an object contains,

name: The command name, excluding the v- prefix.

value: the binding value of the directive

Principle of custom instruction

1. When generating the ast syntax tree, encountering instructions will add the directives attribute to the current element

2. Generate instruction code through genDirectives

3. Extract the hook of the instruction into cbs before patch, and call the corresponding hook during the patch process

4. When the execution instruction corresponds to the hook function, call the method defined by the corresponding instruction

6- Option objects and common apis

filter

The filter is to further screen the data to be displayed, and then display that the filter does not change the original data, but only generates new data based on the original data

global:

Vue.filter('filter name', funciton(val){})

Local filter, defined on the filters property inside the component. It can only be used inside this component.

filters: {filter name: funciton (parameter) {//logic code}}

Use: filter time, filter money

mixin

Mixins allow us to write pluggable and reusable functionality for Vue components. When the mixin project becomes complex, mixin will be used if there is repeated logic between multiple components

If you want to reuse a set of component options between multiple components, such as lifecycle hooks, methods, etc., you can write it as a mixin and simply reference it in the component.

Then merge the contents of the mixin into the component. If you define a lifecycle hook in a mixin, it will be executed optimized for the component's own hook.

Mixin and page execution order issues in vue.js

The code in the mixin is executed first, and the code in the single file is executed later.

page's beforeCreate --> mixin's beforeCreate --> page's created --> mixin's created --> page's beforeMount --> mixin's beforeMount --> page's mounted --> mixin's mounted

nextTick usage scenarios and principles

Delayed callback to execute after the next DOM update cycle ends. Use this method immediately after modifying the data to get the updated DOM. The usage scenario is: you can get the dom node in the created hook function

The callback in nextTick is a deferred callback that executes 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 call the asynchronous method to execute the method wrapped by nextTick in a microtask-first manner

The difference between vue's delete array and native delete array delete

delete array

  1. delete just changes the value of the array element to empty/undefined, the key of the element remains unchanged, and the length of the array remains unchanged.
  2. Vue.delete directly deletes the array, changing the key value and length of the array.

delete object

The two are the same, and the key name (attribute/field) and key value will be deleted.

The function and principle of Vue.extend

Official explanation: Vue.extend uses the base Vue constructor to create a "subclass". The argument is an object containing options for the component.

In fact, 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 subclass of Vue and use mergeOptions to merge the options of the incoming component and the options of the parent class. Basic Usage

<div id="mount-point"></div>
// 创建构造器
/* Vue.extend( options )
  参数:{Object} options
  用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象;
       data 选项是特例,需要注意: 在 Vue.extend() 中它必须是函数;*/
var Profile = Vue.extend({
  template: '<p>{
   
   {firstName}} {
   
   {lastName}} aka {
   
   {alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
​
// 结果如下:
<p>Walter White aka Heisenberg</p>
​
/*
可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过 new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount(’#mount-point’) 来挂载到指定的元素上。
*/
​

7- Component module section (slot, single page, communication)

Vue father and son, son father, brother communication

How does the parent pass the child

(1) Bind a property on the child component tag of the parent component, and mount the variable to be transmitted (2) Accept data through props in the child component. Props can be an array or an object, and the received data can be used directly props: ["property name"] props: {property name: data type}

how the child passes the parent

(1) Customize an event on the child component label of the parent component, and then call the required method (2) Trigger the event defined in the parent component through this.$emit("event") in the method of the child component, Data is passed in the form of parameters

How Sibling Components Communicate

(1) Find the min.js file and mount a public bus V ue . prototype . bus Vue.prototype for vue.b u s V u e . p r o t o t y p e . bus = new Vue() (2) The party that transmits data uses this.bus . bus.b u s . emit('event name', 'transmitted data') (3) use Bus.$on("event name",(data)=>{data is the received data}) on the side receiving data

props validation, and default values

props: It will receive different data types, the writing method of setting default values ​​for commonly used data types, Number, String, Boolean, Array, Function, Object

All props form a single downward binding between their parent and child props: updates from the parent prop flow to the child component, but not the other way around. This prevents child components from accidentally changing the state of the parent component, making your application's data flow difficult to understand. If the value passed by the prop is directly modified in the subcomponent, Vue will issue a warning.

What is the effect of writing the name option in the component

① When the project uses keep-alive, it can be used with the name of the component for cache filtering. ② DOM needs to call its own name when it is a recursive component ③ The component name displayed in the vue-devtools debugging tool is determined by the component name in vue

custom components

Create a new component in the component in vue, define the view layer,

The development in Vue is all developed with the idea of ​​componentization. The way of component encapsulation can improve our development efficiency. Split each module of a single page into a component.

The way of component encapsulation solves the problems of our traditional projects, such as low development efficiency, difficult maintenance, and low reusability.

Use: For example, to encapsulate a swiper, first we need to define a props to accept the passed data, write the logic of the response, and import it into the page to register as a label.

keep-alive function

keep-alive is a built-in component provided by Vue, which caches inactive component instances instead of destroying them. It is used as a label and wrapped outside the component that needs to be cached

During the component switching process, the switched components are kept in memory to prevent repeated rendering of the DOM, reduce loading time and performance consumption, and improve user experience

Function: For example, when the list page enters the details, we want to save the scrolling position of the list, so we can use keep-alive to save the scrolling position of the list page.

After the component uses keep-alive, two new life cycles will be added: actived() and deactived()

activated (used when the component is activated) and deactivated (called when the group price leaves)

There are two parameters: Allows the component to be cached conditionally.

include - the wrapped component name will be cached

The component names wrapped by exclude will not be cached

Will keep-alive cache beforeDestroy still execute?

First of all, the answer is no, to be precise, it will not be called directly. By default, that is, keep-alive is not set. When leaving the current route, it will directly call beforeDestroy and destroyed to destroy. When the component is set to keep-alive, it will not directly call this destruction cycle function, but will add two new ones to the life cycle function, activated and deactivated; when exiting, the deactivated function will be executed

Why is the data in the VUE component a function

Object is a reference data type. If it is not returned by function, the data of each component is the same address in memory. If one data is changed, the other is also changed, which causes data pollution . If data is a function, the data of each instance is in the closure, so it will not affect each

Component Features and Benefits, Basic Composition of Components

(1) 特性:重用性、可指定性、互操作性、高内聚性、低耦合度

(2) 好处:组件可以扩展HTML元素、封装可重用代码

template 结构(html代码)

script行为

style样式

什么是slot?什么是命名slot?slot怎么使用?

插槽就是父组件往子组件中插入一些内容。

有三种方式,默认插槽,具名插槽,作用域插槽

默认插槽就是把父组件中的数据,显示在子组件中,子组件通过一个slot插槽标签显示父组件中的数据

具名插槽是在父组件中通过slot属性,给插槽命名,在子组件中通过slot标签,根据定义好的名字填充到对应的位置。这样就可以指定多个可区分的slot,在使用组件时灵活地进行插值。

作用域插槽是带数据的插槽,子组件提供给父组件的参数,父组件根据子组件传过来的插槽数据来进行不同的展现和填充内容。在标签中通过v-slot=""要穿过来的数据“来接受数据。

scoped 原理及穿透方法

vue 中的 scoped 通过在 DOM 结构以及 css 样式上加唯一不重复的标记:data-v-hash 的方式,以保证唯一(通过 PostCSS 转译),达到样式私有模块化的目的。

scoped 的 3 条渲染规则: ① 给 HTML 的 DOM 节点加一个不重复的 data 属性,来表示它的唯一性; ② 在每句 css 选择器末尾(编译后的生成的 css 语句)加一个当前组件的 data 属性选择器来私有化样式; ③ 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上 ddan 当前组件的 data 属性

在做项目中,会遇到这么一个问题,即:引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。那么有哪些解决办法呢?
①不使用scopeds省略(不推荐);
② 在模板中使用两次style标签。
③scoped穿透:/deep/ >>>

函数式组件使用场景和原理

函数式组件与普通组件的区别
​
1.函数式组件需要在声明组件是指定 functional:true
2.不需要实例化,所以没有this,this通过render函数的第二个参数context来代替
3.没有生命周期钩子函数,不能使用计算属性,watch
4.不能通过$emit 对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件
5.因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement
6.函数式组件的props可以不用显示声明,所以没有在props里面声明的属性都会被自动隐式解析为prop,而普通组件所有未声明的属性都解析到$attrs里面,并自动挂载到组件根元素上面(可以通过inheritAttrs属性禁止)
​
​
优点 1.由于函数式组件不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件 2.函数式组件结构比较简单,代码结构更清晰
使用场景:
一个简单的展示组件,作为容器组件使用 比如 router-view 就是一个函数式组件
“高阶组件”——用于接收一个组件作为参数,返回一个被包装过的组件

8-VUE项目中的问题

单页面应用和多页面应用的优缺点

单页面:只有一个html页面,跳转方式是组件之间的切换

优点:跳转流畅、组件化开发、组件可复用、开发便捷

缺点:首屏加载过慢

多页面:有多个页面,跳转方式是页面之间的跳转

优点:首屏加载块

缺点:跳转速度慢

口述axios封装

First of all, we need to install axios. Generally, I will create a network folder in the src directory of the project as our network request module, and then create a http.js, an api.js file and a requests.js in it.

The http.js file is used to encapsulate our axios basUrl Tiemout,

api.js is used to manage our interface url in a unified way,

Add request interception and response interception in request.js. In the request interception, the token field will be added to the request header, and the loading animation will be turned on. In the response interception, you can close some loading animations, and do some operations to check whether the token is valid or expired according to the status code returned by the backend.

The next thing is to do some encapsulation of the api interface performed by axios. Here I use async and await to encapsulate the request interface function, so that the asynchronous operation can be synchronized, the code is more friendly, and the callback area is avoided.

How to solve cross domain in vue

Implement cross-domain in vue development: find the vue.config.js file in the root directory of the vue project (create it yourself if there is no such file), and set cross-domain in the proxy

 
devServer: {
    proxy: {  //配置跨域
      '/api': {
        target: 'http://121.121.67.254:8185/',  //这里后台的地址模拟的;应该填写你们真实的后台接口
        changOrigin: true,  //允许跨域
        pathRewrite: {
          /* 重写路径,当我们在浏览器中看到请求的地址为:http://localhost:8080/api/core/getData/userInfo 时
            实际上访问的地址是:http://121.121.67.254:8185/core/getData/userInfo,因为重写了 /api
           */
          '^/api': '' 
        }
      },
    }
  },

The difference between assets and static?

The files in assets will be packaged and recompiled by webpack. It is recommended to store js and other files that need to be packaged and compiled in assets.

Files in static will not be packaged and compiled. The files in static are just copied once. It is recommended to put some external third-party files in static, put your own in assets, and put others in static. (Pictures are recommended to be placed in static)

After the value of a property in Vue data changes, will the view re-render immediately and synchronously?

Re-renders are not performed immediately and synchronously. Vue's implementation of responsiveness is not to change the DOM immediately after the data changes, but to update the DOM according to a certain strategy. Vue executes asynchronously when updating the DOM. As long as data changes are detected, Vue will open a queue and buffer all data changes that occur in the same event loop.

If the same watcher is triggered multiple times, it will only be pushed into the queue once. This deduplication while buffering is very important to avoid unnecessary calculations and DOM manipulations. Then, on the next event loop tick, Vue flushes the queue and performs the actual (deduplicated) work.

multiple environment variables

The first is to create .env.* (configuration file) files in the root directory, development local development environment configuration, staging test environment configuration, production official environment configuration (production environment). Because I didn't define many variables in the file I created, but only defined the basic env, so I need to create a config folder in the src directory and create corresponding environment variable files to manage different environments. The corresponding file is created in config for the convenience of later modification, without restarting the project, which is in line with development habits. After that, according to the required environment, it can be imported in the encapsulated axios by deconstructing and assigning, and it can be used in the baseURL.

element-ui and vant-ui are introduced on demand

First install the plug-in imported on demand, add the configuration imported on demand in babel.config.js, create a plugin folder, define a js file to store the code imported on demand, and then first in the built js file Import vue, then import the required vant-ui plug-in, and inject it globally through vue.use(). Modification style can penetrate /deep/ with style

What problem does Vue solve

① Virtual dom: DOM operation consumes a lot of performance. The native dom operation node is no longer used, which greatly liberates dom operation, but the specific operation is still dom, but in a different way. A lot of instructions are provided. Of course, custom instructions are used when low-level operations on dom are required.

② Separation of view, data, and structure: Make data changes easier, and only need to operate data to complete related operations.

③ Componentization: Split various modules in a single-page application into individual components, which is convenient for development and later maintenance

Features of Vue.js

Concise: The page is composed of HTML template + Json data + Vue instance Data-driven: Automatically calculate attributes and track dependent template expressions

Componentization: Use reusable and decoupled components to construct pages Lightweight: Small amount of code, no need to rely on other libraries Fast: Accurate and effective batch DOM update Template friendly: Can be installed through npm, bower, etc., easy to integrate Vue's core library only focuses on the view layer and is very easy to learn

Please tell me the usage of each folder and file in the src directory in the vue.cli project

The assets folder is for static resources;

components is to place components;

router is to define routing-related configuration;

view view;

app.vue is an application main component;

main.js is the entry file

Describe the vue process from initializing the page –> modifying data –> refreshing the page UI?

当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setterd 的形式,实现数据劫持;另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新视图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify( ),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。

How does Vue reset data

Using Object.assign(), vm.data can get the data in the current state,

Object.assign(this. d a t a , t h i s . data, this. data,this.options.data())

Judgment of vue-router login authority

The login permission judgment of vue-router is mainly carried out in the global hook function. In the defined route in the router.js file, we add the meta attribute to the page that requires login permission, and the value is in the form of an object, and then in the object Customize a property in , and the property value is a Boolean value. At this time, judge in the global hook function of the main.js file. If the custom property value of the page that needs to be jumped is true, then it will be judged whether it is logged in or not. If there is no login, tell the user to log in, if there is a login, then perform a page jump.

How to solve the vue first screen loading is too slow?

① Place the infrequently changed library in index.html, import it through cdn, then find the build/webpack.base.conf.js file, and add the following code in module.exports = { }:

externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
}

②Lazy loading of vue routes, lazy loading of pictures, using asynchronous components, loading on demand

③ Do not generate a map file, find the config/index.js file, and modify it to productionSourceMap: false

④ Try not to introduce the vue component globally

⑤ Use a lighter tool library

⑥ Turn on gzip compression: This optimization has two aspects. The front end packs the files into .gz files, and then allows the browser to directly parse the .gz files through the configuration of nginx.

⑦ Do server-side rendering on the homepage alone: ​​If the homepage really has a bottleneck, you can consider using node to do server-side rendering alone, and the following subpages still use spa single-page interaction. It is not recommended to use the nuxt.js server-side rendering solution directly, because this will increase the learning cost, and secondly, the maintenance cost of the server will also increase. Sometimes there is no problem in the local test, but there is a problem in running on the server. Attention, it is better to maximize the use of static pages.

What is the difference between Vue and JQuery? Why give up JQuery and use Vue?

jQuery directly manipulates the DOM, Vue does not directly manipulate the DOM, Vue's data and views are separated, Vue only needs to manipulate the data, it is a framework

jQuery's behavior of manipulating DOM is frequent, and Vue uses the technology of virtual DOM to greatly improve the performance when updating DOM. It is a library

Direct manipulation of DOM is not advocated in Vue, developers only need to focus most of their energy on the data level

Vue integrates some libraries, which greatly improves development efficiency, such as Route, Vuex, etc.

What Vue performance optimizations have you done?

Minimize the data in data as much as possible, the data in data will add getters and setters, and will collect corresponding watchers. v-if and v-for cannot be used together v-if and v-show to distinguish usage scenarios. v-for traversal must add key, key The best is the id value, and avoid using v-if at the same time. If you need to use v-for to bind events to each element, use event proxy

SPA pages use keep-alive cache components In more cases, use v-if instead of v-show Use routing lazy loading and asynchronous components

Anti-shake and throttling third-party modules are imported on demand

The long list is scrolled to the visible area and dynamically loaded, and the data that does not need to be responsive should not be placed in the data (you can freeze the data with Object.freeze())

Image lazy loading

SEO optimized pre-rendering

Server-side rendering SSR packaging optimization,

Compressed code Tree Shaking/Scope Hoisting

Use CDN to load third-party modules Multi-threaded packaging happypack splitChunks Extract public files sourceMap Optimize skeleton screen

PWA can also use cache (client cache, server cache) optimization, enable gzip compression on the server, etc. To prevent internal leaks, destroy global variables and events after the component is destroyed

source;

components is to place components;

router is to define routing-related configuration;

view view;

app.vue is an application main component;

main.js is the entry file

Describe the vue process from initializing the page –> modifying data –> refreshing the page UI?

当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setterd 的形式,实现数据劫持;另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新视图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify( ),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。

How does Vue reset data

Using Object.assign(), vm.data can get the data in the current state,

Object.assign(this. d a t a , t h i s . data, this. data,this.options.data())

Judgment of vue-router login authority

The login permission judgment of vue-router is mainly carried out in the global hook function. In the defined route in the router.js file, we add the meta attribute to the page that requires login permission, and the value is in the form of an object, and then in the object Customize a property in , and the property value is a Boolean value. At this time, judge in the global hook function of the main.js file. If the custom property value of the page that needs to be jumped is true, then it will be judged whether it is logged in or not. If there is no login, tell the user to log in, if there is a login, then perform a page jump.

How to solve the vue first screen loading is too slow?

① Place the infrequently changed library in index.html, import it through cdn, then find the build/webpack.base.conf.js file, and add the following code in module.exports = { }:

externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
}

②Lazy loading of vue routes, lazy loading of pictures, using asynchronous components, loading on demand

③ Do not generate a map file, find the config/index.js file, and modify it to productionSourceMap: false

④ Try not to introduce the vue component globally

⑤ Use a lighter tool library

⑥ Turn on gzip compression: This optimization has two aspects. The front end packs the files into .gz files, and then allows the browser to directly parse the .gz files through the configuration of nginx.

⑦ Do server-side rendering on the homepage alone: ​​If the homepage really has a bottleneck, you can consider using node to do server-side rendering alone, and the following subpages still use spa single-page interaction. It is not recommended to use the nuxt.js server-side rendering solution directly, because this will increase the learning cost, and secondly, the maintenance cost of the server will also increase. Sometimes there is no problem in the local test, but there is a problem in running on the server. Attention, it is better to maximize the use of static pages.

What is the difference between Vue and JQuery? Why give up JQuery and use Vue?

jQuery directly manipulates the DOM, Vue does not directly manipulate the DOM, Vue's data and views are separated, Vue only needs to manipulate the data, it is a framework

jQuery's behavior of manipulating DOM is frequent, and Vue uses the technology of virtual DOM to greatly improve the performance when updating DOM. It is a library

Direct manipulation of DOM is not advocated in Vue, developers only need to focus most of their energy on the data level

Vue integrates some libraries, which greatly improves development efficiency, such as Route, Vuex, etc.

What Vue performance optimizations have you done?

Minimize the data in data as much as possible, the data in data will add getters and setters, and will collect corresponding watchers. v-if and v-for cannot be used together v-if and v-show to distinguish usage scenarios. v-for traversal must add key, key The best is the id value, and avoid using v-if at the same time. If you need to use v-for to bind events to each element, use event proxy

SPA pages use keep-alive cache components In more cases, use v-if instead of v-show Use routing lazy loading and asynchronous components

Anti-shake and throttling third-party modules are imported on demand

The long list is scrolled to the visible area and dynamically loaded, and the data that does not need to be responsive should not be placed in the data (you can freeze the data with Object.freeze())

Image lazy loading

SEO optimized pre-rendering

Server-side rendering SSR packaging optimization,

Compressed code Tree Shaking/Scope Hoisting

Use CDN to load third-party modules Multi-threaded packaging happypack splitChunks Extract public files sourceMap Optimize skeleton screen

PWA can also use cache (client cache, server cache) optimization, enable gzip compression on the server, etc. To prevent internal leaks, destroy global variables and events after the component is destroyed

Guess you like

Origin blog.csdn.net/m0_37408390/article/details/127902762