[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
$emit
with$on
To 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$refs
To 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 $on
Transmission 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