Vue series: core concepts and features of Vue

Keywords: Javascript Vue Vue.js mvc

Hello, I'm front-end Fengfen, a program of second-line city. The second half of the year is a special month for us. At the end of July, Zhengzhou experienced many years of unexpected floods, unable to travel, resting at home, an epidemic occurred in August, working at home for a month, the epidemic in September passed, and finally came to work in the company. The blog has been abandoned for some time, and next, I willUpdate some vue related articles one after another to work hard with the family

Vue (pronunciation/vju/, similar to view) is a progressive framework for building user interfaces.
Features: Easy to use, flexible and efficient incremental framework

You can freely combine the required modules vue + components + vue-router + vuex + vue-cli

I. Concepts and characteristics of Vue

1. What is a library and what is a framework?

  • Libraries are collections of code into a product, and libraries are methods that we call into libraries to implement our own functions.
  • Framework is a product developed to solve a type of problem. Framework is where we write code and it calls for us.

The most essential difference between a framework and a library is control: you call libs, frameworks call you

Vue belongs to framework

2.MVC Model & MVVM Model

  1. M: Model: Data in the corresponding data
  2. V: View: Template
  3. VM: ViewModel: Vue Instance Object

In traditional mvc, logic other than model and view is placed in the controller, which makes the controller logic complex and difficult to maintain. There is no direct relationship between view and model in mvm, all interact through viewModel

Vue is MVVM mode

3. Declarative and imperative

  • Writing a for loop on your own is command (commanding it to get results the way you want)
  • Declarative means using the array method forEach (what we want is a loop, do it internally for us)

2. Basic use of Vue

1.mustache syntax

Allows developers to declaratively bind DOM to data from underlying Vue instances. Data needs to be declared before it can be used

  • Writing ternary expressions
  • Get Return Value
  • JavaScript expression
<div id="app">
    {{ 1+1 }}
    {{ msg == 'hello'?'yes':'no' }}
    {{ {name:1} }}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
    el:'#app',
    data:{
        msg:'hello'
    }
})
</script>

2. Responsive data changes

Vue uses Object.defineProperty to redefine attributes in objects, rewriting methods on the array prototype if it is an array

function notify() {
    console.log('View Update')
}
let data = {
    name: 'jw',
    age: 18,
    arr: [1,2,3]
}
// Method of overriding arrays
let oldProtoMehtods = Array.prototype;
let proto = Object.create(oldProtoMehtods);
['push', 'pop', 'shift', 'unshift'].forEach(method => {
    proto[method] = function (...args) {
        let inserted;
        switch (method) {
            case 'push':
            case 'unshift':
                inserted = args;
                break;
        }
        observerArray(inserted)
        notify();
        oldProtoMehtods[method].call(this, ...args)
    }
})
function observerArray(obj) { // Observe each item in the array
    for (let i = 0; i < obj.length; i++) {
        observer(obj[i]);
    }
}
function observer(obj) {
    if(typeof obj !== 'object'){
        return obj
    }
    if (Array.isArray(obj)) {
        obj.__proto__ = proto
        observerArray(obj);
    }else{
        for (let key in obj) {
            defineReactive(obj, key, obj[key]);
        }
    }
}
function defineReactive(obj, key, value) {
    observer(value); // Loop value again
    Object.defineProperty(obj, key, { // Arrays are not supported
        get() {
            return value;
        },
        set(val) {
            notify();
            observer(val);
            value = val;
        }
    });
}
observer(data);
data.arr.push({name:'jw'})
console.log(data.arr);

defect

  • You cannot change the array by length, index
  • You cannot add attributes to an object
  • Responsive data needs to be forced to be added/deleted through the vm.$set and vm.$delete methods

‚Äč

Features: When using an object, you must first declare an attribute, which is responsive.

  • Adding attributes that do not exist does not update the view (vm.$set)
  • By default, getter s and setter s are added recursively
  • Objects in arrays support responsive change, but have no effect if they are constant
  • Modifying the array index and length will not result in view updates
  • If the new data vue also helps you monitor (object type)

3. Methods on the Vue instance

  • vm.$el;
  • vm.$data;
  • vm.$options;
  • vm.$nextTick();
  • vm.$mount();
  • vm.$watch();
  • vm.$set();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">{{name}} {{age.age}}</div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el:'#app',
            data(){
                return {name:'zf',age:{}}
            }
        });
        // 1) vue has a feature that it will not re-render dom during this round of code execution
        // 2) Execute in the next event ring (promie.then mutationobserver setimmediate settimeout)

        // This will wait for the data to be updated before calling the callback function again
        // Views are updated asynchronously
        vm.$watch("name",function (newValue,oldValue) {
         console.log(newValue,'after');
        });

        // vm.name = 'jw';
        // vm.name = 'zf1';
        // When the data is updated, a queue places the callback of the watch in the queue, overlaying the nextTick backwards
        vm.$nextTick(()=>{
            console.log(vm.$el.innerHTML); // True dom after rendering
        });
        console.log('vm Data',vm.$data); // Data representing the current instance
        console.log('vm In options',vm.$options);

        // vm.$set vm.$delete helps me update my properties 
        // New attributes will not result in view updates, and changing array indexes will not update 
        // vm.age.age = 100;
        vm.$set(vm.age,'age',100); // Object.defineProperty
        // vm.$set([1,2,3],'0',100);

        // vm.$el
        // vm.$options
        // vm.$watch
        // vm.$nextTick
        // vm.$set
    </script>
</body>
</html>

3. Instructions in Vue

Directives in vue is a special feature with v-prefix, the main function is to operate DOM

1.v-once

<div v-once>{{state.count}} </div>

2.v-html

Never use v-html for user input, which can lead to xss attacks

<div v-html="text"></div>

3.v-bind

Dynamic binding properties require v-bind binding

<img v-bind:src="src">

You can use:to abbreviate v-bind

4.v-for

<template v-for="(fruit,index) in fruits" >
    <li :key="`item_${index}`">{{fruit}}</li>
    <li :key="`fruit_${index}`">{{fruit}}</li>
</template>

The template tag is added to the outer layer when multiple elements are looping, the key is added to the real element, and the key cannot be duplicated. Try not to use the index as the value of the key

Take an example of a key value:

5.v-if/v-else/v-show

v-if toggles the existence of DOM elements and internal instructions are not executed when v-if is false
v-show controls the display and hiding of elements, mainly the style of elements

6.v-on

  • Event Binding v-on Binding Event
  • Event modifier (.stop.prevent).Capture.self.once.passive

7.v-model

Bidirectional data binding

<input type="text" :value="value" @input="input">
<input type="text" v-model="value">
  • select
<select v-model="select">
    <option 
        v-for="fruit in fruits"
        :value="fruit">
            {{fruit}}
    </option>
</select>
  • radio
 <input type="radio" v-model="value"  value="male">
 <input type="radio" v-model="value"  value="female">
  • checkbox
<input type="checkbox" v-model="checks" value="Swimming" >
<input type="checkbox" v-model="checks" value="Bodybuilding">
  • Modifier application.number.lazy.trim
<input type="text" v-model.number="value">
<input type="text" v-model.trim="value">
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- {{}} The beard grammar value can be computed (and returned) to make a ternary expression -->
        {{name}}
        {{1+1}}
        {{[1,2,3]}}
        {{true?'yes':null}}
        <!-- Objects must be separated by spaces -->
        {{ {name:'123'} }}
        <span v-once>Once {{name}}</span>
        <!-- Do not display user input on the page xss attack -->
        <!-- The data returned by the backend can be passed through v-html To format -->
        <span v-html="tmp"></span>
        <!-- Dynamic Binding -->
        <div v-bind:title="name">Hello</div>
        <!-- Binding is a variable property -->
        <div :title="name">Hello</div>

        <!-- v-for Loop Data Array Object Number (Character string) -->
        <!-- Whoever loops will v-for To whom -->

        <!-- vue Of key What is the purpose of distinguishing elements,If I have a button to reverse the order -->
        <!-- Only static presentations can use this index to use unique key To distinguish elements-->
        <!-- You can stitch up some content by yourself each time you cycle to ensure uniqueness -->
        No Rendering
        <div v-if="false">
            <template v-for="(fruit,index) in arr" >
                <li :key="`name_${index}`">
                    {{fruit.name}}
                </li>
                <li :key="`color_${index}`">
                    {{fruit.color}}
                </li>
            </template>
        </div>
        <!-- v-if (operation dom Is it displayed))  v-show(Show Hide style) -->
        <!-- The function of an instruction is to encapsulate dom Operational --> 
        <!-- v-for and v-if Don't use them together -->
        <!-- v-show Cannot and template Use together -->

        <!-- vue The default reuse policy is to reuse code -->
        <template v-if="isShow">
            <span>Hello</span>
            <input type="text" key="1">
        </template>
        <template v-else>
            <span>not good</span>
            <input type="text" key="2">
        </template>

        <!-- Bidirectional binding As long as the component can be changed, bi-directional binding is also possible -->
        <br>
        <!-- How to Bind Methods v-on yes@QuanPin-->
        <!-- $event Refers to the source of the event -->
        <input type="text" :value="value" @input="fn($event)">
        <!-- Very Long -->
        <input type="text" :value="value" @input="e=>value=e.target.value">

        <!-- v-model He is the abbreviated grammar sugar above -->
        <input type="text" v-model="value">
        {{value}}
    </div>
    <!-- 
        v-once
        v-html
        v-bind
        v-for
        v-if / else show
        v-model Binding in both directions
     -->
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el: '#app',
            methods:{// By turning this of all methods into vm,bind will not work multiple times
                fn(e){ // this all refers to window
                     this.value = e.target.value
                }
            },
            data() {
                return {
                    value:'Hello',
                    isShow:true,
                    tmp:'<h1>I am very handsome</h1>',
                    name: 'zf',
                    arr:[{name:'A mandarin orange',color:'green'},{name:'Banana',color:' yellow'}]
                }
            }
        });
    </script>
</body>
</html>

4. Custom directives

  • Global and local directives
  • Write a custom instruction
    • Hook function bind, inserted, update
    <input type="text" v-focus.color="'red'">
    Vue.directive('focus',{
        inserted:(el,bindings)=>{
            let color = bindings.modifiers.color;
            if(color){
                el.style.boxShadow = `1px 1px 2px ${bindings.value}`
            }   
            el.focus();
        }
    });
  • clickoutside directive
    <div v-click-outside="change">
        <input type="text"  @focus="flag=true" >
        <div v-show="flag">
            contenter
        </div>
    </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                flag:false
            },
            methods:{
                change(){
                    this.flag = false
                }
            },
            directives:{
                'click-outside'(el,bindings,vnode){
                    document.addEventListener('click',(e)=>{
                        if(!el.contains(e.target,vnode)){
                            let eventName = bindings.expression;
                            vnode.context[eventName]()
                        }
                    })
                }
            }
        })
    </script>

V. Life cycle in Vue

  • beforeCreate is called after instance initialization, before data observer and event/watcher event configuration.
  • The created instance is called after it has been created. In this step, the instance has completed the following configuration: data observer, operation of properties and methods, watch/event callback. There is no $el here
  • beforeMount is called before mounting begins: the related render function is called for the first time.
  • mounted el is replaced by the newly created vm.$el, mounted onto the instance, and then called the hook.
  • Called when the beforeUpdate data is updated, before the virtual DOM is re-rendered and patched.
  • updated renders and patches the virtual DOM as a result of data changes and then calls the hook.
  • Called before the beforeDestroy instance is destroyed. At this step, the instance is still fully available.
  • Called after the destroyed Vue instance is destroyed. When called, everything indicated by the Vue instance is unbound, all event listeners are removed, and all child instances are destroyed. The hook is not called during server-side rendering.

What to do in the hook function

  • The created instance has been created because it was the earliest trigger for some data, resource requests.
  • The mounted instance has been mounted and some DOM operations are possible
  • beforeUpdate can further change the state in this hook, which will not trigger additional rendering processes.
  • updated can perform DOM-dependent operations. However, in most cases, you should avoid changing state during this time, as this may result in an infinite loop of updates. The hook is not called during server-side rendering.
  • destroyed can perform some optimizations, empty the timer, unbind events

Posted by fullyscintilla on Sun, 19 Sep 2021 01:02:01 -0700