[Silicon Valley] Vue JS from introduction to mastery notes (updated daily)

catalogue

Chapter 1: Vue core

1-1. Introduction to Vue

Build user interface: turn the obtained data into an interface that users can see in some way
Progressive: gradual and progressive, that is, from a lightweight and compact core library to a variety of Vue plug-in libraries

If your application is very simple, you only need to introduce a lightweight and compact core library (compression is only 100kb); If it is more complex, various plug-in libraries will be introduced

Imperative coding: execute the command step by step, and command every step
Declarative coding: given a declaration, it completes all commands by itself

diff algorithm: an algorithm for node reuse. If a node has already appeared, it will be reused, which greatly improves the performance

1-2.Vue official website Guide

API: it's equivalent to Vue's dictionary. You can find the API if you don't know how to use it
Awesome: an easy-to-use package officially sorted by Vue

1-3. Build Vue development environment


Prompt to turn off Vue console:
1. Install Vue development tools (tips for installing development tools)
2.Vue.config.productionTip = false; Prevent vue from generating production tips in Qidong City

1-4. First meet Vue

Press shift to strongly brush and report an error:

The reason is that the tab icon is not found. Just put a tab icon in the root directory

Hello small case:

    <!-- Prepare a container -->
    <div id="root">
        <!-- Difference: that is, the inserted value, with{{}}Indicates that it can be accessed directly data data -->
        <h1>Hello,{{name}}</h1>
        <h1>My age is: 18</h1>
    </div>
    
    <script>
        // Create Vue instance
        new Vue({
            // el is used to specify which container the current Vue instance serves. The value is usually css selector string
            // It can also be a node (document.getElementById('root ')
            el: '#root',
            // Data is used to store data. The data is used by the container specified by el. The value is temporarily written into an object (function)
            data: {
                name: 'Shang Silicon Valley',
                age: 18
            }
        });
    </script>

Summary:

  1. To make Vue work, you must create a Vue instance and pass in a configuration object;
  2. The code in the root container still conforms to the html specification, but mixed with some special Vue syntax;
  3. The code in the root container is called [Vue template];
  4. Vue instances and containers correspond one-to-one;
  5. There is only one Vue instance in real development, and it will be used together with components;
  6. xxx in {xxx}} needs to write js expression, and xxx can automatically read all attributes in data
  7. Once the data in the data changes, the places where the data is used in the page will also be updated automatically

Vue template parsing process:
First, there are containers, and then there are Vue instances. The containers are obtained through el for parsing. Scan whether there is any special syntax involved. For example, {{name}} replaces the name value in data. After parsing, replace the old container

Note: distinguish between JS expression and JS code (statement):

  1. Expression: an expression will produce a value, which can be placed wherever a value is needed
    (1)a
    (2)a+b
    (3)demo(1)
    (4)x === y 'a' : 'b'

  2. js code (statement)
    (1)if(){}
    (2)for(){}

Expressions are special JS statements, which can control whether the code can be executed

1-5. Template syntax

Concept: the code in the container is the template syntax

Template syntax is divided into two categories:

  1. Difference syntax:
    Function: used to parse the label body content.
    Writing method: {xxx}}, xxx is a js expression, and all attributes in data can be read directly.
  2. Instruction syntax:
    Function: used to parse tags (including tag attributes, tag body contents, binding events...)
    Note: there are many instructions in Vue in the form of: v -.
    For example: v-bind:hred="xxx" or abbreviated as: href="xxx", xxx also needs to write js expressions, and can directly read all attributes in data.

Examples of errors:

<a href="url"></a>   <!-- At this time url Just a string -->
<a href={{url}}></a> <!-- The writing of the difference in the attribute has been changed Vue Discard -->
<a :href="url"></a>  <!-- Correct usage -->

1-6. Data binding

There are two data binding methods in Vue:

  1. v-bind: data can only flow from data to page.
  2. Two way binding (v-model): data can flow not only from data to page, but also from page to data.
    remarks:
    1. Bidirectional binding is generally applied to form elements (such as input, select, etc.)
    2.v-model:value can be abbreviated as v-model, because v-model collects value by default.

demonstration:

<!-- One way data binding !-->
<input type="text" :value="name">
<!-- Bidirectional data binding !-->
<input type="text" v-model="name">

Examples of errors:
The following code is wrong because v-model can only be applied to form class elements (input class elements)

<h2 v-model:x="name">hello</h2> 

1-7. Two ways of writing el and data

  1. el can be written in two ways:
    (1) new Vue property;
    (2) Create a Vue instance first, and then through VM$ Specified value of root (#el)

  2. data can be written in two ways:
    (1) Object type
    (2) Functional formula
    How to choose? At present, any writing method can be used. When learning components in the future, data must use functional formula, otherwise an error will be reported

  3. An important principle:
    As long as it is a function managed by Vue, you must not write the arrow function. Once the arrow function is written, this is no longer a Vue instance, but a window

    const v = new Vue({
        // el: '#root', //el the first way to write
        // Data: {/ / the first way to write data
        //     name: 'Shang Silicon Valley' 
        // },
        data() { //The second way to write data
            return {
                name: 'Shang Silicon Valley'
            }
        }
    })
    
    v.$mount('#root') //el the second way to write
    

1-8.MVVM model

MVVM model:

  1. M: Model: data in data
  2. 5: View: Vue template
  3. VM: ViewModel: Vue instance object (binding data, dom listening)

Observations:

  1. All the attributes in data finally appear on vm
  2. All attributes of vm and Vue prototype can be accessed directly in Vue template

1-9. Data proxy

1-9-1. Review object Defineproperty method

Function: define the attribute of the object and set the attribute in some advanced way
Parameter: 1 Object to add attribute
2. Add attribute name
3. Configuration item (configuration attribute value or some other parameters)
Note: the defined attribute is light purple, indicating that it cannot be enumerated (traversed)

Common configuration properties

effect

value

Set attribute value

enumerable

Controls whether attributes can be enumerated. The default value is false

writable

Controls whether the attribute can be modified. The default value is false

configurable

Controls whether the attribute can be deleted. The default value is false

get function

When someone reads the age attribute of person, the get function (getter) will be called, and the return value is the value of age

set function

When someone modifies the age attribute of person, the set function (setter) will be called and the specific value of the modification will be received

How to associate a variable with the value of an object?

let number = 18;
let person = {
        name: 'Zhang San',
        sex: 'male'
    }
Object.defineProperty(person, 'age', {
    get: function() {
        return number;
    }
})

Why can't you directly modify person How to modify the value of age?

let number = 18;
let person = {
        name: 'Zhang San',
        sex: 'male'
    }
Object.defineProperty(person, 'age', {
    get: function() {
        return number;
    },
    set: function(value) {
    number = value;
	}
})

Method 1: because age is not writable, you can set the writable property or directly modify the number associated with age
Method 2: assign the modified value to number through the set function

Knowledge development:
Object.keys
Function: this method can extract the attribute names of all attributes of the incoming object and turn them into an array
Parameters: objects

1-9-2. What is a data broker

Definition: the operation (read / write) of an attribute in another object through an object proxy

// Access and modify the x of obj through obj2
let obj = {x: 100}
let obj2 = {y: 200}
Object.defineProperty(obj2, 'x', {
    get() {
        return obj.x;
    },
    set(value) {
        obj2.x = value;
    }
})

1-9-3. Data broker in Vue

  1. Data brokers in Vue:
    Proxy vm through vm object_ Attribute operation (read / write) in the data object (that is, the data object you configured)
  2. Benefits of data brokers in Vue:
    More convenient operation of data in data
  3. Basic principle:
    Through object Defineproperty adds all the properties in the data object to the vm, and specifies a getter/setter for it to operate (read / write) the corresponding properties in the data within the getter/setter.

No data broker: VM_ data. name
With data broker: VM Name (obviously much more concise)

Note: VM_ After expanding data, you will find that it is inconsistent with data. This is because Vue does data hijacking instead of data proxy at the bottom. Its purpose is to realize responsive operation, which will be discussed later.

1-10. event processing

1-10-1. Basic use of events

  1. Use v-on:xxx or @ xxx to bind events, where xxx is the event name;

  2. The callback of events needs to be configured in the methods object and will eventually be on the vm;

  3. Do not use arrow functions for functions configured in methods! Otherwise, this is not a vm, but a window;

  4. The functions configured in methods are all functions managed by Vue. this refers to vm or component instance objects;

  5. @click="demo" and @ click="demo($event)" have the same effect. The default parameter of the former is the event object, while the latter needs $event to generate the event object, and multiple parameters can be passed;

    < button @ Click = "demo" > click my prompt

    < button @ Click = "showInfo(66)" > click my prompt

    < button @ Click = "showInfo(66,$event)" > click my prompt

Note: the method above method will eventually appear on vm, but it is not used as a data proxy because it is not necessary. Once the function is defined, it will be used directly and will not be changed.

1-10-2. Event modifier

Event modifier

describe

prevent

Block default events (common)

stop

Prevent event bubbling (common)

once

Event triggered only once (common)

capture

Capture mode using events

self

Only event The event is triggered only when target is the element of the current operation

passive

Execute the default behavior first and then the callback function

Example:
1. Block default events

<a href="http://www.atguigu. Com "@ click. Prevent =" showinfo "> click my prompt < / a > <! -- added to prevent link jump -- >

2. Prevent event bubbling

<div class="demo1" @click="showInfo">
	<button @click.stop="showInfo">Click my prompt</button> <!-- If it is not added, the outer event will be triggered. If it is added, it will not be triggered -->
</div>

3. The event is triggered only once

<button @click.once="showInfo">Click my prompt</button> <!-- The first point will trigger an event, and the second point will not -->

4. Use the capture mode of events (event flow is divided into capture and bubbling)

1) When you click div2, you first go through two stages: event capture = > event bubbling. The default is event bubbling and event processing;
2) The capture stage is from outside to inside, and the bubbling stage is from inside to outside;

<div class="box1" @click.capture="showMsg(1)">
    div1
    <div class="box2" @click="showMsg(2)">  <!-- No output 1 added,2,Added output 2,1 -->
        div2
    </div>
</div>

5. Only event The event is triggered only when target is the element of the current operation

<div class="demo1" @click.self="showInfo">
	<!-- click button,div and button All the event sources are button -->
	<!-- If you don't add it, it will trigger div If you don't add it, you won't, because self The event source is required to be itself -->
    <button @click="showInfo">Click my prompt</button>
</div>

1)event.target is determined when the element is operated, and the event source object in the event triggered later with the bubble will also be it;
2) self requires event Only when target is its own element will it be triggered;

6. The default behavior of the event is executed immediately without waiting for the event callback to complete

Scroll events are divided into scroll and wheel:
Scroll: mouse, keyboard and scroll wheel can be triggered, but rolling to the bottom will not trigger (default = > callback)
Wheel: only the wheel can be triggered, and it can still be triggered when rolling to the bottom (callback = > Default)

<ul @wheel.passive="demo" class="list"> <!--Rolling before callback is added, and rolling after callback is not added-->
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

Why do you scroll the mouse and the scroll bar doesn't go down?
Because the wheel event will trigger the rolling event first, and then execute the callback. The default behavior will not be executed until the callback is executed. passive is to solve this problem. It will execute the default behavior first, and then execute the callback (scrool has the same effect)

Benefits: it can be optimized to a certain extent. It is commonly used in mobile projects (mobile phones and tablets), but it is less used.

1-10-3. Keyboard events

1. Key aliases commonly used in Vue:

Enter = > Enter
Delete = > delete (capture the delete and backspace keys)
Exit = > ESC
Space = > space
Line feed = > tab (special, must be used with keydown)
Up = > up
Down = > down
Left = > left
Right = > right

2. For cases where Vue does not provide an alias, you can use the original key value of the key to bind, but note that it should be changed to kebab case (named by a dash)

<input type="text" placeholder="Press enter to prompt input" @keyup.caps-lock="showInfo">

3. System modifier keys (special usage): ctrl, alt, shift, meta
(1) Use with keyup: press the modifier key and then press other keys, and then release other keys to trigger the event. (the e.key value at this time is other keys, not system modifier keys)
(2) Use with keydown: normally trigger events.

4. You can also use keyCode to specify specific keys (not recommended, because different keyboard codes may be inconsistent, try to use the key name)

<input type="text" placeholder="Press enter to prompt input" @keyup.13="showInfo">

5.Vue.config.keyCodes. User defined alias = key code. You can specify the key alias

<!-- Vue.config.keyCodes.huiche = 13; -->
<input type="text" placeholder="Press enter to prompt input" @keyup.huiche="showInfo">

1-10-4. Event summary

Modifier tip: event modifiers can be written together

<!-- Block default events and bubbling -->
<div class="demo1" @click="showInfo">
	<a href="http://www.atguigu. Com "@click.stop.prevent =" showinfo "> click on my prompt</a>
</div>


<!-- Press ctrl + y Only triggered (system modifier) + (key name) -->
<input type="text" placeholder="Press enter to prompt input" @keyup.ctrl.y="showInfo">

1-11. Computing properties and monitoring

1-11-1. Name Case

Implementation of difference syntax:

<div id="root">
	Last name:<input type="text" v-model="firstName">
	Name:<input type="text" v-model="lastName">
	full name:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
</div>

<script>
    const vm = new Vue({
        el: '#root',
        data: { firstName: 'Zhang', lastName: 'three' }
    })
</script>

Vue officials suggest that component templates should contain simple expressions, and complex expressions should be refactored into calculated properties or methods

methods implementation:

<div id="root">
    Last name:<input type="text" v-model="firstName">
    Name:<input type="text" v-model="lastName"> 
    full name:<span>{{fullName()}}</span>
    <button @click="fullName">Point me</button>
</div>

<script>
    const vm = new Vue({
        el: '#root',
        data: { firstName: 'Zhang', lastName: 'three' },
        methods: {
            fullName() { return this.firstName + '-' + this.lastName } // this points to vm
        }
    })
</script>

1) Note that the methods method can omit parentheses only when binding events, and cannot be used in the difference
2) As long as the data in the data changes, Vue will re parse the template and get the latest value only after re parsing the template

computed implementation:

<div id="root">
    Last name:<input type="text" v-model="firstName">  
    Name:<input type="text" v-model="lastName"> 
    full name:<span>{{fullName}}</span>
</div>

<script>
    const vm = new Vue({
        el: '#root',
        data: { firstName: 'Zhang', lastName: 'three' },
        computed: {
            fullName: {
                get() {
                    // this here is vm
                    return this.firstName + '-' + this.lastName
                }
            }
        }
    })
</script>

1-11-2. Calculation properties

For Vue, configuration items in data are attributes.

The calculation attribute is to process and calculate the written attribute to generate a new attribute.

The calculation attribute is directly mounted on the vm and can be read and used directly (_data has no calculation attribute).

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three'
    },
    computed: {
        fullName: {
            get() {
             	// this here is vm
                return this.firstName + '-' + this.lastName;
            }
        }
    }
})

What does get do?
When someone reads fullName, get will be called and the return value will be the value of fullName.
(the bottom layer is implemented with getter/setter of Object.defineProperty)

When is get called?

1. It will be executed once when reading for the first time (the data in the cache will be fetched later)
2. When the dependent data changes, it will be called again (so don't worry about getting it from the cache after modifying the value)

<!-- Vue There are four in the template fullName,Why? get Only called once? 
	 because Vue The bottom layer is computed A caching mechanism is made, and the repeated calculated attributes will be obtained from the cache -->
<div id="root">
	<span>{{fullName}}</span>
	<span>{{fullName}}</span>
	<span>{{fullName}}</span>
	<span>{{fullName}}</span>
</div>

<script>
    const vm = new Vue({
        el: '#root',
        data: {
            firstName: 'Zhang',
            lastName: 'three'
        },
        computed: {
            fullName: {
                get() {
                	console.log('get Called'); // Only output "get called" once
                    return this.firstName + '-' + this.lastName
                }
            }
        }
    })
</script>

When is set called?
When fullName is modified.

If the calculation attribute is to be modified, the set function must be written to respond to the modification, and the data that the calculation depends on in the set will change.

<!-- When fullName The page did not change when it was modified because set Not changed to firstName and lastName,It only does output.
	 So if you want the page to change, you have to give set Make a machining and let it modify to firstName and lastName.  -->
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            firstName: 'Zhang',
            lastName: 'three'
        },
        computed: {
            fullName: {
                get() {
                	console.log('get Called'); // "get called" is output only once
                    return this.firstName + '-' + this.lastName
                },
                set(value) {
					console.log('set', value);
					// Format: Zhang - San
					const arr = value.split('-');
					this.firstName = arr[0];
					this.lastName = arr[1];
				}
            }
        }
    })
</script>

computed comparison methods:
Computed has a caching mechanism (reuse), which is more efficient and convenient for debugging (there will be a category of computed on devtools).
The methods function is called several times after it appears, which is inefficient.

Abbreviation of calculated attribute:
Generally speaking, the calculation properties are not modified, but are read and displayed.

Abbreviations can not be used at all times. They can be used only when reading is considered and modification is not considered.

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three'
    },
    computed: {
        fullName() {
            console.log('get Called');
            return this.firstName + '-' + this.lastName
        }
    }
})

Note that parentheses cannot be added after fullName, because it is only the result of calculating the attribute, not a function.

1-11-3. Weather case

<div id="root">
    <h2>It's a fine day today{{info}}</h2>
    <!-- <button @click="isHot = !isHot">Switch weather</button> -->
    <button @click="changeWeather">Switch weather</button>
</div>
<script>
    Vue.config.productionTip = false;

    new Vue({
        el: '#root',
        data: {
            isHot: true
        },
        computed: {
            info() {
                return this.isHot ? 'scorching hot' : 'pleasantly cool';
            }
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot
            }
        },
    })
</script>

When binding events: @ xxx = "yyy" yyy can write some simple js statements

1-11-4. Monitoring properties

Monitoring attribute watch:
1. When the monitored attribute changes, the callback function will be called automatically for relevant operations;
2. The monitored attribute must exist before monitoring can be performed!! (in addition to the data attribute, the calculated attribute can also be monitored)
3. Two ways of monitoring:
(1) When new Vue is selected, the watch configuration is passed in;
(2) Via VM$ Watch monitoring;
(use the first one when specifying which attributes to monitor. You don't know who to monitor when you create an instance, and then use the second one when you know which attribute to monitor according to some user behaviors)

watch configuration properties:

attribute

describe

immediate

Let handler call during initialization

handler(newVal, oldVal)

Called when the monitored attribute changes, the parameter can get the value before and after the change

deep

Deep monitoring can monitor the changes of multi-level data

// Writing method I
const vm = new Vue({
    el: '#root',
    data: {
        isHot: true
    },
    computed: {
    methods: {
    watch: {
        isHot: {
            immediate: true,
            handler(newValue, oldValue) {
                console.log('isHot It was modified', newValue, oldValue);
            }
        }
    }
})

// Method 2
vm.$watch('isHot', { // Note that the writing method of the monitored object is completely consistent with that of the string
    immediate: true,
    handler(newValue, oldValue) {
        console.log('isHot It was modified', newValue, oldValue);
    }
})

Deep monitoring:
1. watch in Vue does not monitor the change of internal value of object by default (monitor layer 1)
2. Configure deep:true to monitor the internal value change of the object (monitor multiple layers)

remarks:
(1) Vue can monitor the change of multi-level data by default (it can be seen from the change of number.a page). However, the watch attribute is not allowed by default. If you want to be able, you have to turn on deep monitoring (for efficiency).
(2) When using watch, decide whether to use deep monitoring according to the specific results of the data.

const vm = new Vue({
    el: '#root',
    data: {
        isHot: true,
        numbers: {
            a: 1,
            b: 1
        }
    },
    computed: {
    methods: {
    watch: {
        isHot: {
        // Monitor the change of an attribute in the multi-level structure -- put quotation marks (original writing)   
        // 'numbers.a': {
        //     handler() {
        //         console.log('a changed ');
        //     }
        // }
        // Monitor the changes of all attributes in the multi-level structure - turn on the depth mode
        'numbers': {
            deep: true,
            handler() {
                console.log('numbers Changed');
            }
        }
    }
})

Abbreviations for monitoring properties:
The configuration item can be abbreviated only when it is a handler.

const vm = new Vue({
    el: '#root',
    data: {
        isHot: true
    },
    computed: {
        info() {
            return this.isHot ? 'scorching hot' : 'pleasantly cool';
        }
    },
    methods: {
        changeWeather() {
            this.isHot = !this.isHot
        }
    },
    watch: {
        // Normal writing:
        /* isHot: {
            // immediate: true,
            // deep:true,
            handler(newValue, oldValue) {
                console.log('isHot Modified ', newValue, oldValue);
            }
        }, */
        // Abbreviation:
        isHot(newValue, oldValue) {
            console.log('isHot It was modified', newValue, oldValue);
        }
    }
});

// Normal writing:
vm.$watch('isHot', {
    // immediate: true,
    // deep:true,
    handler(newValue, oldValue) {
        console.log('isHot It was modified', newValue, oldValue);
    }
});

// Abbreviation:
vm.$watch('isHot', function(newValue, oldValue) {
    console.log('isHot It was modified', newValue, oldValue);
});

watch compared to computed:
1. watch can complete all functions that can be completed by computed.
2. The functions that can be completed by watch may not be completed by computed. For example, watch can perform asynchronous operation.

Two important small principles:
1. All functions managed by Vue should be written as ordinary functions, so that the point of this is the vm or component instance object.
2. All functions not managed by Vue (timer callback function, ajax callback function, Promise callback function, etc.) should be written as arrow function, so that the point of this is the vm or component instance object.

Or take a weather case for comparison:

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three',
        fullName: 'Zhang-three'
    },
    watch: {
        firstName(val) {
            this.fullName = val + '-' + this.lastName;
        },
        lastName(val) {
            this.fullName = this.firstName + '-' + val;
        }
    }
})

The above code is imperative and repetitive. Compare them to the version of the calculated attribute:

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three'
    },
    computed: {
        fullName() {
            return this.firstName + '-' + this.lastName
        }

Much better, isn't it?

Respond after one second delay:

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three',
        fullName: 'Zhang-three'
    },
    watch: {
        firstName(val) {
            // Note that the normal function with this points to window by default, and the arrow function without this will inherit upward
            setTimeout(() => {
                this.fullName = val + '-' + this.lastName;
            }, 1000)
        },
        lastName(val) {
            setTimeout(() => {
                this.fullName = this.firstName + '-' + val;
            }, 1000)
        }
    }
})

watch is easy to complete.

const vm = new Vue({
    el: '#root',
    data: {
        firstName: 'Zhang',
        lastName: 'three'
    },
    computed: {
        fullName() {
        	// The fullName value is equal to null, because fullName has no return value, and the return value is given to the callback of the timer
        	setTimeout(() => {
    			return this.firstName + '-' + this.lastName;
			}, 1000)
        }

In contrast, computed cannot be implemented because it cannot perform asynchronous tasks.

1-12.class and style binding

class style:
Writing method: class="xxx" xxx can be string, object or array.
The string writing method is applicable to: if the class name is uncertain, it should be obtained dynamically.
The object writing method is applicable to: to bind multiple styles, the number is uncertain and the name is uncertain.
The array writing method is applicable to: to bind multiple styles, the number is determined, and the name is also determined, but it is uncertain whether to use it or not.

style:
: style="{fontSize: xxx}" where xxx is a dynamic value. (note that the style name is small hump)
: style="[a,b]" where a and B are style objects.

<div id="root">
    <!-- binding class style--String writing, applicable to: the class name of the style is uncertain and needs to be specified dynamically -->
    <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/>
    <!-- binding class style--Array writing method is applicable to: the number of styles to be bound is uncertain and the name is uncertain -->
    <div class="basic" :class="classArr">{{name}}</div> <br/>
    <!-- binding class style--The object writing method is applicable to: the number of styles to be bound and the name are determined, but it is necessary to dynamically decide whether to use them or not -->
    <div class="basic" :class="classObj">{{name}}</div> <br/>
    
    <!-- binding style style--Object writing -->
    <div class="basic" :style="styleObj">{{name}}</div> <br/>
    <!-- binding style style--Array writing -->
    <div class="basic" :style="styleArr">{{name}}</div>
</div>

<script>
    const vm = new Vue({
        el: '#root',
        data: {
            name: 'Shang Silicon Valley',
            mood: 'normal',
            classArr: ['atguigu1', 'atguigu2', 'atguigu3'],
            classObj: {
                atguigu1: false,
                atguigu2: false
            },
            styleObj: {
                fontSize: '40px',
                color: 'red'
            },
            styleObj2: {
                backgroundColor: 'orange'
            },
            styleArr: [{
                fontSize: '40px',
                color: 'red'
            }, {
                backgroundColor: 'gray'
            }]

        },
        methods: {
            changeMood() {
                const arr = ['normal', 'happy', 'sad'];
                const index = Math.floor(Math.random() * 3);
                this.mood = arr[index];

            }
        },
    })
</script>

1-13. conditional rendering

  1. v-if
    Writing method:
    (1) v-if = "expression"
    (2) v-else-if = "expression"
    (3) v-else = "expression"
    Applicable to: scenes with low switching frequency.
    Features: DOM elements that are not displayed are removed directly.
    Note: v-if can be used with: v-else-if and v-else, but the structure must not be "broken".

  2. v-show
    Writing method: v-show = "expression"
    Applicable to: scenes with high switching frequency.
    Features: DOM elements that are not displayed are not removed, but are only hidden with styles

  3. Note: when using v-if, elements may not be available, but they can be obtained by using v-show.

    The current n is {{n}}

1-14. List rendering

1-14-1. Basic list

v-for instruction:
1. Used to display list data
2. Syntax: V-for = "(item, index) in XXX": key = "yyy"
3. Traversable: array, object, string (rarely used), specified number of times (rarely used)

<div id="root">
	<!-- Traversal array -->
	<h2>Personnel list (traversal array)</h2>
	<ul>
		<li v-for="(p,index) of persons" :key="index">
			{{p.name}}-{{p.age}}
		</li>
	</ul>
	<!-- Traversal object -->
	<h2>Car information (traversal object)</h2>
	<ul>
		<li v-for="(value,k) of car" :key="k">
			{{k}}-{{value}}
		</li>
	</ul>
	<!-- Traversal string -->
	<h2>Test traversal string (less used)</h2>
	<ul>
		<li v-for="(char,index) of str" :key="index">
			{{char}}-{{index}}
		</li>
	</ul>
	
	<!-- Traverse the specified number of times -->
	<h2>Test traversal specified times (less used)</h2>
	<ul>
		<li v-for="(number,index) of 5" :key="index">
			{{index}}-{{number}}
		</li>
	</ul>
</div>

<script type="text/javascript">
	new Vue({
		el:'#root',
		data:{
			persons:[
				{id:'001',name:'Zhang San',age:18},
				{id:'002',name:'Li Si',age:19},
				{id:'003',name:'Wang Wu',age:20}
			],
			car:{
				name:'audi A8',
				price:'70 ten thousand',
				color:'black'
			},
			str:'hello'
		}
	})
</script>

1-14-2.key principle

Interview question: what is the role of the key in react and vue? (internal principle of key)

1. Role of key in virtual DOM:
key is the identification of the virtual DOM object. When the data changes, Vue will generate a new virtual DOM according to the new data. Then Vue will compare the differences between the new virtual Dom and the old virtual dom. The comparison rules are as follows:

2. Comparison rules:
(1) The same key as the new virtual DOM was found in the old virtual DOM:
① If the content in the virtual DOM does not change, directly use the previous real DOM!
② If the content in the virtual DOM changes, a new real DOM is generated, and then the previous real DOM in the page is replaced.
(2) The same key as the new virtual DOM cannot be found in the old virtual dom. Create a new real Dom and then render it to the page.

3. Possible problems caused by using index as key:
(1) If the data is added and deleted in reverse order, it will produce unnecessary real DOM updates = > the interface effect is OK, but the efficiency is low.
(2) If the structure also contains the dom of the input class: an error will be generated. DOM update = > there is a problem with the interface.

4. How to select a key during development:
(1) it is better to use the unique identifier of each data as key, such as id, mobile phone number, id card number, student id number and so on.
(2) If there are no destructive operations such as reverse order addition and reverse order deletion of data, it is only used for rendering the list for display,
There is no problem using index as the key.

Example:

key=0~2, the corresponding data is different, so the new value is filled in, and the input is the same, so it is reused directly
key=3, there is no corresponding key, so a new virtual dom is generated

key=001~002, the corresponding contents are the same and can be reused directly
key=004, generate a new virtual dom

<div id="root">
	<!-- Traversal array -->
	<h2>Personnel list (traversal array)</h2>
	<button @click.once="add">Add an old Liu</button>
	<ul>
		<li v-for="(p,index) of persons" :key="index"> <!-- Don't use it here index Ha -->
			{{p.name}}-{{p.age}}
			<input type="text">
		</li>
	</ul>
</div>

<script type="text/javascript">
	new Vue({
		el:'#root',
		data:{
			persons:[
				{id:'001',name:'Zhang San',age:18},
				{id:'002',name:'Li Si',age:19},
				{id:'003',name:'Wang Wu',age:20}
			]
		},
		methods: {
			add(){
				const p = {id:'004',name:'Lao Liu',age:40}
				this.persons.unshift(p)
			}
		},
	})
</script>

1-14-3. List filtering

When both computed and watch can be implemented, computed is preferred

<div id="root">
    <input type="text" placeholder="Please enter your name" v-model="keyWord">
    <ul>
        <li v-for="(p,index) of filPersons" :key="index">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
    </ul>
</div>

<script type="text/javascript">
    // watch implementation:
    /* const vm = new Vue({
        el: '#root',
        data: {
            keyWord: '',
            persons: [{
                id: '001',
                name: 'Ma Dongmei ',
                age: 18,
                sex: ''female'
            }, {
                id: '002',
                name: 'Zhou Dongyu ',
                age: 19,
                sex: ''female'
            }, {
                id: '003',
                name: 'Jay Chou ',
                age: 20,
                sex: ''male '
            }, {
                id: '004',
                name: 'Wen zhaolun ',
                age: 21,
                sex: ''male '
            }],
            filPersons: []
        },
        watch: {
            keyWord: {
                immediate: true,
                handler(val) {
                    this.filPersons = this.persons.filter((p) => {
                        return p.name.indexOf(val) !== -1;
                    })
                }
            }
        }
    }) */

    // computed implementation:
    const vm = new Vue({
        el: '#root',
        data: {
            keyWord: '',
            persons: [{
                id: '001',
                name: 'Ma Dongmei',
                age: 18,
                sex: 'female'
            }, {
                id: '002',
                name: 'Zhou Dongyu',
                age: 19,
                sex: 'female'
            }, {
                id: '003',
                name: 'Jay Chou',
                age: 20,
                sex: 'male'
            }, {
                id: '004',
                name: 'Wen zhaolun',
                age: 21,
                sex: 'male'
            }]
        },
        computed: {
            filPersons() {
                return this.persons.filter((p) => {
                    return p.name.indexOf(this.keyWord) !== -1;
                })

            }
        }
    })
</script>

Here, computed is executed directly, and watch is executed only after listening to data changes, so it is better to use computed.

1-14-4. sort list

This case fully reflects the powerful function of calculated. As long as any attribute changes, the whole calculation attribute will be recalculated.

<div id="root">
    <input type="text" placeholder="Please enter your name" v-model="keyWord">
    <button @click="sortType = 1">Ascending order of age</button>
    <button @click="sortType = 2">Age descending order</button>
    <button @click="sortType = 0">Original sequence</button>
    <ul>
        <li v-for="(p,index) of filPersons" :key="index">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
    </ul>
</div>

<script type="text/javascript">
    Vue.config.productionTip = false

    // computed implementation:
    const vm = new Vue({
        el: '#root',
        data: {
            keyWord: '',
            persons: [{
                id: '001',
                name: 'Ma Dongmei',
                age: 30,
                sex: 'female'
            }, {
                id: '002',
                name: 'Zhou Dongyu',
                age: 31,
                sex: 'female'
            }, {
                id: '003',
                name: 'Jay Chou',
                age: 18,
                sex: 'male'
            }, {
                id: '004',
                name: 'Wen zhaolun',
                age: 21,
                sex: 'male'
            }],
            sortType: 0 //0 original order @ click="sortType = 0"1 descending order 2 ascending order
        },
        computed: {
            filPersons() {
                const arr = this.persons.filter((p) => {
                    return p.name.indexOf(this.keyWord) !== -1;
                });
                // Determine whether you need to sort
                if (this.sortType) {
                    arr.sort((p1, p2) => {
                        return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
                    })
                }
                return arr;
            }
        }
    })
</script>

Knowledge development:
sort(a,b) array method, a-b ascending order, b-a descending order, change the original array.

1-14-5. A problem when updating

1-14-6. How Vue detects data changes

1-14-7. Simulate a data monitor

1-14-8. Vue. Use of set

1-14-9. Principle of Vue monitoring data change_ array

1-14-10. Summarize Vue data monitoring

1-15. Collect form data

1-16.Vue instance declaration cycle

1-17. Transition & Animation

1-18. filter

1-19. Built in instruction and custom instruction

1-20. Custom plug-ins

Chapter 2: Vue component programming

Chapter 3: using Vue scaffolding

Chapter 4: ajax in Vue

Chapter 5: Vuex

Chapter 6: Vue router

Chapter 7: Vue UI component library

Keywords: Javascript Front-end Vue.js html

Added by Masca on Wed, 09 Mar 2022 07:00:34 +0200