1 introduction

Is a set of progressive frameworks for building user interfaces. Unlike other large frameworks, Vue is designed to be applied layer by layer from the bottom up. Vue’s core library focuses only on the view layer, making it easy to get started and integrate with third-party libraries or existing projects.

Two features:

  • The core only focuses on the view layer
  • Flexible, lightweight, flexible characteristics
  • Suitable for mobile projects
  • Progressive framework

What is a library and what is a framework?

  • A library is a collection of code into a product, a library is we call the methods in the library to implement their own functions
  • Frameworks are products that are developed to solve a class of problems. Frameworks are things that we write code in a given place, and frameworks call them for us.

A framework is an updated version of a library

4 a gradual

  • Declarative rendering (don’t care how it’s implemented)
  • Component system
  • Client Routing (VUe-Router)
  • Large-scale State Management (VUEX)
  • Build Tools (VUE-CLI)

5 Two core points of Vue

  1. Data changes in response
  2. When data changes -> View updates automatically
  3. Composite view components
  4. UI pages are mapped to component trees
  5. Partition components are maintainable, reusable, and testable

6 MVC(backbone,react)

  • The model data
  • view
  • The controller controller

7 MVVM (presents, vue) two-way

  • The model data
  • view
  • ViewModel viewModel

8 Object.defineProperty(ES5) There is no alternative

  • Does not support ie8 < =

2 Basic VUE commands

2.1 installation vue

  • CDN way
  • NPM way

2.2 Simple attempts

CDN is used here to facilitate testing


      
<html>

<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>

<body>
    <div id="content">
        <! Syntax expressions can be set to three values -->
        {{ msg }}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<! -- Use vue address of official website -->
<script>
    // A vue constructor is given after referencing vue
    var vm = new Vue({ // vm === viewModel
        el: '#content'.// Tell vue which part to manage,querySelector "document.querySelector("#content")"
        data: { // The data in data is proxied by the VM
            msg: 'Hello Vue! ' // You can use vm. MSG to get the corresponding day}})// Object.defineProperty
    vm.msg = "wjw" // Modify the view
</script>
</html>
Copy the code

2.3 Template Syntax

The result is a set of template syntax

2.3.1 text

<span>Message:{{msg}}</span>
Copy the code

2.3.2 expression

{{number + 1}}
{{ok?'YES':'NO'}}
{{message.split(' ').reverse().join(' ')}}
Copy the code

But vUE’s form element input Checkbox Textarea radio Select is not text processed

Vue’s directive directive is just an interline attribute in the DOM. Vue assigns meaning to these attributes for special purposes. All directives start with a V – value attribute

2.3.3 Form input

The V-model will assign MSG to the input box, and the change of the value of the input box will affect the data

<input v-model="msg">
<input type="checkbox" v-model="msg1" value="Climb">
Copy the code

2.3.4 raw HTML

<p>Using mustache:<span v-html='rawHtml'></spn></p>
Copy the code

2.3.5 instruction

<p v-if='seen'>See me now</p>
Copy the code

2.3.6 features

<div v-bind:id='dynamicld'></div>
Copy the code

2.4 Object. DefineProperty principle


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="content"></div>
    <input type="text" id="input">
</body>
  
<script>
    let obj = {}
    let temp = {};
    document.getElementById("content").innerHTML = obj.name
    // 'name' stands for attribute
    Object.defineProperty(obj,'name', {configurable:false.// Whether to delete
        // writable:true,// whether it can be assigned (if set is used, it cannot be used)
        enumerable:true.// enumerable, also for.. in..
        // value:1,// value (if use get method, can not use)
        get(){ // Taking obj's name triggers the get method
            return temp['name']
        },
        set(val){// Assigning obj triggers the get method
            // console.log(val);
            temp['name'] = val // Change the result of temp
            input.value = val // Assign the value to the input box}}); input.value = obj.name// As soon as the page loads, the get method is called
    input.addEventListener('input'.function(){ // Wait for the input box to change
        obj.name = this.value // Call the set method when the value changes
        document.getElementById("content").innerHTML = obj.name
    })
</script>

</html>
Copy the code

Finally, the prototype of bidirectional binding can be realized

3 changes in data response

Vue loops through data (data hijacking) adding getters and setters in turn

 let vm = new Vue({
   el:'#content'.data: {a: {}}})Copy the code

But at this point I want to add a school method and find that there is no getter and setter generated

1.1 Method 1 $set

When using variables, initialize them first; otherwise, new attributes will not cause a page refresh

 vm.$set(vm.a,"school".'1')// This method can add responsive changes to an object
Copy the code

1.2 Method two Replaces the original object

vm.a = {"school":"heihei".age:8};
Copy the code

1.3 Array Problems

To change an item in an array that cannot be monitored, you cannot change the length of the array

let vm = new Vue({
  el:'#content'.data: {a: [1.2.3.4.5.6]}})Copy the code

Error method

vm.a[0] =100
vm.a.length -=2 
Copy the code

Variation method: Pop push shift unshit sort reserve splice

 vm.a = vm.a.map(item= >item*3) 
Copy the code

4 array of loops v-for

Vue provides a V-for solution to loop problems more efficiently and reuse legacy structures

4.1 code


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="content">
        <! Add a V-for attribute to whoever you want to loop, similar to for... in.. -->
        <! Value of array/(value,index) of array -->
        <li v-for="(todo,index) in todos">
 <! Methods that change the original array are mutated methods such as push(),pop(), etc. Non-mutating methods that do not change the original array but return a new array -->
            {{ todo.text }} {{index+1}}
        </li>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<! -- Use vue address of official website -->
<script>
    let vm = new Vue({
        el:'#content'.data: {todos: [{text: 'learning JavaScript' },
                { text: 'learning Vue' },
                { text: 'The whole cattle Project'}]}})</script>
</html>
Copy the code

Vue’s in-place reuse mechanism does not change the order of items when using for to update rendered elements. To reorder, add a key attribute to each item (that is, a unique ID for each item)

Want to change

Methods that change the original array are mutated methods such as push(),pop(), etc. A non-mutating method that does not change the original array but returns a new one

4.2 Why v-for must have a key


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <div>
            <input type="text" v-model="name">
            <button @click="add">add</button>
        </div>
        <ul>
            <li v-for="(item, i) in list">
                <input type="checkbox"> {{item.name}}
            </li>
        </ul>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<! -- Use vue address of official website -->
<script>
    // Create Vue instance, get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        name: ' ',
        newId: 3,
        list: [
          { id: 1, name: 'vegetables' },
          { id: 2, name: "Cheese" },
          { id: 3, name: 'meat' }
        ]
      },
      methods: {
        add() {
         // Notice that this is unshift
          this.list.unshift({ id: ++this.newId, name: this.name })
          this.name = ' '}}});</script>
  </div>

</html>
Copy the code

When you type in soup

It’s going to look like this =>

But when you replace it with key

A checkbox with a key id is associated with its contents. That’s what we want to achieve

The Diff algorithm of the virtual DOM of Vue and React is roughly the same. The core of the Diff algorithm is based on two simple assumptions. First, the processing method of the Diff algorithm is introduced.












Is it inefficient to update C to F, D to C, E to D, and then insert E? Therefore, we need to use key to make a unique identification for each node, so that the Diff algorithm can correctly identify this node and find the correct location area to insert a new node.

The list loop in VUE needs to add :key=” unique identifier “. The unique identifier can be the ID index in item, etc., because vUE components are highly reusable, adding keys can identify the uniqueness of components. In order to better distinguish each component key, the main function is to update the virtual DOM efficiently

Five events

5.1 Definitions & Abbreviations

Event definitions and abbreviations

<div id="app">
	<button @click="msg"></button>
	<button @mousedown="add"></button>
  <! $event = $event; $event = $event; $event = $event;
</div>let vm = new Vue({ el:"#app", methods:{ msg(){ console.log(Math.random()); }}})Copy the code

The data in methods and data will all be stored on the VM, and the names should not conflict, which will cause errors. The “this” in methods refers to instances

5.2 mousedown

A MouseDown event occurs when the mouse pointer is moved over an element and the mouse button is pressed (either left or right). Unlike the Click event, the mousedown event only requires the button to be pressed, not released.

5.3 mouseup

A mouseup event occurs when the mouse button (left or right) is released on an element. Unlike the Click event, the Mouseup event simply needs to release the button. Releasing the mouse button when the mouse pointer is over the element triggers the event.

5.4 click

A click event occurs when the mouse pointer hovers over an element and then presses and releases the left mouse button. Note: The click event is triggered by pressing and releasing the left mouse button! , pressing and releasing the right mouse button does not trigger the click event. The firing order of the three events

5.5 summarize

If you press and release the left mouse button on the same element, mouseDown, mouseup, and Click will be triggered until the previous event is executed. The next event will not be executed until the previous event completes, and the click event will not be emitted

Use of event modifiers

1 Event Handling

If you need to access native DOM events in the associative sentence processor. You can use the special variable $event and pass it to a method in methods. In Vue, event modifiers take care of a lot of the details of DOM events, freeing us from having to spend a lot of time dealing with annoying things and focusing on the logic of the program. Event modifiers in Vue are:

  • .stop: is equivalent to JavaScriptevent.stopPropagation()To prevent events from bubbling
  • .prevent: is equivalent to JavaScriptevent.preventDefault()Prevents the execution of a preset behavior (cancels the event if it can be cancelled without stopping further propagation of the event)
  • .capture: In contrast to the direction of event bubbling, events are captured from the outside in
  • .self: fires only events in its own scope, no child elements
  • .once: Triggers only once

1.1 stop Prevents events from bubbling

Bubble events: nested two or three layers of parent-child relationships, and then all have click events, click on the child node, will trigger the click events from inside to outside the child node – “parent node

<! -- HTML --> 

<div id="app"> 
 &emsp;<div class="outeer" @click="outer"> 
   &emsp;<div class="middle" @click="middle"> 
     &emsp;<button @click="inner">Click on the I (^_^)</button>
     </div>
   </div> 
 &emsp;<p>{{ message }}</p> 
</div>let app = new Vue({ el: '#app', data () { &emsp; Return {message: 'test bubble event'}}, &emsp; methods: { &emsp; Inner: function () {this.message = 'inner: this is the inner Button' &emsp; }, &emsp; middle: function () { &emsp; This. message = 'middle: this is the middle Div' &emsp; }, &emsp; outer: function () { &emsp; This. message = 'outer: this is the outer Div' &emsp; } &emsp; }})Copy the code

Stop is equivalent to calling the event. StopPropagation () in each method. Clicking on the child node does not capture the events of the parent node

<! -- HTML --> 

<div id="app"> 

 &emsp;<div class="outeer" @click.stop="outer"> 

   &emsp;<div class="middle" @click.stop="middle"> 

     &emsp;<button @click.stop="inner">Click on the I (^_^)</button>

     </div>

   </div> 

</div>
Copy the code

1.2 Prevent Cancels the default event

.prevent is the JavaScript equivalent of event.preventDefault() to cancel the default event. For example, the tag on our page, when the user clicks, usually lists the # in the browser url:

1.3. Capture Capture events

Capture events: nested two or three layers of parent-child relationships, then all have click events, click on the child node, will trigger click events from the outside to the inner parent node – “child node

<! -- HTML --> 
<div id="app"> 
 &emsp;<div class="outeer" @click.capture="outer"> 
   &emsp;<div class="middle" @click.capture="middle"> 
     &emsp;<button @click.capture="inner">Click on the I (^_^)</button>
     </div>
   </div> 
</div>
Copy the code



1.4. The self

The. Self modifier fires only events in its own scope and contains no child elements.

<! -- HTML --> 
<div id="app"> 
 &emsp;<div class="outeer" @click.self="outer"> 
   &emsp;<div class="middle" @click.self="middle"> 
     &emsp;<button @click.stop="inner">Click on the I (^_^)</button>
     </div>
   </div> 
</div>
Copy the code

1.5. Once Performs only one click

If we add the.once modifier to the @click event, clicking the button will only happen once.

2 Keyboard modifier

In addition to the events described above, there are keyboard events in JavaScript events, and it is often necessary to monitor common key values. Allows V-ON to add key modifiers when listening for keyboard events in Vue. Remembering all keycodes can be difficult, so Vue provides aliases for the most common keyboard events:

  • . Enter: The Enter key
  • . TAB: indicates the TAB key
  • .deleteContains:deleteandbackspacekey
  • . Esc: Return key
  • Space: the blank space key
  • . Up: Indicates the up button
  • . Down: Indicates the down key
  • . Left: Left
  • .right: Right click

3 Mouse modifier

The mouse modifier is used to restrict the handler from listening for a particular mouse key. Common ones are:

  • . Left: the left mouse button
  • . Middle: Indicates the middle mouse wheel
  • . Right: Right mouse button

4 modifier keys

Mouse or keyboard event listening can be turned on with the following modifier to respond when a key is pressed:

  • .ctrl
  • .alt
  • .shift
  • .meta

5 Customize the alias of key modifier

You can customize key modifier aliases in Vue via config.keyCodes. For example, because keycode 116 (F5) has a pre-defined alias of F5, pressing F5 in the text input box triggers the prompt method and an alert appears.

<! -- HTML --> <div id="app">

    <input type="text" v-on:keydown.f5="prompt()">

</div>



Vue.config.keyCodes.f5 = 116;



let app = new Vue({

    el: '#app',

    methods: {

        prompt: function() {

            alert('I'm F5! '); }}});Copy the code

6 summarizes

In Vue, v-ON is used to bind events to elements, and Vue provides methods to better handle logical things. Define methods in methods that help us with logical things. In this article, we mainly introduce some event modifiers, such as the common prevent event bubbling, keyboard modifiers and so on. In addition, config.keyCodes provide custom keymodifier aliases.

7 abbreviations

7.1 Command Abbreviations

<a v-bind:href='url'></a>
<a :href='url'></a>
<a v-on:click='doSomething'></a>
<a @click='doSomething'></a>
Copy the code

7.2 Function Abbreviations

After the abbreviations

8 Component management

1. Componentized development

We can intuitively divide a complex page into several independent components, each containing the logic and style of the component, and then combine these independent components into a complex page. This reduces logic complexity and enables code reuse. A page is a container of components. Components are automatically combined to form a complete interface. When a component is no longer needed or a component needs to be replaced, you can replace or delete it at any time without affecting the entire application.

2. Benefits of componentized development

  • Improve development efficiency
  • Easy to reuse
  • Facilitate collaborative development
  • Easier to manage and maintain

In vue, div, span can be considered a component

3. Global components

  • Global components: Can be declared to be used anywhere at once
  • Local component: You must tell who this component belongs to

Global components are usually used more when writing plug-ins


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>

<body>
    <div id="app">
        <my-handsom></my-handsom>
        <my-handsom></my-handsom>
        <my-handsom></my-handsom>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    Vue.component("my-handsom", {// An object can be viewed as a component
        data: function (a) {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
    })
    var vm = new Vue({
        el: '#app'
    })
</script>
</html>
Copy the code

  • Do not use uppercase component names. Use – for multiple components
  • This is ok as long as the component and definition are the same (the first letter can be capitalized)
  • HTML is separated by a short line naming js transit hump is also possible

Learn more about components

props

Component parameter passing

slot

The application of slot in component abstract design

Custom events

How parent and child components communicate

9 Global API-vue.extend

Using the base Vue constructor, create a “subclass.” The parameter is an object that contains component options.

The data option is a special case, note – it must be a function in vue.extend ()

<div id="mount-point"></div>
Copy the code
// Create a constructor
var demo = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>'.data: function () {
    return {
      firstName: 'Walter'.lastName: 'White'.alias: 'Heisenberg'}}})// Create a Profile instance and mount it to an element.
new demo().$mount('#mount-point')
Copy the code

10 global API – nextTick

The official instructions

Parameters:

  • {Function} [callback]
  • {Object} [context]

Usage: A deferred callback is performed after the next DOM update loop ends. Use this method immediately after modifying the data to get the updated DOM.

// Modify the data
vm.msg = 'Hello'

// DOM has not been updated yet
Vue.nextTick(function () {
  // DOM is updated
})

// Use as a Promise (new since 2.1.0, see hints below)
Vue.nextTick()
  .then(function () {
    // DOM is updated
})
Copy the code

New since 2.1.0: Returns a Promise if no callback is provided and in an environment that supports Promise. Note that Vue doesn’t come with Promise’s polyfill, so if your target browser doesn’t support Promise nave, you’ll have to provide polyfill yourself.

The sample

Let’s start with an example of DOM updates in Vue and what nextTick can do. The template

<div class="app">
  <div ref="msgDiv">{{msg}}</div>
  <div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
  <div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
  <div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
  <button @click="changeMsg">
    Change the Message
  </button>
</div>
Copy the code

* * Vue instance

new Vue({
  el: '.app'.data: {
    msg: 'Hello Vue.'.msg1: ' '.msg2: ' '.msg3: ' '
  },
  methods: {
    changeMsg() {
      this.msg = "Hello world."
      this.msg1 = this.$refs.msgDiv.innerHTML
      this.$nextTick((a)= > {
        this.msg2 = this.$refs.msgDiv.innerHTML
      })
      this.msg3 = this.$refs.msgDiv.innerHTML
    }
  }
})
Copy the code

Click on the former

After clicking on

As you can see from the figure, msG1 and MSG3 still display the content before the transformation, while MSG2 shows the content after the transformation. The root cause is that DOM updates in Vue are asynchronous (more on that later).

Application scenarios

The following describes the main application scenarios and causes of nextTick.

  • In the Vue life cyclecreated()DOM operations performed by hook functions must be placed inVue.nextTick()In the callback function of

The DOM doesn’t actually render at the time the Created () hook function executes, and DOM manipulation is useless, so make sure you put the DOM manipulation js code in the view.nexttick () callback. The mounted() hook function is the mounted() hook function, because it executes when all DOM operations are completed.

  • Any operation to be performed after the data changes that requires the use of a DOM structure that changes with the dataVue.nextTick()In the callback function of.

The specific reasons are explained in detail in the official documents of Vue:

Vue performs DOM updates asynchronously. Whenever a data change is observed, Vue opens a queue and buffers all data changes that occur in the same event loop. If the same watcher is triggered more than once, it will only be pushed into the queue once. This removal of duplicate data while buffering is important to avoid unnecessary computation and DOM manipulation. Then, in the next event loop, “TICK,” Vue refreshes the queue and performs the actual (de-duplicated) work. Vue internally tries to use native promise.then and MessageChannel for asynchronous queues, or setTimeout(fn, 0) instead if the execution environment does not support it. For example, when you set vm.someData = ‘new value’, the component does not immediately re-render. When the queue is refreshed, the component updates with the next “tick” when the event loop queue is empty. In most cases we don’t need to worry about this process, but if you want to do something after a DOM status update, it can be tricky. While vue.js generally encourages developers to think in a “data-driven” way and avoid direct contact with the DOM, sometimes we do. To wait for Vue to finish updating the DOM after the data changes, use vue.nexttick (callback) immediately after the data changes. This callback will be called after the DOM update is complete.

11 global API – set

Website shows

Vue.set( target, propertyName/index, value )

  • parameter:
    • {Object | Array} target
    • {string | number} propertyName/index
    • {any} value
  • Return value: the value set.
  • usage:

    Add a property to a reactive object and make sure the new property is also reactive and triggers view updates. It must be used to add new properties to reactive objects because Vue cannot detect ordinary new properties (e.gthis.myObject.newProperty = 'hi')

Note that the object cannot be a Vue instance, or the root data object of the Vue instance.

The sample

<div id="div">  
	<p >{{items}}</p>
</div>
 
<script>
 
var vm = new Vue({
el:"#div",
  data: {
    items: ['a', 'b', 'c']
  }
});
 
Vue.set(vm.items,2,"ling")
 
</script>
Copy the code

1 Set the array elements

Vue. Set (vm. Items, 2, “ling”) : according to the vm. The items of the array element with a subscript 2, “ling” instead of the array (” a “, “b”, “c”] is modified [” a “, “b”, “ling”]



2 Add attributes to reactive objects

<div id="div">  
	<p>{{person}}</p>
</div>
 
<script>
var vm = new Vue({
el:"#div",
data: {
   person:{
			name:"ling",
			job:"engineer"
   }
},
created:function(){
		alert(this.person.age)
  }
});
 
Vue.set(vm.person,"age","26")
</script>
Copy the code

Note: Person is a child of data, so you can use the vue.set () method. The data root object cannot use the set method

Console can find the age attribute in the person, indicating that the added success (responsive)

**

Compare non-responsive methods

vm.food=”chocolate”

alert(vm.food)

{{person}} on the console and web page does not show the food attribute, indicating that the food attribute has not been added (non-responsive)



12 global API – delete

Vue.delete( target, propertyName/index )

  • parameter:
    • {Object | Array} target
    • {string | number} propertyName/index

Array + index is supported only in version 2.2.0+.

  • Usage: Delete an attribute of an object. If the object is reactive, make sure the deletion triggers an update to the view. This method is mainly used to get around the restriction that Vue cannot detect property deletions, but you should rarely use it.

Working on arrays is also supported in 2.2.0+.

  • The target object cannot be a Vue instance or the root data object of the Vue instance.
data:{
   namelist : {
     id : 1.name : 'Leaf Fall forest'}}Copy the code
/ / delete the name
delete this.namelist.name;/ / js method
Vue.delete(this.namelist,'name');/ / the vue method
Copy the code

13 Global API-fifer filter

8.1 introduction

Allows you to customize filters that can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and v-bind expressions (the latter supported as of 2.1.0+). Filters should be added to the end of JavaScript expressions, indicated by the “pipe” symbol

8.2 advantage

1. Using Filters in Vue is an interesting way to render data. First, we need to know that filters in Vue do not replace methods, computed, or Watch in Vue. Filters do not change the real data, but only the rendered result and return the filtered version. Filters can be useful in many different situations, such as keeping API responses as clean as possible and handling data formatting on the front end. 5. They also effectively encapsulate all the logic behind reusable code blocks in cases where you want to avoid duplication and wiring.

8.3 Filter Example


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <div>{{ message | capitalize }}</div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app',
      data: {
        message: 'world'
      },
      filters: { // There are many custom filters available
        capitalize(value) { // This refers to the window
            if(! value)return ' '
            value = value.toString()
            return value.charAt(0).toUpperCase() + value.slice(1)}}});</script>
</html>
Copy the code

8.4 Filter Cascading


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        {{ message | filterA | filterB }}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app',
      data: {
        message: 'world'
      },
      filters: { // There are many custom filters available
        filterA(value){
            return value.split(' ').reverse().join(' ');
        },
        filterB(value){
            return value.charAt(0).toUpperCase() + value.slice(1)}}});</script>
</html>
Copy the code

8.5 Filter Parameter Transfer


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        {{ message | filterA('hello',hi) }}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app'.data: {
        hi:'! '.message: 'world'
      },
      filters: { // There are many custom filters available
        filterA(value1,value2,value3){
            return `${value2} ${value1} ${value3}`; }}});</script>
</html>
Copy the code

Here, filterA is defined as a filter function that takes three arguments. Where the value of message takes the first argument, the plain string ‘hello’ takes the second argument, and the expression hi takes the third argument.

14 slots – slot

The old version vue

There can only be one root element in a template

The HTML content template element is a mechanism for holding client-side content that is not rendered when the page is loaded, but can then be instantiated at run time using JavaScript.

<div id="app">
   <modal></modal> 
</div>

<template id="modal">
   <div>
     <h1>Whether or not to delete</h1>
  </div>
</template>
Copy the code
let modal = {
 template:"#modal"
}

const app = new Vue({
 el:'#app'.components:{
   modal
 },
 data: {}})Copy the code

We usually want to put h1 values in dynamically, so we use slots

A single slot default slot | | anonymous slot

The first is a single slot. A single slot is the official name for a VUE, but it can also be called a default slot, or as opposed to a named slot, we can call it an anonymous slot. Because it doesn’t set the name property. A single slot can be placed anywhere in a component, but as the name suggests, there can only be one such slot in a component. Correspondingly, there can be many named slots, as long as the name attribute is different.

<div id="app">
  <modal>
    <h1>Insert the success</h1>
  </modal>
</div>

<template id="modal">
  <div>
    <slot></slot>
  </div>
</template>
Copy the code

When we see that the insert is successful, the anonymous insert is implemented

A named slot

An anonymous slot does not have a name attribute, so it is an anonymous slot. After the name attribute is added to the slot, it becomes a named slot. Named slots can appear N times in a component, in different locations. Here is an example of a component with two named slots and a single slot. The three slots are represented by the parent component using the same SET of CSS styles, but with slightly different contents.

Basically, we might have a problem where we want to insert different things into different slots

Deprecated in 2.6.0+

<div id="app">
    <modal>
        <h1>Insert the success</h1>
        <h2 slot="title">The title</h2>
        <h2 slot="content">content</h2>
    </modal>
</div>

<template id="modal">
  <div>
    <slot name="default"></slot>
    <slot name="title"></slot>
    <slot name="content"></slot>
  </div>
</template>
Copy the code

We can see that in the absence of name, the default is default

Scope slot | slot with data

Finally, there is our scope slot. This is a little bit harder to understand. Officially called a scoped slot, we can actually call it a slot with data compared to the previous two. The first two types are written inside the template of the component

Deprecated in 2.6.0+


This will be familiar to those of you who are used to Element-UI.

Summary: 1. Use slot to insert native HTML elements into custom components. Use the name and slot attributes together, otherwise multiple slots may return duplicate HTML elements. 2. Slot-scope is used to point the scope inside a slot to the child component, otherwise the default scope is to the parent component of the calling slot.

New version of v-slot

Starting at [email protected], Vue introduced a new syntax for named and range slots, the main character of today’s lesson: the V-slot directive. The goal is to unify slot and scope-slot syntax to make code more formal and clear. Now that the new syntax is in place, it’s clear that slot and scope-slot will be done with [email protected] for good. Starting with [email protected], the official recommendation is to use V-slot instead of the latter two.



/ / component
Vue.component('lv-hello', {
  template: ` < div > < slot name = "header" > < / slot > < h1 > my day < / h1 > < / div > `
})

new Vue({
  el: '#app1'.data: {}});Copy the code

The old version

<div id="app1">
  <! -- Older versions use named slots -->
  <lv-hello>
    <p slot="header">I am a head</p>
  </lv-hello>
</div>
Copy the code

New version changes

  <! -- New version uses named slot -->
  <lv-hello>
    <! Note: The v-slot directive can only be written to the template tag, not to the P tag.
    <template v-slot:header>
      <p>I am a head</p>
    </template>
  </lv-hello>
</div>
Copy the code

An abbreviation for named slot

Replace v-slot: with #

<div id="app">
  <lv-hello>
    <template #header>
      <p>I am a head</p>
    </template>
    <! Note: # must be followed by an argument, otherwise an error will be reported. Even the default slot needs to be written as #default -->
    <template #default>
      <p>I'm the default slot</p>
    </template>
  </lv-hello>
</div>
Copy the code

Scope slot

A scoped slot allows the contents of the slot to access data only available in child components.

Vue.component('lv-hello', {
  data: function () {
    return {
      firstName: '张'.lastName: '三'}},template: '
      

Omg

'
}) Copy the code
<div id="app">
  <! -- Older versions use named slots -->
  <lv-hello>
  	<p slot="header" slot-scope="hh">I am the header {{hh.firstName}} {{hh.lastName}}</p>
	</lv-hello>
<! -- New version uses named slot -->
    <lv-hello>
      <! Note: The v-slot directive can only be written to the template tag, not to the P tag.
      <template v-slot:header="hh">
         <p>I am the header {{hh.firstName}} {{hh.lastName}}</p>
      </template>
  	</lv-hello>
</div>
Copy the code

15 Dynamic binding style – V-bind

13.1 Object Syntax

The style of the class binding does not conflict with the class binding

13.1.1 Directly Binding a Data

<div v-bind:class="{ active: isActive }"></div>
Copy the code

The existence of the active class depends on the Boolean value of the data attribute isActive

<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
Copy the code

13.1.2 Data uses an object binding

data: {
  classObject: {
    active: true.'text-danger': false}}Copy the code

13.1.3 Calculating Binding in Properties

data: {
  isActive: true.error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'}}}Copy the code

13.2 Array Syntax

<div v-bind:class="[activeClass, errorClass]"></div>
Copy the code

13.2.1 Dynamically Binding a Class directly

data: {
  activeClass: 'active'.errorClass: 'text-danger'
}
Copy the code

13.2.2 Ternary expressions

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
Copy the code

However, this is a bit cumbersome when there are multiple conditional classes. So you can also use object syntax in array syntax:

<div v-bind:class="[{ active: isActive }, errorClass]"></div>
Copy the code

16 Data – Computed attributes (computed)

1 What are calculated attributes

Expressions in templates are very convenient, but they are designed for simple calculations. Putting too much logic into a template can make it too heavy and difficult to maintain. Such as:


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
       <div id="example">
           {{ message.split('').reverse().join('') }}
       </div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        message: 'Hello'}});</script>
  </div>

</html>
Copy the code

The expression here contains three operations and is not very clear, so complex logic should be handled using Vue’s computed property, computed.

2 Calculate the use of attributes


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
       <div id="example">
           {{getMessage}}
       </div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        message: 'Hello'
      },
      computed: { // Put in computed and eventually put in VM, not the same name as methods and data
        getMessage() {
            return this.message.split(' ').reverse().join(' ')}}});</script>
  </div>

</html>
Copy the code

3 Techniques for calculating attributes

Computed properties can depend on other computed properties Computed properties can depend on data not only from the current Vue instance, but also from other instances


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app1"></div>
    <div id="app2">
         {{getMessage}}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app1'.data: {
        message: 'World'}});var vm2 = new Vue({
      el: '#app2'.data: {
        message: 'Hello'
      },
      computed: { 
        getMessage() {
            return `The ${this.message} ${vm.message}`}}});</script>
  </div>
</html>
Copy the code

4 getter and setter

Each computed property contains a getter and a setter, and our two examples above are the default uses of computed properties that only use the getter to read. If you need to, you can also provide a setter function that will be triggered to perform custom operations when manually modifying the value of a calculated property as if it were modifying normal data


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="getMessage"> <-- Simulation modification --!>
        {{getMessage}}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app'.data: {
        hi:'Hello'.message: 'World'
      },
      computed: {getMessage: {/ / the get and set methods
           // getter
           get(){
             return this.hi + ' ' + this.message
           },
           // setter
           set(newValue){
              console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
              console.log(newValue);
              console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
              var names = newValue.split(' ');
              this.hi = names[0];
              this.message = names[names.length - 1]; }}}});</script>
</html>
Copy the code

Most of the time, we only use the default getter to read a calculated property. Setters are rarely used in business. Therefore, when declaring a calculated property, you can use the default notation instead of declaring both getters and setters.

5. Why not directly use methods to question

We can define the same function as a method rather than a calculated property, and the end result is exactly the same in both ways. Just one using getMessage() and one using getMessage. The difference, however, is that computed attributes are cached based on their dependencies. A calculated property is reevaluated only if its associated dependencies change. This means that as long as the HI hasn’t changed, multiple calls to the getMessage computed property will immediately return the previous computed result without having to execute the function again.

<! DOCTYPE html><html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <div>{{getMessage}}</div>
        <div> {{getMessage1()}}</div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm= new Vue({
      el: '#app',
      data: {
        hi:'Hello',
        message: 'World'
      },
      computed:{
        getMessage(){ / / the get and set methods
            return this.hi + ' ' + this.message 
            // As long as the title does not change, the page rendering is not recomputed, but cached.
        }
      },
      methods:{
        getMessage1(){
            return this.hi + ' ' + this.message
            // Enter this method and calculate again. Instead of refreshing, as soon as the page is rendered, it is recalculated into the method.}}});</script>
</html>
Copy the code

17 Data-Observation (Watch)

An object whose key is the expression to observe and whose value is the corresponding callback function. The value can also be a method name, or an object that contains options. The Vue instance will call $watch() at instantiation time, iterating through each property of the Watch object.

Why must there be a watch? Is it ok not to use it? We already have computed, can we not use it?

1. The emergence of Watch

Do an experiment


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="a">
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>

    var vm = new Vue({
        el:'#app'.data: {a:"1"
        },
        computed: {
            a(){
               setTimeout((a)= > {
                   this.a=1;
               }, 500); }}})</script>
</html>
Copy the code

It is not hard to see how it is difficult to use _ when _ is asynchronous

2 Code implementation

<! DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>vue</title> </head> <body> <div id="app"> <input type="text"  v-model="a"> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var vm = new Vue({ el:'#app', data:{ a:"" }, watch: {// Asynchron is triggered only when the value changes, otherwise we are better at using a(newVal,oldVal){// The name of the watch property should be the same as the name of the person observing console.log(newVal); console.log(oldVal); } }, }) </script> </html>Copy the code

3 Differences between computed and Watch

Vue provides a more general way to observe and respond to changes in data on Vue instances: listening properties. It’s easy to abuse Watch when you have some data that needs to change with other data

<! DOCTYPE html><html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        {{ fullName }}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
</html>
Copy the code
    var vm = new Vue({
    el: '#app'.data: {
            firstName: 'Foo'.lastName: 'Bar'.fullName: 'Foo Bar'
        },
        watch: {
            firstName: function (val) {
                this.fullName = val + ' ' + this.lastName
            },
            lastName: function (val) {
                this.fullName = this.firstName + ' ' + val
            }
        }
    })
Copy the code

The code above is imperative and repetitive. Compare this to the version of the calculated property:

var vm = new Vue({
  el: '#demo'.data: {
    firstName: 'Foo'.lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})
Copy the code

Doesn’t it feel a lot more elegant

4 the listener

While computing properties is more appropriate in most cases, sometimes a custom listener is required. That’s why Vue provides a more generic way to respond to changes in data with the Watch option. This approach is most useful when asynchronous or expensive operations need to be performed when data changes.


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
       <input type="text" v-model="something">
       {{somethingShow}}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
    el: '#app'.data: {
            something: ' '.somethingShow:' '
        },
        watch: {
            something(val){
                this.somethingShow = "loading"
                this.getSomething()
            }
        },
        methods:{
            getSomething(){
                setTimeout((a)= > {
                    this.somethingShow = "hello"
                }, 1000);// We use latency to simulate a network request}}})</script>
</html>
Copy the code

5 vm.$watch

vm.$watch( expOrFn, callback, [options] )

An expression to observe a Vue instance change or to evaluate a property function. The callback takes new and old values. The expression accepts only supervised key paths. For more complex expressions, replace them with a function.


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
       <input type="text" v-model="something">
       {{somethingShow}}
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
    el: '#app'.data: {
            something: ' '.somethingShow:' '
        }
    })
    vm.$watch('something',(newVal,oldVal)=>{// The name of the watch property should be the same as the name of the person being observed
        vm.somethingShow = "loading"
        console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
        console.log(newVal);
        console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
        vm.somethingShow = newVal
    })
</script>
</html>
Copy the code

18 Data – Properties (props)

One of the options accepted by the component is an important option in Vue. The parent-child component relationship can be summarized as follows: props down, events UP The parent component passes data to the child component through props. The child component sends messages to the parent component through Events.

Parent and child component

For example, we need to create two components, parent and Child. Ensuring that each component can be written in relative isolation also improves the maintainability of components. Here we define the parent and child components and a Vue object

var childNode = {
  template: `
        <div>childNode</div>
        `
};
var parentNode = {
  template: `
        <div>
          <child></child>
          <child></child>
        </div>
        `,
  components: {
    child: childNode
  }
};
new Vue({
  el: "#example",
  components: {
    parent: parentNode
  }
});
Copy the code
<div id="example">
  <parent></parent>
</div>
Copy the code

The template defined by childNode here is a div, and the content is a “childNode” string. The parentNode template defines a div class named parent and contains two child components.

Static props

The scope of a component instance is isolated. This means that you cannot (and should not) directly reference the parent component’s data in the child component’s template. To make a child component use the parent component’s data, you need to pass the props option of the child component. There are two ways for a parent component to pass data to a child: dynamically and statically. Modify the code in the example above to add a props option to childNode and the required forChildMsg data; You then pass the data by adding features to placeholders in the parent component.

var childNode = {
  template: ` 
      
{{forChildMsg}}
`
.props: ["for-child-msg"] // Put the parameters directly as an array }; var parentNode = { template: `

parentNode

`
.components: { child: childNode } }; Copy the code

Naming conventions **

For properties declared by the props, in the parent component’s template template, the name of the properties must be underlined. When declaring the props property, use either a small hump or a hyphen. Child component templates that use variables passed from parent components need to be written with the corresponding small hump. Don’t worry, Vue correctly recognizes variables that mix small hump and underscore naming, such as forChildMsg and for-child-msg, which are the same value here.

Dynamic props

In principle it’s simple, for-child-msg as a variable

var parentNode = {
  template: ` 
      

parentNode

`
.components: { child: childNode }, data: function() { return { childMsg1: "child-1".childMsg2: "child-2"}; }};Copy the code

ChildMsg1 and childMsg2 in the return data of the parent component’s data are passed into the child component

Props to verify

Verify the data specification for the props parameter passed in, and Vue will warn if the data specification is not met.

All types of type values are: String, Number, Boolean, Function, Object, Array, Symbol

Vue.component("example", {
  props: {
    // Base type detection, null means any type can be used
    propA: Number.// Multiple types
    propB: [String.Number].// Mandatory and String
    propC: {
      type: String.required: true
    },
    // Numbers have default values
    propD: {
      type: Number.default: 101
    },
    // Array, the default value is a factory function return object
    propE: {
      type: Object.default: function() {
        console.log("propE default invoked.");
        return { message: "I am from propE."}; }},// Customize the validation function
    propF: {
      isValid: function(value) {
        return value > 100; }}}});let childNode = {
  template: "<div>{{forChildMsg}}</div>".props: {
    "for-child-msg": Number}};let parentNode = {
  template: ` 
      
`
.components: { child: childNode }, data() { return { // An error will be reported if this is the string "123456" msg: 123456}; }};Copy the code

You can also add a custom validation function to the props data and print a warning if the function returns false. For example, if we change the for-child-msg of childNode to an object with a function named Validator, the custom function name will not take effect

let childNode = {
  template: "<div>{{forChildMsg}}</div>".props: {
    "for-child-msg": {
      validator: function(value) {
        return value > 100; }}}};Copy the code

Here we set the for-child-msg variable to a validator and require that the value passed in must be greater than 100, otherwise a warning is reported.

Unidirectional data flow

The props are bound unidirectionally: when properties of the parent component change, they are transmitted to the child component, but not vice versa. This is to prevent the child component from modifying the state of the parent component. Therefore, you should not change the values in props in child components, and Vue will warn you.

let childNode = {
  template: ` < div class = "child" > < div > < span > child components data < / span > < input v - model = "forChildMsg" / > < / div > < p > {{forChildMsg}} < / p > < / div > `.props: {
    "for-child-msg": String}};let parentNode = {
  template: ` < div class = "parent" > < div > < span > parent component data < / span > < input v - model = "MSG" / > < / div > < p > {{MSG}} < / p > < the child :for-child-msg="msg"> `.components: {
    child: childNode
  },
  data() {
    return {
      msg: "default string."}; }};Copy the code

The transfer process will be short horizontal segmentation naming, into the camel name can be

Here we have an input box for both parent and child components and display parent and child data. When we enter new data in the parent’s input box, the synchronized child data is also modified; This is the function passing data to the subcomponents. When we modify the input field of the child component, the browser console reports an error warning

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “forChildMsg”

Modifying props Data

There are usually two reasons:

  1. When prop is passed in as an initial value, the child component wants to use it as local data

  2. After prop is passed in as an initial value, it is processed into other data output by the child components

  3. Define a local variable and initialize it with the value of prop

But because the ownChildMsg defined can only accept the initial value of forChildMsg, ownChildMsg cannot receive updates when the value to be passed by the parent component changes.

let childNode = {
  template: 
      

{{forChildMsg}}

ownChildMsg : {{ownChildMsg}}

`
.props: { "for-child-msg": String }, data() { return { ownChildMsg: this.forChildMsg }; }};Copy the code

Here we added one

OwnChildMsg (default); ownChildMsg (default); ownChildMsg (default);


  1. Define a calculation property that handles the value of prop and returns it

Because it is a calculated property, values can only be displayed, not set. What we set up here is that once we modify the forChildMsg data from the parent component, we add a string “– ownChildMsg” to forChildMsg and display it on the screen. It is possible to update ownChildMsg data whenever the parent modifies new data.

let childNode = {
  template: 
      

{{forChildMsg}}

ownChildMsg : {{ownChildMsg}}

`
.props: { "for-child-msg": String }, computed: { ownChildMsg() { return this.forChildMsg + "---ownChildMsg"; }}};Copy the code
  1. A more appropriate approach is to use variables to store the initial value of a prop and watch to see how the prop value changes. Update the value of a variable when changes occur.
let childNode = {
  template: 
      

{{forChildMsg}}

ownChildMsg : {{ownChildMsg}}

`
.props: { "for-child-msg": String }, data() { return { ownChildMsg: this.forChildMsg }; }, watch: { forChildMsg() { this.ownChildMsg = this.forChildMsg; }}};Copy the code

19 Life Cycle

1 Introduction to the VUE lifecycle

2 Life cycle exploration


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">{{message}}</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var app = new Vue({
        el: '#app'.data: {
            message: "hello is world"
        },
        beforeCreate() {
            console.group('beforeCreate pre-creation state =============== ');
            console.log("%c%s"."color:red"."el : " + this.$el); //undefined
            console.log("%c%s"."color:red"."data : " + this.$data); //undefined 
            console.log("%c%s"."color:red"."message: " + this.message)
        },
        created() {
            console.group('created Created state =============== ');
            console.log("%c%s"."color:red"."el : " + this.$el); //undefined
            console.log("%c%s"."color:red"."data : " + this.$data); // has been initialized
            console.log("%c%s"."color:red"."message: " + this.message); // has been initialized
        },
        beforeMount() {
            console.group('beforeMount State before mounting =============== ');
            console.log("%c%s"."color:red"."el : " + (this.$el)); // has been initialized
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data); // has been initialized
            console.log("%c%s"."color:red"."message: " + this.message); // has been initialized
        },
        mounted() {
            console.group('Mounted End status ===============');
            console.log("%c%s"."color:red"."el : " + this.$el); // has been initialized
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data); // has been initialized
            console.log("%c%s"."color:red"."message: " + this.message); // has been initialized
        },
        beforeUpdate() {
            console.group('beforeUpdate Pre-update status =============== ');
            console.log("%c%s"."color:red"."el : " + this.$el);
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data);
            console.log("%c%s"."color:red"."message: " + this.message);
        },
        updated() {
            console.group('Updated completed status ===============');
            console.log("%c%s"."color:red"."el : " + this.$el);
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data);
            console.log("%c%s"."color:red"."message: " + this.message);
        },
        beforeDestroy() {
            console.group('beforeDestroy Pre-destruction state =============== ');
            console.log("%c%s"."color:red"."el : " + this.$el);
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data);
            console.log("%c%s"."color:red"."message: " + this.message);
        },
        destroyed() {
            console.group('Destroyed completion state ===============');
            console.log("%c%s"."color:red"."el : " + this.$el);
            console.log(this.$el);
            console.log("%c%s"."color:red"."data : " + this.$data);
            console.log("%c%s"."color:red"."message: " + this.message)
        }
    })
</script>
</html>
Copy the code

If you open F12 in Chrome, you can see it on console

3 beforecreated

El and data are not initialized

4 created

Data is initialized, el is not

5 beforeMount

Initialization of EL and data is complete

6 mounted

Complete the mount

7 update

Enter in the Console

app.message= 'hello!! ';
Copy the code

8 destroy

The vue instance is destroyed with a command from the console. Once the destruction is complete, we re-change the value of message, and vUE no longer responds to this action. However, the originally generated DOM element still exists, so once you destroy it is no longer under vUE control.

app.$destroy();
Copy the code

9 Life cycle summary

9.1 beforecreate

We can add a loading event here, an animation to load

9.2 created

This is where loading ends and some initialization is done to make the function self-executing

9.3 mounted

Make a back-end request here, get the data back, and do something with the routing hook

9.4 beforeDestroy

Are you sure to delete XX? Destroyed: Deletes the current component

20 Instruction – Conditional judgment (V-if & V-show)

1 v-if&v-show

  • Conditional rendering (usev-if)
  • Conditional display (usev-show)

If operates in a dom show style and if you switch the DOM frequently and use v-show, as soon as the data is turned on it’s better to use V-if, if the if doesn’t execute through internal instructions you can only use vue animations if the DOM goes from show to hide or hide to show


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
        <span v-if="flag">You can see me</span>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            flag:true}})</script>
</html>
Copy the code

2. Summary of Differences

  • V-show: operates on the display attribute of the element
  • V-if: handles element creation and insertion
  • By comparison, the PERFORMANCE of the V-Show is higher

21 Built-in Components – Transition

1 Component transition

Vue provides a wrapper component for Transition, and you can add an entry/exit transition to any element or component in the following cases

There are six class switches in the entry/exit transition.

  1. v-enter: Defines the state at the beginning of the transition. It takes effect before the element is inserted and is removed the next frame after the element is inserted.

  2. v-enter-active: Defines the state when the transition takes effect. Applied throughout the transition phase, before the element is inserted and removed after the transition/animation is complete. This class can be used to define the process time, delay, and curve functions that enter the transition.

  3. v-enter-to2.1.8 and aboveDefine the end state of the transition. The next frame takes effect after the element is inserted (at the same timev-enterRemoved) after the transition/animation is complete.

  4. v-leave: Defines the beginning state of the exit transition. Immediately after the exit transition is triggered, the next frame is removed.

  5. v-leave-active: Defines the state when the exit transition takes effect. Applies throughout the exit transition phase, takes effect immediately when the exit transition is triggered, and removes after the transition/animation is complete. This class can be used to define exit transition process time, delay and curve functions.

  6. v-leave-to2.1.8 and aboveDefine the end state of the exit transition. The next frame takes effect after the exit transition is triggered (at the same timev-leaveRemoved) after the transition/animation is complete.

1.1 Preliminary code implementation


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<style>
    div>div{
        width:100px;height: 100px;background: red;
    }
    .v-enter{
        opacity: 1;
    }
    /* When activated */
    .v-enter-avtive{
        opacity: 0;
        transition: 1s linear;
    }
    / * * / leave
    .v-leave-active{
        opacity: 0;
        background: black;
        transition: 1s linear;
    }
</style>
<body>
    <div id="app">
        <button @click="flag=! flag">switch</button>
        <! Vue custom components -->
        <transition>
            <div v-show="flag"></div>
        </transition>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            flag:true}})</script>
</html>
Copy the code

More than 1.2 the transition

When there are multiple transitions, the same class conflicts with each other


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<style>
    div>div{
        width:100px;height: 100px;background: red;
    }
    .jw-enter-active {
        transition: all .3s ease;
    }
    .jw-leave-active {
        transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .jw-enter..jw-leave-to
    {
        transform: translateX(10px);
        opacity: 0;
    }
</style>
<body>
    <div id="app">
        <button @click="flag=! flag">switch</button>

        <! Vue custom components -->
        <transition name="jw">
            <div v-show="flag"></div>
        </transition>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            flag:true}})</script>
</html>
Copy the code

Transition has a name property that is called in the CSS name- state

22 Self-defined directives – Directives

1 introduction

Vue also allows you to register custom directives. Note that in VU 2.0, the main form of code reuse and abstraction is components. However, there are cases where you still need to perform low-level operations on normal DOM elements, and custom directives are used. Here’s a chestnut:

<! DOCTYPE html><html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<body>
    <div id="app">
       <div v-color='flag'>123</div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
        directives:{
            color(el,bindings){ // The el value refers to the button
                console.log(arguments); el.style.background = bindings.value; }},el: '#app'.data: {
            flag: 'red'
        },
        methods:{
            getSomething(){
                return "hello"}}})</script>
</html>
Copy the code

As shown in the figure

Another chestnut


      
<html>
<head>
    <meta charset="utf-8" />
    <title>vue</title>
</head>
<style>
    .a{
        position: absolute;width: 100px;height: 100px;background: red;
    }
</style>
<body>
    <div id="app">
       <div class="a" v-drag></div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
    var vm = new Vue({
        directives:{
            drag(el){
                el.onmousedown = function (e) {
                    var disx = e.pageX - el.offsetLeft;
                    var disy = e.pageY - el.offsetTop;
                    document.onmousemove = function (e) {
                        el.style.left = e.pageX - disx +'px';
                        el.style.top = e.pageX - disy + 'px';
                    }

                    document.onmouseup = function (e) {
                        document.onmousemove = document.onmousemove = null; } e.preventDefault(); }}},el: '#app'.data: {
            flag: 'red'
        },
        methods:{
            getSomething(){
                return "hello"}}})</script>
</html>
Copy the code

Can drag

2 Hook function

An instruction definition object can optionally provide the following hook functions: bind: called only once, when the instruction is first bound to an element. This is where you can perform one-time initialization Settings.

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

Update: called when the component’s VNode is updated, but may occur before its child VNodes are updated. The value of the instruction may or may not have changed. However, you can ignore unnecessary template updates by comparing the values before and after the update (see below for detailed hook function parameters).

3 Hook function parameters

  • el: the element bound by the directive that can be used to manipulate the DOM directly.
  • binding: an object containing the following properties:
    • name: Indicates the command namev-Prefix.
    • value: The binding value of the directive, for example:v-my-directive="1 + 1", the binding value is2.
    • oldValue: The value preceding the instruction binding, only inupdate 和 componentUpdatedHooks are available. Available regardless of whether the value changes.
    • expression: Command expression in the form of a string. For example,v-my-directive="1 + 1"Where, the expression is"1 + 1".
    • arg: Optional parameter passed to the instruction. For example,v-my-directive:fooWhere, the parameter is"foo".
    • modifiers: an object that contains modifiers. Such as:v-my-directive.foo.bar, the modifier object is{ foo: true, bar: true }.
  • oldVnode: Indicates the last virtual nodeupdate 和 componentUpdatedHooks are available.

23 Instance attribute -$ref

The official website explains -ref

  • expected:string

    refIs used to register reference information for an element or child component. Reference information will be registered in the parent component’s$refsOn the object. If used on a normal DOM element, the reference refers to the DOM element. If used on a child component, the reference refers to the component instance:
<! -- `vm.$refs.p` will be the DOM node -->
<p ref="p">hello</p> <! -- `vm.$refs.child` will be the child component instance -->
<child-component ref="child"></child-component>
Copy the code
  • whenv-forWhen applied to an element or component, the reference information will be an array containing the DOM node or component instance.

    Important note about ref registration times: Because ref’s are themselves created as render results, you can’t access them during initial render – they don’t exist yet!$refsIt is not reactive, so you should not try to use it to do data binding in templates.

Operating the dom

You can manipulate the DOM in general if you use jQuery

$("#id").text('xxx')   / / using Jquery
document.getElementById("id")  // Use native Dom
Copy the code

Now that we’re awesome, we use VUE. So in VUE, what do I do if I want to get the Dom? Ref, $refs = ref, $refs

<div id="app">
   <div>{{msg}}</div>
</div>
Copy the code

We are accustomed to use the document in JavaScript. The getElementsByTagName


Vue dom operation

So we are in VUE

<div id="app">
   <div ref="msg">{{msg}}</div>
</div>
Copy the code

    var vm = new Vue({
      el: '#app'.data: {msg:'hello'
      },
      mounted() {
        // console.log(document.getElementsByTagName("div")[0].innerHTML);
        console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
        console.log(this.$refs.msg);
        console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ='); }})Copy the code