Vue principle

Response principle

Object.definproperty, how to listen on objects (deep listening), listen on arrays, several disadvantages

  • Deep monitoring needs to recurse to the end, which requires a large amount of one-time calculation

  • Unable to listen on new attributes/delete attributes (vue.set vue.delete)

  • Unable to listen on arrays natively, requires special handling to rewrite array prototypes

    Function updateView() {
        console.log('View Update')}
    // Redefine Array prototype const oldArrayProperty = array.prototype
    // Create a new object, the prototype points to oldArrayProperty, and extending the new method does not affect the prototype
    const arrProto = Object.create(oldArrayProperty);
    ['push'.'pop'.'shift'.'unshift'.'splice'].forEach(methodName= > {
        arrProto[methodName] = function () {
            updateView()
     // Triggers a view update
            oldArrayProperty[methodName].call(this. arguments)// Array.prototype.push.call(this, ... arguments)
        }})
    // Redefine attributes to listen
    function defineReactive(target, key, value) {
        // Deep monitor
        observer(value)
        / / core API
        Object.defineProperty(target, key, {
            get() {
                return value
            },
            set(newValue) {
                if(newValue ! == value) {// Deep monitor
                    observer(newValue)
                    // Set the new value
                    // Note that value is always in the closure, and after this is set, the latest value will be retrieved when we get it
                    value = newValue
                    // Trigger to update the view
                    updateView()
                }
            }
        })}
    Function observer(target) {
        if (typeoftarget ! = ='object' || target === null) {
            // Not objects or arrays
            return target
        }
        // Contaminate the global Array prototype
        // Array.prototype.push = function () {
        // updateView()
        / /...
        // }
        if (Array.isArray(target)) {
            target.__proto__ = arrProto
        }
        // Redefine attributes (for in can also iterate over arrays)
        for (let key in target) {
            defineReactive(target, key, target[key])
        }}
    // Prepare data const data = {
        name: 'zhangsan'.age: 20.info: {
            address: 'Beijing'
     // Deep listening is required
        },
        nums: [10.20.30]}
    // Monitor data observer(data)
    / / / test
    / data.name = 'lisi'
    // data.age = 21//
     // console.log('age', data.age)
    // data.x = '100'
     Vue. Set = Vue
    // delete data.name
     // Delete attribute, listen not -- all Vue. Delete
    // data.info.address = 'Shanghai'
     // Deep listen data.nums.push(4)
     // Listen for arrays
    Copy the code

Vdom and DIff algorithms

Use JS to simulate the DOM structure, calculate the smallest changes, and manipulate DOM

– Compare only the same level, not across levels

– If the tag is not the same, delete it and rebuild it

– If the tag and key are the same, the node is considered to be the same

PatchVnode, addVnodes, removeVnodes, updateChildren (Key importance)

Template compilation

  • Vue Template Complier compiles the template into the render function and executes the rende function to produce vNodes

  • The template is compiled into the render function, which is executed to return vNode

  • Perform patch and DIff based on vNode

  • With Webpack vue-loader, templates are compiled in a development environment

    const compiler = require('vue-template-compiler')
    / / the interpolation
    // const template = `<p>{{message}}</p>`
    // with(this){return createElement('p',[createTextVNode(toString(message))])}
    // h -> vnode
    // createElement -> vnode
    // // expression
    // const template = `<p>{{flag ? message : 'no message found'}}</p>`
    // // with(this){return _c('p',[_v(_s(flag ? message : 'no message found'))])}
    // // properties and dynamic properties
    // const template = `//
         <div id="div1" class="container">//
             <img :src="imgUrl"/>
    // 
    / / `
    // with(this){return _c('div',
    // {staticClass:"container",attrs:{"id":"div1"}},
    / / /
    // _c('img',{attrs:{"src":imgUrl}})])}
    / / / / conditions
    // const template = `
    // 
            
    //

    A

    //

    B

    // / / ` // with(this){return _c('div',[(flag === 'a')?_c('p',[_v("A")]):_c('p',[_v("B")])])} / / loop // const template = ` //
      //
    • {{item.title}}
    • // / / ` // with(this){return _c('ul',_l((list),function(item){return _c('li',{key:item.id},[_v(_s(item.title))])}),0)} // `// with(this){return _c('button',{on:{"click":clickHandler}},[_v("submit")])} // v-modelconst template = `<input type="text" v-model="name">` // Look at the input event // with(this){return _c('input',{directives:[{name:"model",rawName:"v-model",value:(name),expression:"name"}],attrs:{"type":"text"},domProps: {"value":(name)},on:{"input":function($event){if($event.target.composing)return; name=$event.target.value}}})} / / render function Const res = compiler.compile(template)console.log(res.render) // --------------- splitter -------------- // // find the meaning of abbreviation function from vue source // function installRenderHelpers (target) { // target._o = markOnce; // target._n = toNumber; // target._s = toString; // target._l = renderList; // target._t = renderSlot; // target._q = looseEqual; // target._i = looseIndexOf; // target._m = renderStatic; // target._f = resolveFilter; // target._k = checkKeyCodes; // target._b = bindObjectProps; // target._v = createTextVNode; // target._e = createEmptyVNode; // target._u = resolveScopedSlots; // target._g = bindObjectListeners; // target._d = bindDynamicKeys; // target._p = prependModifier; // } Copy the code

    Component rendering process

    – Reactive: listen for getter setters for data properties (including arrays)

    – Template compilation: template to render function, then vNode

    -vdom: patch(elem, vnode) and patch(vnode, newVnode)

    Initial rendering process

    • Parse the template as the Render function (or completed in the development environment, vue-loader)
    • Trigger reactive, listen for the data property getter
    • Render function, generate vnode, patch(elem, vnode)

    The update process

    • Modify data to fire the setter (already listened on in the getter)
    • Re-execute the render function to generate newVnode
    • Patch (vnode, newVnode)

    Asynchronous rendering

    The front-end routing

    • hash – window.onhashchange
    • H5 history-history. pushState and window. onpopState

    Vue

    1. The difference between V-show and V-for

    • V-show Controls the display and hiding using the CSS display
    • V-if components really render and destroy, not show and hide
    • To frequently switch the display status, run v-show; otherwise, run V-if

    2. Why is key used in V-for

    • You must use key, and you don’t have to try index and random
    • Diff algorithm uses key and tag to determine whether it is a sameNode
    • Reduce rendering times and improve rendering performance

    3. Describe the VUE component lifecycle (if there are parent and child components)

    Vue’s parent and child component lifecycle hook function execution sequence can be categorized into the following four parts:

    • Loading the rendering process

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

    • Child component update process

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

    • Parent component update process

      Parent beforeUpdate -> Parent updated

    • Destruction of the process

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

    4. How do VUE components communicate

    • The parent component props and this.$emit
    • Noevent. No event. Noevent. Off event.$emit
    • vuex

    5. Describe the process of component rendering and updating

    6. Realization principle of two-way data binding V-Model

    • The value of the input element =this.name
    • Bind the input event this.name = $event.target.value
    • Data update triggers re-render

    7. com puted and watch

    Computed: Computed attributes depend on other attribute values, and computed values are cached. Only when the dependent attribute values change, computed values will be recalculated the next time it obtains computed values.

    Watch: It is more of a function of “observation”, similar to the listening callback of some data. Whenever the monitored data changes, the callback will be executed for subsequent operations.

    Application scenario:

    • When we need to do numerical calculations and rely on other data, we should use computed, because we can take advantage of the caching nature of computed and avoid recalculating each time we get a value.

    • Watch should be used when we need to perform asynchronous or expensive operations when data changes. Using the Watch option allows us to perform asynchronous operations (accessing an API), limits how often we perform that operation, and sets the intermediate state until we get the final result. These are all things you can’t do with computed properties.

    8. Why does component data have to be a function

    9. Common performance optimization schemes of VUE

    (1) Optimization at the code level

    • Use v-if and V-show wisely
    • Use computed and Watch wisely
    • V-for traversal must add a key to the item and avoid using v-if at the same time
    • Keep-alive, asynchronous components
    • Timely destruction of custom events and DOM events
    • Lazy loading of image resources
    • Route lazy loading
    • The introduction of third-party plug-ins on demand
    • Optimize infinite list performance
    • Server render SSR or prerender

    (2) Optimization of Webpack level

    • Webpack compresses images
    • Reduce redundant code from ES6 to ES5
    • Extract common code
    • Template precompilation
    • Extract the COMPONENT’s CSS
    • Optimize SourceMap
    • Build results output analysis
    • Compilation optimization of Vue project

    (3) Optimization of basic Web technology

    • Enable Gzip compression
    • Browser cache
    • The use of CDN
    • Use Chrome Performance to find Performance bottlenecks

    10. Proxy implements reactive mode