I learned the Vue framework some time ago, so I sorted out some points needing attention about Vue in the learning process. I may keep updating this BLOG based on Vue in the future according to the project I have developed. Welcome to exchange

1. The MVVM Vue

Those of us who have used Vue know that Vue is a framework developed using the MVVM pattern, but where does it fit in?

As shown above:

View layer: This is what we call the View layer, which is our BOM. It is mainly used to present data to users

Model layer: The data layer, which may be the dead data we are given, but is most likely to be requested from the server side during development

View-model layer: The view-model layer is the bridge between View and model. It mainly realizes data binding and dynamic monitoring of data, and realizes responsive datamation.

2. The methods and computed

In the options option of vue, except method method can handle our logic, calculation properties can also do the same thing, it seems that they are very similar, in fact, they are different. So what’s the difference between these two approaches.

  1. You do not need to write attributes in the form of calls, whereas methods must be usedMethod ()Form of call
  2. The calculated property depends on the change in data. If data does not change, the calculated property will take the cached result, that is to say, the calculated property has the caching function.
  3. The method method is called again regardless of whether the value in data is changed. That is, implement it as many times as you call it, so it’s wasteful

3. V-on parameter transfer problem and common modifiers

V-on is often used to handle some event-listening operations. Its syntactic sugar is the @ event

3.1 Parameter transfer problem

We often embed methods in events when we use V-Ons to handle events. There are three cases.

  1. When no arguments are passed, parentheses may or may not be used, but a parameter may be added to the method implementation to indicate that the event precedes it.
  <div class="box">
    <button @click='btnclivk'></button>
  </div>
Copy the code
btnclivk(e){ console.log(e); // Current event object}Copy the code
  1. When passing ordinary arguments, just as you would normally use a function, it is important to note that the arguments are either primitive data types or must be variables in data
  2. The event parameter is also needed when passing normal parameters, which is passed in$event() is a fixed notation for the current event object

3.2 Common modifiers

  1. V-on: event stop: prevents the event from bubbling
  2. V-on: event prevent: prevents the default behavior
  3. V-on: events {keycode}: wait for a specified key to trigger
  4. V-on: events once: events are triggered only once
  5. V-on: event native: listens to the native of components and elements

5. Difference between V-if and V-show

First, it should be clear that v-if and V-show are both used to handle whether or not the DOM is displayed, so we need to understand how they differ here.

**v-if: ** When v-if is used, the dom will be deleted when the value is false, and the DOM will be created when the value is true

** V-show: ** When used, the CSS style display: None is usually used to handle whether it is visible or not

Common usage:

We usually use V-if when we need to repeat show and hide operations in the interface, because it is more efficient.

We usually select V-if to operate when there is only one switch.

6. Differences between binding keys and non-binding keys in V-for

First imagine a scenario where we want to display an array on the LI tag and use V-for to operate on the LI tag. But what happens when I have a requirement: you need to insert something in the middle of an array.

At this point we might want to just insert the content into the array. But have you considered a question. At the bottom of Vue.

In fact, Vue uses the virtual DOM underneath to do this, but when we insert it in the middle, something like this might happen:

Except for the previous dom reuse, all the remaining data will be re-rendered.

For example, if our current array is [a,b,c, D,e], when we now add an f after b. Then the default operation is c — >f, D — >c,e — > D, and finally insert e. This feels inefficient. As shown below:

Therefore, the official recommendation is to use the binding key, whose value is usually a unique identifier (note that index is not used: index changes after inserting elements, so it is meaningless). In this way, diff algorithm can find the same reusable DOM for rendering, that is, we have a key li to match

And finally, insert our node to be inserted. That saves a lot of efficiency.

So in a word, the key’s main purpose is to update the virtual DOM efficiently.

7. Which array methods in Vue are reactive

One of the main reasons we found it so convenient to use Vue again is that it refreshes data in a responsive manner.

So when we use arrays, what are the ways that we can be data responsive?

push()
pop()
shift()
unshift()
splice() 
sort()
reverse()
Vue.set()
Copy the code

Main: Data responsiveness cannot be achieved through arrays directly.

8. Use of V-model two-way binding

8.1 When used for forms

V-models are commonly used in forms to achieve two-way binding, which enables real-time updates of operations and data, and to achieve responsiveness.

This means that when we enter data into a form, the data actually changes directly.

lizi :

	<input type="text" v-model='message'>
    <p>{{message}}</p>
Copy the code

The above example can realize that when we input data, message will change in real time, and the content of the corresponding P tag will also change.

In fact v-Model is the syntactic sugar for the following two operations:

  1. V-bind binds data to value
  2. V-on: Input triggers events for the form binding to pass values to Message.
 <input type="text" :value='message' @input='message=$event.target.value'>
 <p>{{message}}</p>
Copy the code

In addition to text, V-model is often used in select, CHacked, radio.

Decorator:

Here are its three modifiers

  1. V-model. lazy: Indicates that data is not updated in real time. Data is updated only when the user enters or the input is out of focus
  2. V-model. number: By default v-model is a string of type. This modifier can return a number
  3. V – model. The trim: go to space

9. Why must data be a function type in a component

First of all, vUE components are mostly used for reuse, so every time it is reused, it will use our data attribute. If data is an object at this time, there will be a problem when we reuse components. Data in one component changes, so data in all components will change. So vUE’s bottom layer adds this setting to the data property.

Of course, this property can also be encountered during development, which can expose the object and then introduce it to achieve consistency of all component data.

Let’s look at a very simple example:

Write a counter component

 Vue.component('mycom', {
    template: '#mypom'.data() {
      return {
        message: 0}},methods: {
      add() {
        this.message++
      },
      decre() {
        this.message--
      },
    },
  })
Copy the code

Use:

<div id="app">
    <mycom></mycom>
    <mycom></mycom>
    <mycom></mycom>
    <mycom></mycom>
  </div>
Copy the code

And then we see that each component is independent, and that’s because, this is due to the data property being a function. Therefore, they do not share data within an object.

But it’s also easy if we have this need for one move, all moves.

  var obj={
    message: 0
  }
  Vue.component('mycom', {
    template: '#mypom'.data() {
      return obj
    },
    methods: {
      add() {
        this.message++
      },
      decre() {
        this.message--
      },
    },
  })
Copy the code

That’s what we want to do.

10. Complex bidirectional binding between parent and child components

One requirement: You now have two inputs in the component, and you need to implement bidirectional binding of inputs (and change the data value of the parent component), and output the value of the second input as 100 times the second value.

Technical points used: parent-child component communication, bidirectional binding of forms

It is worth mentioning that we do not recommend putting the props values directly in the model when we use the model, because this value is passed from the parent component, so it might be messy to change it directly. Therefore, we need to use the data property of the component to do worthy binding;

To change the properties of data, we can pass the component’s data to the parent and then modify the value of the parent’s data. In this way, we can also modify the parent’s data and the related values of the child component’s props.

The final requirement is 100x, which also listens when our input event fires, then evaluates, and then passes via emit

<! DOCTYPEhtml>
<html lang="en">

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

<body>
  <div id="app">
    <mycon :cnum1='num1' :cnum2='num2' @event1='event1' @event2='event2'></mycon>
  </div>
  <template id="cpm">
    <div>
      <p>props:{{cnum1}}</p>
      <p>data:{{copycnum1}}</p>
      <input type="text" name="" id="" :value='copycnum1' @input='docopycnum1'>
      <p>props{{cnum2}}</p>
      <p>data{{copycnum2}}</p>
      <input type="text" name="" id="" :value='copycnum2' @input='docopycnum2'>
    </div>
  </template>
</body>
<script src=".. /vue.js"></script>
<script>
  var cpm = {
    template: '#cpm'.props: {
      cnum1: Number.cnum2: Number,},data() {
      // The official recommended practice
      return {
        copycnum1: this.cnum1,
        copycnum2: this.cnum2,
      }
    },
    methods: {
      docopycnum1(event) {
        this.copycnum1 = event.target.value;
        this.$emit('event1'.this.copycnum1);
        this.copycnum2=this.copycnum1*100
        this.$emit('event2'.this.copycnum2)
      },
      docopycnum2(event) {
        this.copycnum2 = event.target.value;
        this.$emit('event2'.this.copycnum2)
        this.copycnum1=this.copycnum2/100
        this.$emit('event1'.this.copycnum1)
      }
    },
  }
  new Vue({
    el: '#app'.data: {
      num1: 0.num2: 0
    },
    components: {
      mycon: cpm
    },
    methods: {
      event1(data) {
        this.num1 = parseFloat(data);
      },
      event2(data) {
        this.num2 = parseFloat(data); }}})</script>

</html>
Copy the code

11. Precautions when using Webpack for vue

First of all, we need a VUE environment in our project.

NPM install:

npm install vue --save
Copy the code

After installation, we will directly write the vUE related code and compile it, and we will find an error:

The reason for this error is that there are two versions of Vue in the build release, runtime-only and Runtime-compiler.

** Runtime-only: ** This version cannot have any template

Runtime -compiler: Templates can be used in code because templates can be compiled with compiler

Solution (added in the WebPack configuration file) :

 resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'}}Copy the code

Resolve resolves to resolve path issues, so we can guess that this changes the default configuration

11.2 Compiling a VUE File

To package vUE files in WebPack, we need to install the VUe-Loader plug-in and vue-template-Compiler plug-in

Then configure in the configuration file:

  module: {
    rules: [{test: /\.vue$/,
        use: ['vue-loader']]}},Copy the code

After using it, we will find an error.

Vueloader is not available and a plugin is missing.

We can configure a plugin (no installation required) :

const VueLoaderPlugin = require('vue-loader/lib/plugin');
  plugins: [
    newVueLoaderPlugin(), ... ] .Copy the code

12. Difference between run-time Compiler and Run-time Only

When building a project using VUE CLI2, we are often asked to choose the VUE build mode. When we create two projects, we’ll notice that the main.js file in the SRC directory is different

The Runtime – Compiler mode:

import App from './App';
new Vue({
  el: '#app'.components: { App },
  template: '<App/>'});Copy the code

The Runtime read-only mode:

import App from './App';
new Vue({
  el: '#app'.render:h= >h(app)
});
Copy the code

We find that the two modes are written differently in the Vue instance. We find that run-time Compiler mode is used in the normal way of registering components, while run-time only uses the render function. So what is the difference between the two modes?

Here is the rendering of a template in Vue:

Ast: The result of template parsing, abstract syntax tree

Render function: the ast is compiled to generate a virtual DOM

Virtual DOM: indicates the virtual DOM

Template ->ast->render function -> virtual DOM -> Render to UI

However, we use the second run-time Only to start directly at the node of the render function.

Conclusion: Run-time Only is more efficient than Run-time Compiler, with less source code and lighter volume after packaging.

Runtime-only: Template is compiled with the render function runtime-only: Template is compiled with the render function run-time

Therefore, we recommend using runtime-only mode to build our project.

About the Render function:

1. Pass our component object directly to our callback function in render.

new Vue({
  el: '#app'.// components: { App },
  // template: '<App/>',
  render:(e) = > {
    return e(App)
  }
});
Copy the code

2. Pass in the basic DOM:

 render:(e) = > {
    return e('div', {class:'box'},'web'])}Copy the code

The first parameter is a DOM element, the second parameter is an attribute value, and the third parameter is data.

13. Vue – the router lazy loading

The official explanation for lazy loading of routes is:

JavaScript packages can become very large when packaged to build applications, affecting page loads. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed.

Actually means that we each routing corresponding is a show user page, but according to the normal operating these pages may end webpack packaged as a bundle of js file, which caused the page is very huge, where the request may take some time, bad to cause the user experience. So we can solve this problem by routing lazy loading. This means that different routing pages are packaged into different JS files, which eliminates the server’s time consuming problem.

When we did not use lazy loading, the packaged Vue project would generate three files, one is all the business code of the APP, one is the code of the organization and management module relationship, and one is the code of the third party introduced by the project.

Then let’s look at the way lazy loading is implemented: there are three ways to combine asynchronous components, AMD way, es6 modular way

In ES6, we can write a much simpler way to organize code splitting between Vue asynchronous components and Webpack. So we did it the simplest way:

 component: () = > import('.. /components/about.vue') 
Copy the code

Example:

 routes: [
    {
      path: '/'.redirect: '/home'
    },
    {
      path: '/hello'.component: () = >import('.. /components/HelloWorld.vue')}, {path: '/home'.component: () = > import('.. /components/home.vue')}, {path: '/about'.component: () = > import('.. /components/about.vue')}, {path: '/person/:userid'.component: () = > import('.. /components/person.vue')},Copy the code

We found that each routing interface has a JS file, which allows us to load on demand and takes the strain off the server