Often ask some

1. Encapsulate a designated dispatch function and dispatch a method for the specified component (e.g. ElementUI’s $Dispatch implementation)

  • Implement the $Dispatch method
  • Achieve $broadcast
// All the way up to the parent trigger method
// If I want to trigger the method that specifies the component
Vue.prototype.$dispatch = function (eventName, conponmentName, value) {
  let parent = this.$parent;
  while (parent) {
    if (parent.$options.name === conponmentName) {
      parent.$emit(eventName, value);
      return; } parent = parent.$parent; }};Copy the code

2. The role of the vue modifier sync

🍁 When a child component changes the value of a prop, the change is also synchronized to the parent component bound to 🍁

  • 🌰 Since 2.3.0 we have reintroduced the.sync modifier, but this time it only exists as a compile-time syntactic sugar. It is extended to a V-ON listener that automatically updates the parent component’s properties
<comp :foo.sync="bar"></comp>
Copy the code

Will be expanded to

<comp :foo="bar" @update:foo="val => bar = val"></comp>00
Copy the code

When a child component needs to update the value of foo, it needs to explicitly fire an update event:

this.$emit("update:foo", newValue);
Copy the code
  • 🍊 When a child component changes the value of a prop, the change is also synchronized to the parent component binding. If we don’t want to do.sync and we want to do that popover function, we can also pass the initial value, and then the event listener, which isn’t too complicated to implement. The sync implementation here is just to give you an idea of how it works, and there may be other complex features that can be used with Sync.

This is just a simple example. After reading this, do you think there is an instruction similar to this one, V-Model? Yes, when the V-Model is used on components.

3. Vue keep-alive common attributes

  • Include – a string or regular expression. Only components with matching names are cached. (Delimit a string, regular expression, or array with a comma)
  • Exclude – a string or regular expression. Any component with a matching name will not be cached.
  • Max – Numbers. Maximum number of component instances can be cached.

4. Vue operation mechanism relies on collection

🍂 Vue enables views to be refreshed when a piece of data changes, and changes to be synchronized elsewhere using the data; In addition, the data must be dependent before views and other uses of the data change. So, Vue needs to be able to know if a piece of data is being used, and the technique for implementing this mechanism is called dependency collection 🍂

  • Each component instance has a corresponding Watcher instance – the process of rendering the component records properties as dependencies – and when we manipulate a data, the setter for the dependency is called to inform Watcher of the recalcalculation, which causes the component associated with it to be updated 🍉
  1. 🌰 Since some data is needed for template rendering, it must be accessed, so intercepting the getter gives you time to process it
  2. 🌰 there is also a setter to intercept when a value changes, so intercept the setter so that the next action can be taken.

So in the getter, we do dependency collection (dependencies are the data that this component needs to rely on), and when the dependent data is set, the setter gets this notification and tells the Render () function to recalculate. 🍓 🍓 🍓

5. When a page has parent and child components, what is the life cycle triggered by the rendering sequence once entered

  1. Component synchronization is introduced in the lifecycle order

    BeforeCreate, created, beforeMount, beforeCreate for all child components, created, beforeMount, Mounted for all child components, mounted 🍊 for the parent component

  2. When components are introduced asynchronously, the lifecycle order is

    BeforeCreate, created, beforeMount, mounted -> beforeCreate, created, beforeMount, mounted 🍊 for the child components

6. Keep-alive, what if you only want a component of the router-view to be cached

  • The component object is wrapped with include/exclude keep-alive

    Router-view is also a component

  • Add the router.meta attribute

/ / routes configuration
export default[{path: "/".name: "home".component: Home,
    meta: {
      keepAlive: true.// Need to be cached}, {},path: "/:id".name: "edit".component: Edit,
    meta: {
      keepAlive: false.// Do not need to be cached}},];Copy the code
<keep-alive>
  <router-view v-if="$route.meta.keepAlive">
    <! -- Here are the view components that will be cached, such as Home! -->
  </router-view>
</keep-alive>

<router-view v-if=! "" $route.meta.keepAlive">
  <! -- Here are view components that are not cached, such as Edit! -->
</router-view>
Copy the code

7. Assume that there are three routes: A, B, and C. BY default,A is displayed. When you jump from B to A,A is not refreshed

  • Use the beforeRouteLeave guard inside the component to change the route.meta property value before jumping to the next route
  • B Component Settings
export default {
  data() {
    return {};
  },
  methods: {},
  beforeRouteLeave(to, from, next) {
    // Set the meta of the next route
    to.meta.keepAlive = true; // let A cache, i.e., not refreshnext(); }};Copy the code
  • C Component Settings
export default {
  data() {
    return {};
  },
  methods: {},
  beforeRouteLeave(to, from, next) {
    // Set the meta of the next route
    to.meta.keepAlive = false; // let A not cache, that is, refreshnext(); }};Copy the code

8. What is the principle of EventBus in component communication

EventBus is also called an EventBus. The idea of using EventBus as a bridge in Vue is that all components share the same event center to which they can register to send and receive events, so components can notify other components up and down in parallel

  • Create the global EventBus
const EventBus = new Vue();

Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      returnEventBus; ,}}});Copy the code

Prototype.$bus = new vue ();

  • Use a publish/subscribe model
this.$bus.$emit('nameOfEvent', {... pass some event data ... });this.$bus.$on('nameOfEvent'.($event) = > {
    // ...
})
Copy the code

$once The value is executed only once

9. Disadvantages of Using EventBus

  • Vue is a single-page application, and if a page is refreshed, the EventBus associated with it is removed
  • If the business has repeated operations on the page, The EventBus will trigger many times when listening, which is also a very big risk. At this point, we need to deal with the relationship of EventBus in the project. It is often used to remove the EventBus event listener when the VUE page is destroyed
import EventBus from ".. /assets/EventBus";
EventBus.$off("sendMessage", event function);// Remove the specified event
EventBus.$off("sendMessage"); // Remove all application listening for this event
EventBus.$off(); // Remove listening for all events in the application
Copy the code
  • Since both pages are using a single Vue instance, it is easy to trigger multiple times, with the same event name defined for both pages and not destroyed by $off (often during route switching).

10. The class implementation

  • Es5 via constructors (class is just a syntactic sugar)
class Mold {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
  count() {
    return this.a + this.b; }}let sum = new Mold(1.2);
console.log(sum.count()); / / 3
Copy the code

The corresponding constructor in ES5

function Mold(a, b) {
  this.a = a;
  this.b = b;
}
Mold.prototype.count = function () {
  return this.a + this.b;
};
let sum = new Mold(1.2);
console.log(sum.count()); / / 3
Copy the code

11. Several ways to implement inheritance

1. Prototype chain inheritance

Use an instance of a parent class as a prototype for a subclass

function Son(name) {
  // Father.call(this);
  this.name = name || "->son";
}
Son.prototype = new Father();
var s = new Son("son");
console.log(s.name); // son
s.sayAge(); / / 18
s.sayName(); // son
console.log(s.age); / / 18
console.log(s instanceof Father); // true
console.log(s instanceof Son); // true
Copy the code
  • advantages
    • In pure inheritance, an instance is an instance of both a subclass and a parent class
    • The parent class adds new stereotype methods and attributes that are accessible to subclasses
    • Simple and easy to implement
  • disadvantages
    • You can add instance attributes to the Son instance in the Son constructor. New attributes and methods must be executed after statements like new Father().
    • Multiple inheritance cannot be implemented because stereotypes can only be changed by one instance at a time
    • All properties from the stereotype object are shared by all instances
    • Cannot pass arguments to the parent constructor when creating a subclass instance

2. Construct inheritance (call) : Copy instance attributes of the parent class to subclasses

function Son(name) {
  Father.call(this);
  this.name = name || "->son";
}
var s = new Son("son");
console.log(s.name); // son
//s.sayAge(); // Throw an error
s.sayName(); // son
console.log(s.age); // undefined
console.log(s instanceof Father); // false
console.log(s instanceof Son); // true
Copy the code
  • advantages
    • The problem that subclass instances share parent reference attributes in prototype chain inheritance is solved
    • When you create a subclass instance, you can pass parameters to the parent class
    • Multiple inheritance can be implemented (call multiple parent objects)
  • disadvantages
    • An instance is not an instance of a parent class, only an instance of a subclass
    • You can only inherit properties and methods from the parent instance, not from its prototype
    • Function reuse is not possible, and each subclass has a copy of the parent class instance, affecting performance

3. Instance inheritance: Add new characteristics to the parent class instance and return it as a subclass instance

function Son(name) {
  var f = new Father();
  f.name = name || "->son";
  return f;
}
var s = new Son("son");
console.log(s.name); // son
s.sayAge(); / / 18
s.sayName(); // son
console.log(s.age); / / 18
console.log(s instanceof Father); // true
console.log(s instanceof Son); // false
Copy the code
  • advantages
    • There is no limit to calling a method, whether it is a new subclass () or a subclass (), and the object returned has the same effect
  • disadvantages
    • An instance is an instance of a parent class, not a subclass
    • Multiple inheritance is not supported

4. Composite inheritance: Inherit the attributes of the parent class and retain the advantages of passing parameters by calling the parent class construction, and then reuse functions by using the parent class instance as the prototype of the subclass

function Son(name) {
  Father.call(this);
  this.name = name || "->son";
}
Son.prototype = new Father();
// Fix constructor pointing
Son.prototype.constructor = Son;
var s = new Son("son");
console.log(s.name); // son
s.sayAge(); / / 18
s.sayName(); // son
console.log(s.age); / / 18
console.log(s instanceof Father); // true
console.log(s instanceof Son); // true
Copy the code
  • advantages
    • To compensate for the disadvantage of construction inheritance, it is now possible to inherit properties and methods of both instances and prototypes
    • Both an instance of a subclass and an instance of a superclass
    • There is no reference property sharing problem
    • Can pass the cords
    • Functions can be reused
  • disadvantages
    • The parent constructor is called twice, generating two instances (the subclass instance hides the subclass prototype)

5. Parasitic combination inheritance: In the parasitic way, the instance attributes of the parent class are cut off to avoid the disadvantage of combining inheritance to generate two instances

function Son(name) {
  Father.call(this);
  // var f = new Father();
  this.name = name || "->son";
}
(function () {
  // Create a class with no instance methods
  var None = function () {};
  None.prototype = Father.prototype;
  // Use the instance as the prototype of the subclass
  Son.prototype = new None();
  // Fix constructor pointingSon.prototype.constructor = Son; }) ();var s = new Son("son");
console.log(s.name); // son
s.sayAge(); / / 18
s.sayName(); // son
console.log(s.age); / / 18
console.log(s instanceof Father); // true
console.log(s instanceof Son); // true
Copy the code
  • advantages
    • perfect
  • disadvantages
    • It’s complicated to implement

6. Class Inheritance: Extends indicates which parent Class it inherits from, and super must be called in the subclass constructor

class Son extends Father {
  constructor(name) {
    super(name);
    this.name = name || "->father"; }}var s = new Son("son");
console.log(s.name); // son
s.sayAge(); / / 18
s.sayName(); // son
console.log(s.age); / / 18
console.log(s instanceof Father); // true
console.log(s instanceof Son); // true
Copy the code

12. Implementation of new

  • Create an empty object as the instance to be returned.
  • Points the empty object’s proTO to the constructor’s Prototype property.
  • Assign the empty object to this in the constructor.
  • Points to the code in the constructor
function A() {
  this.name = 1;
  this.age = 2;
  // if a class returns a reference space, the instance will point to that space
}
// let a = new A(); // 1) Create the object and pass it to the function as this
A.prototype.say = function () {
  console.log("say");
};
function mockNew(A) {
  let obj = {};
  A.call(obj);
  obj.__proto__ = A.prototype;
  return obj;
}
let o = mockNew(A);
o.say();
console.log(o);
Copy the code

13. Big Factory interview questions

1. Promise. All Exception handling (how to make promise. All even a promise program reject, promise.

Promise. All Normally, an “ALL” passes an array of promises, but if there is an error, it goes into a catch and no normal data is caught

  • Solution:
  • Change all to serial calls (lose the concurrency advantage, not recommended)
  • Use catch to catch exceptions
const a = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve(111);
  }, 1000);
});

const b = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    reject(222);
  }, 1000);
});

Promise.all(
  [a, b].map((p) = > {
    return p.catch((error) = > error);
  })
)
  .then((res) = > {
    console.log(res, "res");
  })
  .catch((error) = > {
    console.log(error, "error");
  });
Copy the code

2. Comparison and sorting of version numbers

Has a set of version number as follows [‘ while ‘, ‘2.3.3’, ‘0.302.1’, ‘4.2’, ‘4.3.5’, ‘4.3.4.5’]. Now, it is necessary to sort the sorting result for [‘ 4.3.5 ‘, ‘4.3.4.5’, ‘2.3.3’, ‘0.302.1’, ‘while’]

const arr = ["0.1.1"."2.3.3"."0.302.1"."4.2"."4.3.5"."4.3.4.5"];

arr.sort((a, b) = > {
  const arr1 = a.split(".");
  const arr2 = b.split(".");
  let i = -1;
  while (true) {
    i++;
    const s1 = arr1[i];
    const s2 = arr2[i];
    if ((s1 === undefined) | (s2 === undefined)) {
      return arr2.length - arr1.length;
    }
    if (s1 === s2) continue;
    returns2 - s1; }});console.log(arr);
Copy the code

3. The KTH largest element in the array

Finds the KTH largest element in the unsorted array. Notice that you want to find the KTH largest element in the sorted array

  • Example 1: input: [3,2,1,5,6,4] and k = 2, output: 5

  • Example 2: input: [3,2,3,1,2,4,5,5,6] and k = 4, output: 4

    If you use quicksort (sort first), the sorting time is O(NlogN), where N is the length of the array NUMs, and you want the KTH largest element, but you sort the entire array, so there are some tricks. You can reduce the time complexity down to order Nlog k, or even order N.

4. All paths in the binary tree

5. Binary tree paths with a neutral value

6. Implement promisify in node

The util core module promises the method to implement async + await + promise

  • Use the sample
const http = require("http");
const url = require("url");
const fs = require('fs');
const { promisify } = require("util");
const readFile = promisify(fs.readFile);

http.createServer((req, res) = >{(async() = > {try {
            let data = await readFile('./index2.html');
            res.statusCode = 200;
            res.setHeader('Content-Type'."text/html; charset=utf-8");
            res.end(data);
        } catch (err) {
            console.log(err);
        }
    })();
Copy the code
  • The implementation principle is as follows
// Implement the principle of promisify
const promisify1 =
  (fn) = >
  (. args) = > {
    return new Promise((resolve, reject) = >{ fn(... args,function (err) {
        // Node is asynchronous. The last argument is that the callback only applies to node because node is error-first
        if (err) reject(err);
        resolve();
      });
    });
  };
Copy the code

7. Fetch is compatible with timeout retransmission

Implement the FETCH request timeout/error to resend once

  • Blocking request methods:
    • AbortController Controller that blocks Web requests (incompatible with IE)
    // IE does not support it
    const controller = new AbortController();
    // The abortController.signal property gets a reference to its associated AbortSignal object
    const signal = controller.signal;
    controller.abort();
    Copy the code
    • Internet Explorer compatible XMLHttprequest.abort ()
  • Timeout resends => promise.race: Sends multiple requests at the same time, returning the result of the first request
let newFetch = (url) = > {
  // Retransmission times control
  let requestAgain = 0;
  // Create a controller object
  const controller = new AbortController();
  // The abortController.signal property gets a reference to its associated AbortSignal object
  const signal = controller.signal;
  // Check whether it is Internet Explorer the check does not support Internet Explorer 11 or higher
  if (navigator.userAgent.indexOf("MSIE") > -1) {
    // If ie does not support -- AbortController--
    Fetch is not supported either
    // Use native xmlHttpRequest at this point
    // Ie5/6 and IE6 + create xmlHttpRequest objects differently
    return new Promise((resolve, reject) = > {
      xmlreq(url, "GET", resolve);
    })
      .then((res) = > {
        // console.log('success')
        // console.log(res)
      })
      .catch((err) = > {
        // Resend the request
        if(requestAgain ! =0) return;
        requestAgain++;
        xmlreq(url, "GET", resolve);
      });
  } else {
    / / not ie
    return Promise.race([
      requestPromise(url, signal)
        .then(async (res) => {
          let result = await res.json();
          // console.log(result)
        })
        .catch((err) = > {
          // Repeat the error
          // Use the controller to terminate the request
          controller.abort();
          // Resend the request
          requestPromise(url).then(async (res) => {
            let result = await res.json();
            // console.log(' Request retransmission ')
            // console.log(result)
          });
        }),
      new Promise((resolve, reject) = > {
        setTimeout(() = > {
          // Use the controller to terminate the request
          controller.abort();
          // Resend the request
          if(requestAgain ! =0) return;
          requestAgain++;
          requestPromise(url).then(async (res) => {
            let result = await res.json();
            // console.log(' Request retransmission ')
            // console.log(result)
          });
        }, 30000); })); }};// Encapsulate the fetch request
let requestPromise = (url, signal = {}) = > {
  return fetch(url, {
    signal,
    headers: {
      "Content-Type": "application/json; charset=utf-8;",}}); };/ / encapsulation xmlHTTPRequest
let xmlreq = (url, methods = "GET", resolve) = > {
  // Create an xmlHttpRequest object
  let xmlHttpReq;
  if (window.XMLHttpRequest) {
    // ie6+
    xmlHttpReq = new XMLHttpRequest();
  } else {
    // ie5/6
    xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
  }
  // Set the timeout period
  xmlHttpReq.timeout = 30000;
  xmlHttpReq.open("GET", url);
  xmlHttpReq.send();
  xmlHttpReq.ontimeout = (event) = > {
    // Terminate the last request
    xmlHttpReq.abort();
    // Resend the request
    xmlHttpReq.send();
  };
  xmlHttpReq.onreadystatechange = function (event) {
    if (event.target.readyState == 4 && event.target.status == 200) {
      let resData = JSON.parse(xmlHttpReq.response); resolve(resData); }}; }; newFetch("http://a.com");
Copy the code

8. Observer mode (high frequency)

When the value of a variable is changed, it automatically notifies all other objects concerned about the variable and automatically reupdates to obtain the new value of the variable

  • The observer mode is invoked by a specific target, for example, the observer method is invoked when an event triggers the Dep, so there is a dependency between the subscriber and the observer.
  • The publish-subscribe pattern is invoked by a unified dispatch center (eventBus) because publishers and subscribers do not need to be aware of each other’s existence.
// Publisher - target
class Dep {
  constructor() {
    // Record all subscribers
    this.subs = [];
  }
  // Add subscribers
  addSub(sub) {
    // Determine if the subscriber exists and there is an update method
    if (sub && sub.update) {
      this.subs.push(sub); }}// Issue a notification
  notify() {
    // Circularly publish notifications
    this.subs.forEach((s) = >{ s.update(); }); }}// Subscriber - observer
class Watcher {
  update() {
    console.log("update --->"); }}let dep = new Dep();
let watcher = new Watcher();
// Add subscribers
dep.addSub(watcher);
// Publish execution
dep.notify();

Update -->
Copy the code

9. Implement String indexOf

10. Flat

Turns a multidimensional array into a one-dimensional array

  • Reduce implementation
function flatten(arr) {
  return arr.reduce((result, item) = > {
    return result.concat(Array.isArray(item) ? flatten(item) : item); } []); }Copy the code
  • . Extend operator implementation
function flatten(arr) {
  while (arr.some((item) = > Array.isArray(item))) { arr = [].concat(... arr); }return arr;
}
Copy the code

11. Coriolization of functions

The technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function) and returns a new function that takes the remaining arguments and returns the result

const curry = (fn, args = []) = > {
  const len = fn.length;
  return (. rest) = > {
    const arr1 = args.concat(rest);
    if (arr1.length < len) {
      return curry(fn, arr1);
    }
    returnfn(... arr1); }; };function add(a, b, c, d, e, f) {
  var val = a + b + c + d + e + f;
  return val;
}

// let sum = curry(add)(1)(2, 3)(4, 5, 6);
let sum = curry(add)(1) (2) (3) (4) (5.6);

console.log(sum);
Copy the code
  • Implement an ADD method so that the results meet the following expectations:
    • add(1)(2)(3) = 6;
    • add(1, 2, 3)(4) = 10;
    • Add (1) (2) (3) (4, 5) = 15;
function add() {
  // On the first execution, an array is defined to store all the parameters
  var _args = Array.prototype.slice.call(arguments);

  // Internally declare a function that uses closure properties to hold _args and collect all parameter values
  var _adder = function () { _args.push(... arguments);return _adder;
  };

  // Take advantage of toString's implicit conversion feature
  // Implicit conversion is performed when finally executed, and the final value is returned
  _adder.toString = function () {
    return _args.reduce(function (a, b) {
      return a + b;
    });
  };
  return _adder;
}

/ / 6
console.log(add(1) (2) (3));
/ / 10
console.log(add(1.2.3) (4));
/ / 15
console.log(add(1) (2) (3) (4) (5));
Copy the code

14. How does VUE implement component encapsulation

  • Vue.extend creates the component’s constructor
  • Vue.com Ponent Registers global components
  • When instantiating the extends component constructor, the passed property must be propsData, not props

15. Vue internal navigation guard, route exclusive guard and component internal guard

Global navigation guard

  1. Router. BeforeEach Global front guard
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) = > {
  // ...
})
Copy the code
  1. Router. BeforeResolve Global resolution guard

    • The parse guard is called before the navigation is confirmed and after all the intra-component guards and asynchronous routing components have been parsed
  2. Router.aftereach Global post-hook

  • Global post-hooks can be registered, however unlike guards, these hooks do not accept the next function nor change the navigation itself

Route exclusive guard

  • You can define beforeEnter guards directly on the route configuration, with the same method parameters as global front-guards
const router = new VueRouter({
  routes: [{path: "/foo".component: Foo,
      beforeEnter: (to, from, next) = > {
        // ...}},]});Copy the code

Guards within components

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const Foo = {
  template: `... `.beforeRouteEnter(to, from, next) {
    // called before the corresponding route to render the component is confirmed
    / / no! Can!!!! Get component instance 'this'
    // Because the component instance has not been created before the guard executes
  },
  beforeRouteUpdate(to, from, next) {
    // Called when the current route changes but the component is being reused
    // For example, for a path /foo/:id with dynamic parameters, when jumping between /foo/1 and /foo/2,
    // Since the same Foo component will be rendered, the component instance will be reused. And the hook will be called in that case.
    // Access component instance 'this'
  },
  beforeRouteLeave(to, from, next) {
    // called when navigating away from the component's corresponding route
    // Access component instance 'this'}};Copy the code