[TOC]

This is a technical document of the first training course of Vue training for my company’s back-end colleagues, aiming to guide them to get into the development world of Vue and release more front-end resources. Now open out for industry members of the technical advice or supplement, thank you ~ the following documents with code together to demonstrate and explain the effect better. Code address: vue-coe-test code address

Create the first VUE instance

Create a VUE project using the following command line

$ npm install -g vue-cli
$ vue init webpack vue-coe-test
$ cd vue-coe-test
$ npm install
$ npm run dev
Copy the code

Mount points, templates, instances

Official Documentation

### // App.vue
<div id="app"></div>

//main.js
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<h1>{{ msg }}</h1>'.data () {
    return {
      msg: 'Hello,my first Vue.js App'}}})Copy the code
  • The mount point is the DOM node corresponding to the EL attribute in the Vue instance.
  • Templates are the contents of mount points and can also be written to the instance template.
  • The new instance is a DOM node, a template content, and a data attribute. Vue automatically generates dynamic data to be placed in the mount point.

Basic data expressions:

Official document – Interpolate official document – V-text & V-html

  • {{ data }}
  • v-text
  • v-html
<h1>{{ msg }}</h1>
<div v-text="text"></div>
<div v-html="text"></div>
Copy the code
data () {
  return {
    msg: 'Welcome to Your Vue.js App',
    text: '<div style="color: red">I am red</div>'}},Copy the code

Property binding and bidirectional data binding in Vue

<div v-bind:title="title" v-bind:class="[{ active: isActive }, 'title']"> < div style = "box-sizing: border-box! Important;data () {
  return {
    title: 'Big Ice's best Seller'}}Copy the code

So what is bidirectional binding?

Two-way data binding means that data can determine the display of the page, and the operation of the page can also change the data.

<input type="text" v-model="title">
data () {
  return {
    title: 'Big Ice's best Seller'}},Copy the code

Common commands in VUE

Directives are special and v-prefixed. The value of the directive property is expected to be a single JavaScript expression (v-for is the exception, which we’ll discuss later). The directive’s job is to react to the DOM with the collateral effects of changing the value of an expression.

v-bind

The official documentation

Dynamically bind one or more properties, or a component prop, to an expression.

<a v-bind:href="url">... </a> <! <a :href="url">... </a>Copy the code

Here the href is the argument that tells the V-bind directive to bind the element’s href property to the value of the expression URL.

<! --> <div v-bind:class="[{ active: isActive }, errorClass]"></div>
Copy the code
data: {
  isActive: true,
  errorClass: 'text-danger'
}
Copy the code

In this case, the class is responsive, showing the corresponding class according to the value in the data, of course, you can also add the specified class.

V-show, V-if, V-for

Official documentation – V-show & V-if

Official documentation – V-for

V-if is “true” conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch. V-if is also lazy: if the condition is false during initial rendering, nothing is done — the conditional block is not rendered until the condition is true for the first time. V-show, by contrast, is much simpler — elements are always rendered regardless of initial conditions and simply switch based on CSS. In general, V-if has a higher switching overhead, while V-show has a higher initial rendering overhead. Therefore, v-show is good if you need to switch very frequently; It is better to use V-if if conditions rarely change at run time.

  • Examples (see official documentation for more usage)

HTML

<! Q: What line do orangutans hate the most? </h2> <div> <button :class="[{active: item.active}, 'js-button btn-answer']" v-for="item, index in btns" @click="clickHandle(index)">{{item.text}}</button>
    </div>
    <div class="js-answer"></div>
    <div v-show="show">
       <div v-if="answer == 0"> bingo! Parallel lines do not intersect (banana) </div> <div v-else-if="answer == 1"</div> <div v-else> </div> </div> </div> </div> </div> -- twig --> {%set items = ['A, parallel '.'B, line segment '.'C, cross line '] %}
{% for item in items %}
    <button class="js-button btn-answer"
        {{ item }}
    </button>
{% endfor %}
<div class="js-answer"></div>
Copy the code

data

data () {
    return {
        show: false,
        answer: 0,
        btns: [
        {
          key: 0,
          text: 'A, parallel ',
          active: false
        },
        {
          key: 1,
          text: 'B, line segment ',
          active: false
        },
        {
          key: 2,
          text: 'C, cross line ',
          active: false}}},Copy the code

js

<! -- jquery -->mounted() {$('.js-button').click(function(e) {
        let index = $(e.target).index();
        let answerText = ' ';
        index ? (answerText = "You must be a fake chimp.") : (answerText = 'bingo! Parallel lines do not intersect (banana) '.The $()'.js-answer').text(answerText);
        $(this).addClass('active').siblings().removeClass('active'); })}, <! -- vue --> methods: { clickHandle(index) { this.show =true;
        this.answer = index;
        this.btns.forEach( item=> {
            if (item.key == index) {
              item.active = true;
            } else {
              item.active = false; }}}})Copy the code

v-on

The official documentation

Bind event listeners. The event type is specified by the parameter. The expression can be the name of a method or an inline statement, or it can be omitted if there are no modifiers.

<! <button V-on :click="doThis"></button> <! < button@click ="doThis"></button> <! <button V-on :click= button V-on :click="doThat('hello', $event)"></button> <! Listen for custom events on child components (event handlers are called when a child component fires "my-event") --> <my-component @my-event="handleThis"></my-component>
Copy the code

Methods and events in vUE instances

The official documentation

Data transmission method

$emitwith$onTo transfer data between components

  • 1. Parent component communicates with child component

  • 2. Communication between child components and parent components

  • 3. Communication between sibling components

vm.$on( event, callback )

Listen for custom events on the current instance. Events can be emitted by vm.$emit. The callback function receives any additional arguments that are passed in to the event that triggers the function.

Vm. $emit (eventName, args […])

Triggers events on the current instance. Additional parameters are passed to the listener callback.

vm.$emit('test'.'hi')

vm.$on('test'.function (msg) {
  console.log(msg)   // hi
})
Copy the code

Father and son communicate, son and father communicate, brother communicate

Code demo

  • Parent-child communication

The first is that a parent component passes children to children, using props

<! --> <child :sonMsg="msg"></child>

// js
import child from './children.vue';

export default {
  components: {
    child
  }
}
Copy the code
<! // HTML <div class="children-text">{{sonMsg}}</div>

// js
export default {
  props: {
    sonMsg: {
      type: String,
      default: 'Default values for parent component data'}}}Copy the code

Second: use$refsTo transmit data

<! Parent component --> // HTML <inputtype="button" @click="parentEnvet" value="Parent component trigger" />
<child ref="childcomp"></child>

// js
import child from './children.vue';

export default {
  components: {
    child
  },
  methods: {
    parentEnvet() {// Note that childFn is the existing method this in the child component.$refs.childcomp.childFn(); // Or write: this.$refs['childcomp'].childFn(); }}}Copy the code
<! // js methods: {childFn() {
      // do somethings
    }
  }
Copy the code

Third: use$emit and $onTransmission of data (including parent-child communication)

<! // HTML <div class="parent-box">
    <div class="mb20" v-text="vals"></div>
</div>
<div class="children-box">
    <child @showMsg="msgFromChild" :sonMsg="msg">
    </child>
</div>

// js
<script>
import child from './children.vue';

export default {
  components: {
    item
  },
  data () {
    return {
      vals: 'I'm going to show you the data that the child component sends me.',
      msg: 'I am the parent's data to be passed to the child.'}}, methods: {msgFromChild(data) {this.vals = data; } } } </script>Copy the code
<! HTML <div> <div class="children-text">{{parentMsg}}</div>
    <button @click="send"</button> </div> // js <script>export default {
  props: {
    parentMsg: {
      type: String,
      default: 'Default values for parent component data'}},data () {
    return {
      msg: 'I am so handsome.'
    }
  },
  methods: {
    send() {// Pass the data this to the parent component.$emit('showMsg', this.msg)
    }
  }
}
</script>
Copy the code
  • Non-parent components communicate

Consider: Now that you know about parent-child communication, what do you think communication between non-parent-child components should look like?

To transfer values between non-parent and child components, you need to define a common instance file, bus.js, as the intermediate repository for transferring values; otherwise, the effect of transferring values between routing components cannot be achieved.

1. Create a public instance file with the following contents:

// src/util/bus.js
import Vue from 'vue'

export default new Vue();
Copy the code

2. Import the public instance file (if named Bus) separately within the non-parent component

The A component uses Bus.$emit(‘fnName’, data) to emit data in the method

// component A <template> <div> <h3> </h3type="text" @change="saiHi" v-model="text"/>
  </div>
</template>

<script>
import Bus from '.. /util/bus.js';

export default {
  data () {
    return {
      text: 'Hello, I'm Peppa Pig A'
    }
  },
  methods: {
    saiHi() {
      Bus.$emit('saiHi', this.text);
    }
  }
}
</script>

Copy the code

Bus.$on(‘fnName’, (data) => {XXX})

Component B <template> <div> <div class="message-text" v-for="msg in msgs" v-text="msg.text"></div>
  </div>
</template>

<script>
import Bus from '.. /util/bus.js';

export default {
  data () {
    return {
      msgs: [{
        text: 'hello'}]}},mounted() {
    Bus.$on('saiHi', (data) => {
      this.msgs.push({text: data});
    })
  },
}
</script>
Copy the code

The Vue computes the properties computed and listens to the properties function watch

The official documentation

define

** Computed attributes: ** cached based on their dependencies. They are reevaluated only if the dependencies change. ** Listening properties: ** This is most useful when asynchronous or expensive operations need to be performed when data changes. It is often better to use computed properties rather than imperative Watch callbacks

Comparison between computed and Watch

<div id="demo">{{ fullName }}</div>
Copy the code
var vm = new Vue({
  el: '#demo',
  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 fullName attribute depends on firstName and lastName, and the downside is that whenever either firstName or lastName changes, a different listener is called to update the fullName attribute. But when we use computed properties, the code becomes much more concise.

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

In this case, we just listen for the fullName attribute, and any changes to the firstName or lastName attribute will get the final fullName value through the getter() method of the fullName. Note also that computed properties only have getters by default and cannot be assigned by this.xxx = ‘XXX’, but you can provide a setter if you want, allowing both getter() and setter() methods to be set. As follows:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
Copy the code
  • Similarities: First of all, they are based on Vue’s dependency tracking mechanism. What they have in common is that they all hope that when the dependent data changes, the dependent data will change “automatically” according to predefined functions.

  • Differences: Different data relation scenarios are processed by Watch and computed respectively (1) Scenarios that Watch is good at processing: one data affects multiple data. Suitable for monitoring scenarios, what operations need to be done when a variable changes; Similar to onchange, it is suitable for time-consuming operations such as network requests. (2) Scenarios that computed is good at handling: one data is affected by multiple data. When a variable changes, the [single] outcome of the influence changes correspondingly.

The life cycle

The official documentation

  • Before/after creation ** (beforeCreated/created) ** : In the beforeCreated phase, the mount element $EL and the data object data of the Vue instance are both undefined and not initialized. In the Created phase, the vue instance’s data object data is available, but $EL is not.

  • Before/after loading ** (beforeMount/ Mounted) ** : In the beforeMount phase, vue instance $EL and data are initialized, but the previously virtual DOM node is still mounted, data.message is not replaced. In mounted phase, vue instance is mounted and data.message is successfully rendered.

  • Before/After update ** (beforeUpdate/updated) ** : The beforeUpdate and updated methods are triggered when data changes.

  • Before/after destroy ** (beforeDestory/destroyed) ** : Changes to data do not trigger periodic functions after destroy, indicating that the vue instance has been unevent-listening and unbound to the DOM, but the DOM structure still exists