Vue passes the object Option
1. El:
- 1) type: string | HTMLElement
- Function: Determines which DOM object to manage
2. data:
- (1) type: Object | Function (component of the data must be a Function)
- ② Function: Data object corresponding to Vue instance
3. The methods:
- {[key:string]:Function}
- ② Function: define methods that belong to Vue, which can be called elsewhere or in instructions
4. Watch:
- 1) type: {[key: string] : the Function | Object}
- ② Function: listener function, monitoring a data or method changes and the implementation of the side effect
Vue basic syntax
1. Interpolation operation
1-1 Mustache Grammar (double brace)
Not only can you write variables directly, but you can also write simple expressions
<div id="app">
<! Mustache's syntax allows you to write not just variables directly, but also simple expressions -->
<h2>{{firstName + " " + lastName}}</h2> // kevin durant
<h2>{{firstName}} {{lastName}}</h2> // kevin durant
<h2>{{count * 2}}</h2>/ / 200</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {firstName:"kevin".lastName:"durant".count:100}})</script>
Copy the code
1-2, v – once
Render only once, not as data changes. It’s not followed by an expression.
1-3, v – HTML
Identifying HTML tags
<div id="app">
<h2 v-html="url"></h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {url:}})</script>
Copy the code
1-4, v – text
V-text is a little bit like Mustache: It’s used to put data in an interface and V-text usually takes a string
<div id="app">
<h2 v-text="message"></h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {message:"Hello?"}})</script>
Copy the code
But generally not, not flexible enough.
1-5, v – pre
Displays the text as it is, without following the expression
<div id="app">
<h2>{{message}}</h2>/ / hello<h2 v-pre>{{message}}</h2> // {{message}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {message:"Hello?"}})</script>
Copy the code
1-6, v – cloak
<div id='app' v-cloak></div>The div has the V-cloak attribute before vue parsing. The V-cloak attribute is deleted after vue parsingCopy the code
2. Bind properties
2-1, v – bind
V-bind is used to bind one or more property values, or to pass props to another component to dynamically bind properties, such as image link SRC, website link href, classes, styles, and so on.
v-bind | Value |
---|---|
role | Dynamically bound properties |
abbreviations | : (Grammar sugar) |
expected | any (with argument) |
parameter | attrOrProp (optional) |
<div id="app">
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHerf">The baidu</a>
<! -->
<img :src="imgURL" alt="">
<a :href="aHerf">The baidu</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app".data: {
imgURL: "https://cn.bing.com/th?id=OIP.NaSKiHPRcquisK2EehUI3gHaE8&pid=Api&rs=1".aHerf: "http://www.baidu.com"}})</script>
Copy the code
2-2, bind class
(1) Object syntax
:class=”{class name 1: Boolean, class name 2: Boolean}”
Normally, booleans are not assigned directly, but instead are assigned by variables.
<div id="app">
<! -- Dynamically binding class object usage -->
<! - < h2: class = "{name of the class 1: Boolean, the name of the class 2: Boolean}" > {{message}} < / h2 > -- >
<h2 :class="{active:isActive}">{{message}}</h2>
<button @click="change">Click on the color</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {message:"Hello?".active:"active".isActive:true
},
methods: {
change(){
this.isActive = !this.isActive
}
}
})
</script>
Copy the code
(2) Array syntax
:class=”[class name 1, class name 2]”; Variables are not quoted. It’s not usually used.
2-3, binding style
Use V-bind :style to bind some CSS inline styles.
When writing CSS property names, for example, font size ① we can use camelCase fontSize ② string form: kebab-case (remember to use single quotation marks) ‘font size’
(1) Object syntax
:style=”{key(attribute):value(attribute)}”
The key of the object is the name of the CSS property and the value of the object is the assigned value. The value can come from a property in data
<div id="app">
<! -- Parse as string with single quotes -->
<h2 :style="{fontSize:'50px'}">{{message}}</h2>
<! -- without single quotes, variable parsing -->
<h2 :style="{fontSize:fontSize}">{{message}}</h2>
<h2 :style="{fontSize:fontSize1 + 'px'}">{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {message:"Hello?".fontSize:'100px'.fontSize1:100}})</script>
Copy the code
(2) Array objects
<div id="app">
<h2 :style="[baseStyle1,baseStyle2]">{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {message:"Hello?".baseStyle1: {backgroundColor:'red'.fontSize:'100px'},
baseStyle2: {backgroundColor:'black'.fontSize:'50px'}}})</script>
Copy the code
3. Compute attributes computed
3-1, the foundation
It’s essentially a property, but it’s written like a function. When naming, try to use the form of attribute name, call is the call name, do not need to add parentheses ()
<div id="app">
<! -- Mastache syntax -->
<h2>{{firstName+ " " + lastName}}</h2> // Kevin Durant
<! Method - - - >
<h2>{{getFullName()}}</h2> // Kevin Durant
<! -- Calculate attributes -->
<h2>{{fullName}}</h2> // Kevin Durant
<! -- no need to add () -->
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {firstName:"Kevin".lastName:"Durant"
},
computed: {
fullName:function(){
return this.firstName + "" + this.lastName
}
},
methods: {
getFullName(){
return this.firstName + "" + this.lastName
}
},
})
</script>
Copy the code
3-2. Complex operations
<div id="app">
<h2>{{totalPrice}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".data: {books:[
{id:110.name:"JavaScript from the Ground up".price:1},
{id:111.name:"Java from entry to abandonment".price:2},
{id:112.name:"Code art".price:3},
{id:113.name:"Complete Code".price:4}},],computed: {
totalPrice(){
let result= 0;
for (let i = 0; i < this.books.length; i++) {
result += this.books[i].price;
}
return result
}
}
})
</script>
Copy the code
3-3, cache
Methods and computed seem to do what we do, so why have a computational property? Cause: The calculated property is cached. If it is used multiple times, the calculated property is called only once. Methods are used once and called once, so evaluating properties is relatively better.
3-4. Calculate the setter for the property
Computed properties only have getters by default, but setters can be provided if desired
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
4. Event monitoring
4-1. Introduction to V-ON
project | Value |
---|---|
role | Bind event listeners |
abbreviations | @ |
expected | Function, Inline Statement, Object |
parameter | event |
4-2. V-on parameters
When defining a method from methods for @click to call, you need to be aware of parameter issues:
- ① If the method does not require additional arguments, the () after the method may not be added. Note, however, that if the method itself has an argument, the native event argument is passed in by default
- If you need to pass in an event, you can pass in an event via $event.
<div id="app">
<! -- Event was not added -->
<button @click="btnClick">Button 1</button> <! -- Event did not pass parameters -->
<button @click="btnClick()">Button 2</button> <! -- Event did not pass parameters -->
<! The event calls the method to pass the argument. The parentheses are omitted when writing the function, but the function itself needs to pass an argument.
<button @click="btnClick2(123)">Button 3</button> <! - $123 - >
<button @click="btnClick2()">Button 4</button> <! -- undefined -->
<button @click="btnClick2">Button 5</button> <! -- [object MouseEvent] -->
<! Call event (event);
<button @click="btnClick3($event,123)">Button (6)</button> <! -- [object MouseEvent]123 -->
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app".methods: {btnClick(){
console.log("Event did not pass parameters");
},
btnClick2(value){
console.log(value);
},
btnClick3(event,value){
console.log(event+value); }}})</script>
Copy the code
4-3, V-ON modifier
The modifier | role |
---|---|
.stop | Call event. StopPropagation (). To prevent a bubble |
.prevent | Calls to the event. The preventDefault (). Blocking default behavior |
. Or keyCode. KeyAlias | The callback is triggered only if the event is triggered from a particular key. |
.native | Listen for native events on the component root element. |
.once | Only trigger once |
<div id="app">
<! --1.. stop modifier -->
<! Stop -->
<div @click="divClick">
aaaaaaa <! -- click aaa to display div -->
<button @click.stop="btnClick">Button 1</button> <! -- The BTN div bubbles when the button is clicked -->
</div>
<! Stop -->
<div @click="divClick">
aaaaaaa <! -- click aaa to display div -->
<button @click.stop="btnClick">Button 2</button> <! -- Click the button to display BTN -->
</div>
<! --2. Use of prevent modifier -->
<! -- Not used to prevent -->
<form action="http://www.baidu.com">
<input type="submit" value="Submit" @click="submitClick"> <! Submit is displayed when you click submit, but quickly jumps to another page -->
</form>
<!-- 使用.prevent -->
<form action="http://www.baidu.com">
<input type="submit" value="Submit" @click.prevent="submitClick"> <! -- "Submit" is displayed when you click submit, no jump to another page -->
</form>
<! --3. Listen for a key cap on a keyboard -->
<input type="text" @keyup.enter="keyUp"> <! -- Listen for the enter key -->
<! -- use of the.. once modifier -->
<button @click.once="btn2Click">Button 3</button> <! -- call once -->
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
methods: {
btnClick() {
console.log("btn");
},
divClick() {
console.log("div");
},
submitClick() {
console.log('submit');
},
keyUp() {
console.log('keyUp');
},
btn2Click() {
console.log('Call once'); }}})</script>
Copy the code
5. Conditions and loops
5-1. Conditional rendering
V-if, V-else -if, and V-else are similar to JavaScript conditional statements like if, else, and else if. Vue’s conditional directives can render or destroy elements or components in the DOM based on the value of an expression
When the condition after v-if is false, the corresponding element and its child elements are not rendered, i.e., no corresponding tags appear in the DOM at all.
<div id="app">
<p v-if="score>=90">good</p>
<p v-else-if="score>=80">good</p>
<p v-else-if="score>=60">Pass the</p>
<p v-else>Don't pass the</p>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
score: 99}})</script>
Copy the code
5-2, V-if vs V-show
V-if When the condition is false, there is no corresponding element in the DOM at all. V-show When the condition is false, it simply sets the display attribute of the element to None.
Use v-show when you need to slice frequently between show and hide. Use V-if when there is only one switch
5-3, V-for instruction
(1) Go through the number group
(1) Directly traverse item in Arry (2) include index (item,index) in Arry
<div id="app">
<! --1. No index value (subscript value) is used during traversal -->
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<! Select * from index ();
<ul>
<li v-for="(item, index) in names">{{index+1}}.{{item}}</li>
</ul>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
names: ['Durant'.'Kobe'.'Irving'.'Curry']}})</script>
Copy the code
(2) The traversal number group of vue.js
In general, we write the traversal number group in JS code as follows:
let books = [1.2.3];
for (let i = 0; i < books.length; i++) {
console.log(books[i]); / / 1 2 3
}
Copy the code
There are two simple ways to write it: for(let me in/of books)
// 1. in
for(let i in books){
console.log(i); / / 0 1 2
conlose.log(books[i]); / / 1 2 3
// I is the index value
}
// 2. of
for(let i of books){
console.log(i); / / 1 2 3
// I is an array element
// Write I as item to make it easier to recognize
}
Copy the code
(3) Traverse the object
Number of values obtained:
- If you just get a value while walking through an object, you get a value
- If you get two values, you get value, key: (value, key)
- If we get three values, we get value, key, index.
- Note: value, key, and index are only code names, even if (key,index,value) is written, the information is (attribute value, attribute name,index number), i.e. key is the attribute value,index is the attribute name, and value is the index number.
<div id="app">
<! --1. If only one value is obtained, then a value is obtained -->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<! (value, key) -->
<ul>
<li v-for="(value, key) in info">{{value}}-{{key}}</li>
</ul>
<! Value, key, index (value, key, index) -->
<ul>
<li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
</ul>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
info: {
name: 'why'.age: 18.height: 1.88}}})</script>
Copy the code
It is recommended that we add a key attribute to the corresponding element or component when using V-for.
A later article will cover the functions of keys in more detail
5-4. Detect array updates
Because Vue is responsive, when data changes, Vue automatically detects data changes and the view updates accordingly. Vue includes a set of methods to watch arrays compile, and using them to change arrays also triggers view updates. The following methods can be used to be responsive
methods | role |
---|---|
push() | Append data to the end of the array |
pop() | Deletes the last data in the array |
shift() | Deletes the first element of the array |
unshift() | Add elements to the front of the array |
splice() | Delete elements, insert elements, replace elements |
sort() | The sorting |
reverse() | Flip the array |
1. Splice ()
// splice deletes elements/inserts elements/replaces elements
// The first argument is the index number, which represents the starting position
var arr = ['a'.'b'.'c'];
// Delete element: The second argument is passed how many elements you want to delete (if not, delete all subsequent elements)
arr.splice(1.1); // ['a','c']
// Insert element: The second argument is passed 0, followed by the element to be inserted
arr.splice(1.0.'d'); // ['a','b','d','c']
// Replace elements: The second argument, indicating how many elements we want to replace, is followed by the previous element
arr.splice(1.1.'d'); // ['a','d','c']
arr.splice(1.1.'d'.'f'); // ['a','d','f','c']
[1] insert 'd','f',' d','f',' d','f',' d','f',' d','f
Copy the code
(2) the sort ()
When.sort() is used alone, there are no arguments. Judge the size of the units digit, you can order from the smallest to the largest; But when the value is multiple digits, it does something different. It compares the first digit, then the second digit… So in the following case the order is 1,13,4,7,77.
var arr1 = [1.4.7.3];
arr1.sort();
console.log(arr1); / /,3,4,7 [1]
var arr2 = [13.1.7.4.77];
arr2.sort();
console.log(arr2); / /,13,4,7,77 [1]
Copy the code
To sort the order from smallest to largest, there are templates like the following:
Arr. Sort (function(a,b){return a-b; / / ascending});
Arr. Sort (function(a,b){return b-a; / / descending});
Note: The parentheses of sort enclose the entire function, so remember to end with a semicolon
var arr1 = [13.1.7.4.77];
arr1.sort(function(a,b){
returnA - b;/ / ascending
});
console.log(arr1); / /,4,7,13,77 [1]
var arr2 = [13.1.7.4.77];
arr2.sort(function(a,b){
returnB - a;/ / descending
});
console.log(arr2); / /,13,7,4,1 [77]
Copy the code
6. Form binding
6-1. Basic use of V-Model
The V-model directive is used in Vue to implement bi-directional binding between form elements and data
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'}})</script>
Copy the code
When we input content in the input box, because the V-Model in the input is bound to Message, the input content will be transmitted to Message in real time, and message will change. When a message changes, the DOM changes in response because we use Mustache syntax above to insert the value of a message into the DOM.
Therefore, two-way binding is achieved through v-Model.
Of course, we can also use the V-Model for textarea elements
6-2. V-model principle
The V-Model is a syntactic sugar that essentially contains two operations:
- V-bind binds a value attribute
- The V-on directive binds the input event to the current element
<input type="text" v-model="message"> {{message}}
Copy the code
Is equal to:
<input type="text" :value="message" @input="message = $event.target.value">>{{message}}
Copy the code
6-3. Other types
(1) the radio
Radio, put the selected things into the information.
In this case, the chosen sex is incorporated into the data
<div id="app">
<label for="male">
<input type="radio" id="male" value="Male" v-model="sex">male</label>
<label for="female">
<input type="radio" id="female" value="Female" v-model="sex">female</label>
<h2>The gender you have selected is: {{sex}}</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
sex: ' '}})</script>
Copy the code
V-model is bound to the same variable sex, so it can be mutually exclusive. (This function is equivalent to setting name=”sex” for both radios)
(2) the checkbox
Check boxes are classified into two types: single check box and multiple check boxes. (1) Single check box:
- V-model is a Boolean value.
- In this case, the input value does not affect the V-model value.
(2) Multiple check boxes:
- When multiple checkboxes are selected, the property in the corresponding data is an array because more than one check box can be selected.
- When one of them is selected, the value of the input is added to the array.
<div id="app">
<! --1. Checkbox
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">Agree to a deal</label>
<h2>Your choice is: {{isAgree}}</h2>
<button :disabled=! "" isAgree">The next step</button>
<!--2.checkbox多选框-->
<input type="checkbox" value="Basketball" v-model="hobbies">basketball<input type="checkbox" value="Football" v-model="hobbies">football<input type="checkbox" value="Table tennis" v-model="hobbies">Table tennis<input type="checkbox" value="Badminton" v-model="hobbies">badminton<h2>Your hobbies are: {{hobbies}}</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
isAgree: false./ / radio buttons
hobbies: [] // Multi-select box,}})</script>
Copy the code
(3) the select
Uncommon (1) Single option: Only one value can be selected.
- The V-model binds to a value.
- When we select one of the options, we assign its corresponding value to mySelect
(2) Multiple selection: Multiple values can be selected. multiple
- The V-Model binds to an array.
- When multiple values are selected, the value corresponding to the selected option is added to the array mySelects
- Multi – select to use CRTL + mouse click
<div id="app">
<! --1. Choose a -->
<select name="abc" v-model="fruit">
<option value=The word "apple">apple</option>
<option value="Banana">banana</option>
<option value="Durian">durian</option>
<option value="Grapes">grapes</option>
</select>
<h2>Your choice of fruit is: {{fruit}}</h2>
<! --2. Select multiple -->
<select name="abc" v-model="fruits" multiple>
<option value=The word "apple">apple</option>
<option value="Banana">banana</option>
<option value="Durian">durian</option>
<option value="Grapes">grapes</option>
</select>
<h2>Your fruit of choice is {{fruits}}</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
fruit: 'banana'.fruits: []}})</script>
Copy the code
6-4. Value binding
It’s just assigning value dynamically. v-bind:value=””
const app = new Vue({
el: '#app'.data: {
num1: 1.num2: 0
},
// When num1 and num2 change, the corresponding function is called
watch: {num1(newvalue){
console.log(num1 changed);this.num2 = newvalue * 10; // num2 changes, num2(){}
},
num2(newvalue){
console.log(num2 changed); }}Copy the code
6-5. Modifiers
- Lazy decorator:
By default, v-Model synchronizes input field data in input events by default. In other words, the data in the corresponding data will be automatically changed once the data is changed. The lazy modifier allows data to be updated only if it loses focus or hits enter
- The number modifier:
By default, whether we enter letters or numbers in the input field is treated as a string. But if we want to deal with numeric types, it’s better to treat the content as a number. The number modifier automatically converts what is entered in the input field to a number type
- Trim modifier:
If you enter content that has a lot of whitespace at the beginning and end, and you want to remove it, the trim modifier filters the whitespace on the left and right sides of the content
7. Filters
Can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and V-bind expressions
<div id='app'>{{123 | show}} / / RMB 123.00</div>
<script>
const app = new Vue({
el:'#app';
filters:{
show(price){
return A '$'+price.toFixed(2)}}})</script>
Copy the code
8, Monitor watch
Listen for changes in the property of a variable. The function name is the property name. Two are newValue, oldValue
8-1 Many ways to write watch
watch:{
el: function(newThat old){
console.log(1)},el(newThat old){
console.log(2)},// Directly observe changes in EL values to perform side effects
el: {
immediate: true.handle(new, old){
console.log(3)},deep: true,},// Write it as an object to facilitate the configuration of multiple parameters
}
Copy the code
Watch can be configured with a flush in addition to immediate and deep. See watchEffect, a fascinating new feature in the Vue Composition API in this article
Stop listening
There is a special API $watch in vue, which is the same as the watch function in Vue Option. It can register the function of watch listener. Of course, its execution function returns a stop function by default, which can be used to cancel the listener
Two, componentized development
1. Know the components
Vue componentization idea
As much as possible, break the page up into small, reusable components. This makes our code easier to organize and manage, and also more extensible.
2. Componentization basis
2-1. Register components
(1) Basic steps of registration
The use of components is divided into three steps: ① Create a component constructor: vue.extend () ② register a component: Vue.component() ③ Use a component. Used within the scope of Vue instances
(2) Initial experience of componentization
<div id="app">
<! --3. Use components -->
<my-cpn></my-cpn>
<div>
<my-cpn></my-cpn>
</div>
</div>
<script src=".. /js/vue.js"></script>
<script>
// 1. Create a component constructor object
const cpnC = Vue.extend({
template: ` < div > < h2 > I am a title < / h2 > < p > I'm content, ha ha ha ha < / p > < p > I'm content, ha ha ha ha < / p > < / div > `
})
// 2. Register components
Vue.component('my-cpn', cpnC)
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'}})</script>
Copy the code
(3) Global and local components
Global components, meaning they can be used under multiple Vue instances registered outside of new Vue
<div id="app">
<cpn></cpn>
</div>
<div id="app2">
<cpn></cpn>// It can be used globally, but cannot be used locally because it is not registered</div>
<script src=".. /js/vue.js"></script>
<script>
// 1. Create a component constructor
const cpnC = Vue.extend({
template: '
I am the title
I am the content, ha ha ha ha ah
'
})
// 2. Register components
// global component, which means it can be used under multiple instances of Vue
// Vue.component('cpn', cpnC)
const app = new Vue({
el: '#app'.// select * from the local component
components: {
cpn: cpnC // CPN Specifies the label name of the component used in cpnC}}const app2 = new Vue({
el: '#app2'
})
</script>
Copy the code
(4) Parent and child components
If component A is registered with component B, component A is A child component of component B. Child components can only be used within the parent component, and child components cannot be used in the instance or elsewhere unless the child component is registered with the instance or globally.
<div id="app">
<cpn2></cpn2>
<! When cpn1 is registered only in cpn2, it can only be called in cpn2. It can only be used in cpn2 unless it is registered in vue instance or globally.
<cpn1></cpn1>
</div>
<script src=".. /js/vue.js"></script>
<script></script>
Copy the code
(5) Register component syntax sugar
The call to vue.extend () is omitted, and an object can be used instead.
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<script src=".. /js/vue.js"></script>
<script>
// 1. Syntax sugar for global component registration
// 1. Create a component constructor
// const cpn1 = Vue.extend()
// 2. Register components
Vue.component('cpn1', {
template: '
I'm heading 1
I'm content, hahaha
'
})
// 2. Register the syntax sugar of the local component
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
components: {
'cpn2': {
template: '
I'm heading 2
I'm content, hehe hehe
'}}})</script>
Copy the code
(6) separate writing method of template
If you want to use a script tag, you can use a text/x-template tag.
<div id="app">
<cpn></cpn>
</div>
<! --1.script tag, note: the type must be text/x-template-->
<script type="text/x-template" id="cpn"></script>
<script src=".. /js/vue.js"></script>
<script>
// 1. Register a global component
Vue.component('cpn', {
template: '#cpn'
})
const app = new Vue({
el: '#app'
})
</script>
Copy the code
The template tags:
<! - 2. The template tags - >
<template id="cpn">
<div>
<h2>I am heading</h2>
<p>I am content, hehe hehe</p>
</div>
</template>
Copy the code
(7) Component cannot access data of Vue instance data
A component is an encapsulation of a single functional module that has its own HTML template and should also have its own property data.
The data attribute must be a function that returns an object containing data
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>{{title}}</h2>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
// 1. Register a global component
Vue.component('cpn', {
template: '#cpn'.// Data is a function that returns an object that holds data
data() {
return {
title: 'abc'}}})const app = new Vue({
el: '#app'.data: {
message: 'Hello.',}})</script>
Copy the code
(8) Two ways that component data returns objects
(1) The returned object is defined in data. (Information is not shared.) (2) The returned object is defined externally. (Information sharing)
The first way:
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>Current count: {{counter}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
Vue.component('cpn', {
template: '#cpn'.data() {
return {
counter: 0}},methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
const app = new Vue({
el: '#app',})</script>
Copy the code
Clicking on any module only changes the value of count for the current component. Each object has its own memory address. Three calls to the component’s data return three objects with different memory addresses (the same content, but different addresses). So information is not shared.
The second way is:
<script>
const obj = {
counter: 0
}
Vue.component('cpn', {
template: '#cpn'.data() {
return obj
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
</script>
Copy the code
Clicking on any module changes the value of count. Because obj is defined first, obj has a memory address, and when the component’s data is called three times, it returns obJ with the same memory address. So that leads to information sharing.
2-2. Data transmission
The parent component passes data to the child component through functions and the child component sends messages to the parent component through eventsIn real development, the communication between a Vue instance and a child is the same as the communication between a parent and a child.
(1) The parent passes props to the child
Use the option props in the child component to declare the data that needs to be received from the parent.
There are two ways to value props:
Method 1: string array, the string in the array is the name of the pass.
Method 2: object, object can be set when the type of transfer, can also set the default value.
① Array form
String array :(not used)
<div id="app">
<! When calling a child component that needs data from the parent, you must v-bind the binding property -->
<cpn :cmessage="message" :cmovies="movies"></cpn>
</div>
<template id="cpn">
<div>
<p>{{cmovies}}</p>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
// Props
const cpn = {
template: '#cpn'.props: ['cmovies'.'cmessage']}const app = new Vue({
el: '#app'.data: {
message: 'Hello.'.movies: ['the sea king'.One Piece.Haier Brothers]},components: {
cpn
}
})
</script>
Copy the code
② Object form
The supported data types are: String, Number, Boolean, Array, Object, Date, Function, and Symbol
<div id="app">
<! When calling a child component that needs data from the parent, you must v-bind the binding property -->
<cpn :cmessage="message" :cmovies="movies"></cpn>
</div>
<template id="cpn">
<div>
<p>{{cmovies}}</p>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
// Props
const cpn = {
template: '#cpn'.props: {
// 1. Type restriction
// cmovies: Array,
// cmessage: String,
// 2. Provide some default values as well as mandatory values
cmessage: {
type: String.// Data type
default: 'aaaaaaaa'./ / the default value
required: true // true means that the cmessage property must be called when the component is called
},
When the type is an object or array, the default value must be a function
cmovies: {
type: Array.default() {
return[]}}}}const app = new Vue({
el: '#app'.data: {
message: 'Hello.'.movies: ['the sea king'.One Piece.Haier Brothers]},components: {
cpn
}
})
</script>
Copy the code
③ Points of attention for hump identification:
When we declare variables in props using a hump nomenclature (cMessage), the v-bind attribute name cannot be humped and needs to be changed when calling the child component and passing the parent component data. CMessage is converted to C-message
<div id="app">
<! -->
<cpn :cMessage="message"></cpn>
<! -->
<cpn :c-message="message"></cpn>
</div>
<template id="cpn">
<div>
<h2>{{cMessage}}</h2>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
const cpn = {
template: '#cpn'.props: {
cMessage: {
type: String.default: 'very good'}}}const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
components: {
cpn
}
})
</script>
Copy the code
(2) The child passes to the parent
The child component passes data or events to the parent component using custom events.
Custom event flow: In the child component, emit the event via $emit(‘ event name ‘, parameter). Emit means emit. In the parent component, v-on is used to listen for child component events. @event name =’ Event of parent component ‘
<! Parent component template -->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<! -- Subcomponent template -->
<template id="cpn">
<div>
<button v-for="item in categories"
@click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
// 1. Child components
const cpn = {
template: '#cpn'.data() {
return {
/ / class
categories: [{id: 'aaa'.name: 'Top Recommendations'},
{id: 'bbb'.name: 'Mobile Digital'},
{id: 'ccc'.name: 'Home Appliances'},
{id: 'ddd'.name: 'Computer Office'}}},],methods: {
btnClick(item) {
// Launch event: custom event
this.$emit('item-click', item);
// item-click is the binding event name of the parent component @item-click= ""}}}// 2. Parent component
const app = new Vue({
el: '#app'.components: {
cpn
},
methods: {
cpnClick(item) {
console.log('cpnClick', item); }}})</script>
Copy the code
(3) Parent-child component access
Parent component accessing child component: Use children or children or children or refs (Reference reference) Child component accessing parent component: Use parent to access root component: Use parent to access root component: Use parent to access root component: Use root to access root component
The most common is refs
Children gets a collection of subcomponents, an array that must be accessed by an index value. Children’s weakness: When there are too many child components and we need to get one of them, we are often unsure of its index value and may even change.
Refs is a key that defines the REF attribute for each child component and then calls it using refs to access a specific child component without error as the number of locations changes.
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">button</button>
</div>
<template id="cpn">
<div>I'm a child component</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
methods: {
btnClick() {
// 1.$children
console.log(this.$children);
for (let c of this.$children) {
console.log(c.name);
}
console.log(this.$children[1].name);
// 2.$refs => object type, default is an empty object
console.log(this.$refs.aaa.name); }},components: {
cpn: {
template: '#cpn'.data() {
return {
name: 'I'm the name of the child component'}}},}})</script>
Copy the code
Parent:
- Although in Vue development we are allowed to access parent components through parent, try not to do so in real development.
- The child component should avoid direct access to the parent component’s data because it is too coupled.
- If we put a child component inside another component, it is likely that the parent does not have corresponding properties, often causing problems.
- It would be even harder to change the state of the parent component directly with $parent, which would make the state of the parent component erratic, which would be very difficult for me to debug and maintain.
(4) Non-parent-child component communication
3. Advanced componentization
3-1, slot slot
Component slots are also designed to make the components we package more extensible. Let the user decide what some of the content inside the component actually shows.
(1) Compile scope
Everything in the parent component template is compiled in the parent scope; Everything in the subcomponent template is compiled in the subscope.
(2) Basic use of slot
Use the label slot in the child component. Use the child component directly in the parent component and use the desired label internally.
<! 2. The default value of the slot <slot>button</slot> 3. If multiple values are put into the component at the same time for replacement, they are used as replacement elements together -->
<div id="app">
<cpn></cpn> <! - button - >
<cpn><i>Ha ha ha</i></cpn> <! -- Ho ho ho -->
<cpn>
<i>Ha ha ha</i> <! Div p-->
<div>I'm a div element</div>
<p>I'm a p element</p>
</cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>I am a component</h2>
<p>I'm a component, hahaha</p>
<slot><button>button</button></slot> <! -- default is button -->
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
components: {
cpn: {
template: '#cpn'}}})</script>
Copy the code
(3) Named slot
When there are multiple slots and you want to replace the contents of a slot, simply give the slot element a name attribute. When replacing the slot element, you can use the V-slot directive on a template tag and supply the name(which can also be a dynamic parameter) as a parameter to the V-slot. Abbreviation # name
<div id="app">
<template v-slot="center"><span>The title</span></template>
<template v-slot="left"><button>return</button></template>
</div>
<template id="cpn">
<div>
<slot name="left"><span>On the left</span></slot>
<slot name="center"><span>In the middle</span></slot>
<slot name="right"><span>On the right</span></slot>
</div>
</template>
<script src=".. /js/vue.js"></script>
<script>
const app = new Vue({
el: '#app'.data: {
message: 'Hello.'
},
components: {
cpn: {
template: '#cpn'}}})</script>
Copy the code
(4) Slot Scope slot
The parent component replaces the label of the slot, but the content is provided by the child component. The core is to get data from the child component and use it in the parent component. We can bind user as an attribute of the element
<span>
<slot v-bind:user="user"> {{ user.lastName }}
</slot>
</span>
Copy the code
Attributes bound to
elements are called slot prop. Now in parent scope, we can define the name of our supplied slot prop using v-slot with a value:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
Copy the code
In this example, we chose to name the object that contains all the slotProps slotProps, but you can use any name you like.
4. Component lifecycle
Here is a brief introduction to the parent-child component lifecycle creation sequence, and I will go into more detail on vue source code analysis in a later article
When a parent component contains a child component, its lifecycle is created in the following order:
Parent beforeCreate-> Parent created-> parent beforeMount-> child beforeCreate-> child created-> child beforeMount-> Child Mounted -> parent Mounted
5. Modular development
CommonJS, AMD, CMD, and ES6 Modules
5-1, CommonJS
Use Node, Node will learn, learn Node to write the article will be introduced and in this supplementary link
Module. exports = {} export let {} = require(‘./… js’)
5-2, Modules for ES6
Type =”module” in the import js file
<script src="aaa.js" type="module"></script>
<script src="mmm.js" type="module"></script>
Copy the code
Export (export), inport(import)
Export Method 1:
var flag= true;
function sum(num1,num2){
return num1 + num2
}
class Person {
run() {
console.log('On the run'); }}export {
flag,
sum,
Person
}
Copy the code
Export method two :(first out when defining)
export var num1 = 1000;
// Export function/class:
export function mul(num1, num2) {
return num1 * num2
}
export class Person {
run() {
console.log('On the run'); }}Copy the code
In some cases, a module contains a function that we do not want to name and let the importer name it himself, using Export Default
Note: Export default cannot exist in one module at the same time.
// export default
export default const address = 'Beijing'
// Export the function
export default function(argument) {
console.log(argument);
}
// Import is written differently than usual
import addr from "./aaa.js"; // addr is self-named, no longer need to add {}
Copy the code
Import:
// Partial import
import {flag,sum} from "./aaa.js";
// all imports are unified
import * as bbb from './aaa.js' // the name that BBB named for itself
console.log(bbb.flag); // Invoke the imported flag
console.log(bbb.sum(10.20)); // Call imported sum()
Copy the code
Third, the vue – the router
1. Know routes
Routing is the activity of transferring information from a source address to a destination address over an interconnected network – Wikipedia. Routing determines the path a packet takes from its source to its destination.
There is a very important concept in routing called routing table, which is essentially a mapping table that determines the direction of packets.
2. Vue-router is used basically
2-1. Route jump rules
(1) URL hash
The hash of the URL is the anchor point (#). We can change the href by assigning location.hash directly, but the page does not refresh.
(2) History of ES5
pushState
Jump back. The jump instruction is: history.back()
replaceState
Replace, cannot jump.
go
History.back () is equivalent to history.go(-1). History.forward () is equivalent to history.go(1).
2-2. Install routes
NPM install vue-router –save CLI install: select vue-router yes CLI install will automatically configure for us, if it is webpack install, we need to configure ourselves. The configuration can be as follows:
src/router/index.js
// Configure routing information
import Vue from 'vue'
import VueRouter from 'vue-router'
Use Vue. Use (plug-in) to install the plug-in
Vue.use(VueRouter)
// Configure the mapping between routes and components (mapping table)
const routes = [
]
// create the VueRouter object
const router = new VueRouter({
routes
})
// 3. Pass the Router object to the Vue instance
export default router
Copy the code
main.js
import Vue from 'vue'
import App from './App'
import router from './router' // Import a route to import a folder, the index file will be imported by default
Vue.config.productionTip = false
new Vue({
el: '#app',
router, // Import a route
render: h= > h(App)
})
Copy the code
2-3. Use routes
src/router/index.js
// Configure routing information
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '.. /components/Home' // Import components
import About from '.. /components/About' // Import components
Use Vue. Use (plug-in) to install the plug-in
Vue.use(VueRouter)
// Configure the mapping between routes and components
const routes = [
{
// The default route path
path: ' '.redirect: '/home' // redirect
},
{
path: '/home'.component: Home
},
{
path: '/about'.component: About
}
]
// create the VueRouter object
const router = new VueRouter({
routes,
mode:'history' // mode: the default hash value is' #/home '. If you use ES5 history, there is no #
})
// 3. Pass the Router object to the Vue instance
export default router
Copy the code
main.js
import Vue from 'vue'
import App from './App'
import router from './router' // Import a route to import a folder, the index file will be imported by default
Vue.config.productionTip = false
new Vue({
el: '#app',
router, // Import a route
render: h= > h(App)
})
Copy the code
App.vue
<template>
<div id="app">
<router-link to="/home">Home page</router-link>
<router-link to="/about">about</router-link>
<router-view></router-view> <! -- Component will be replaced with router-view -->
</div>
</template>
Copy the code
Router-link: this label is a built-in component of vue-router, which is rendered as an A label by default. Router-view: this label dynamically renders different components based on the current path. The rest of the page, such as the title/navigation at the top, or some copyright information at the bottom, is at the same level as the router-View. During route switching, only the components mounted by the router-View are switched. Other contents remain unchanged
(1) the router – the link
Router-link: This tag is a component already built into vue-Router and is rendered as an A tag by default. Properties:
- To: Indicates the jump path.
- Tag: You can specify what tag router-link will render to, such as a button tag, tag=”button”
- Replace: The default jump is pushState. To replaceState, add the replace property directly.
- ④ Ctive -class: When the router-link route matches successfully, the system automatically sets a router-link-active class for the current element. You can change the default name of the active-class.
This class is used when highlighting navigation menus or tabbars at the bottom.
However, if you have more than one router-link, you need to modify it several times, so there is an easy way to write it: SRC /router/index.js
const router = new VueRouter({
routes,
mode:'history'.linkActiveClass:'active' // If the route is successfully matched, the default class name is active
})
export default router
Copy the code
(2) Another way to jump
A router-link link is a router-link link. A router-link link is a router-link link
<template>
<div id="app">
<button @click="homeClick">Home page</button>
<button @click="aboutClick">about</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'.methods: {
homeClick() {
// Modify the vue-router in code
// this.$router.push('/home')
this.$router.replace('/home') // Router is the router defined in index.js (Vuerouter object)
},
aboutClick() {
// this.$router.push('/about') // push=>pushState
this.$router.replace('/about') // replace=>replaceState}}}</script>
Copy the code
2-4. Dynamic routing
In some cases, the path of a page may be indeterminate. For example, when we enter the user interface, we want the following path: /user/aaaa or /user/ BBBB (in addition to /user, the user ID is followed by the user ID). We can also obtain information by routing. Path in index.js:
{
path: '/user/:id'.// id useId obtained from app. vue
component: User
}
Copy the code
App.vue
<router-link :to="'/user/'+userId">The user</router-link>
<script>
export default {
name: 'App'.data() {
return {
userId: 'zhangsan'}}}</script>
Copy the code
/ User /zhangsan = / User /zhangsan = user.vue = / User /zhangsan = User
<template>
<div>
<h2>{{userId}}</h2> <! -- Get information from computer -->
<h2>{{$route.params.id}}</h2> <! -->
</div>
</template>
<script>
export default {
name: "User".computed: {
userId() {
return this.$route.params.id
// The route is not the same as the "alternative route" router
// Route is the active route of routes in the router
// id is the ID of path: '/user/:id' in the active route}}}</script>
Copy the code
2-5. Lazy route loading
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.
The main function of route lazy loading is to pack the components corresponding to the route into JS code blocks one by one. The components are loaded only when the route is accessed. Previously: index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '.. /components/Home' // Import components
import About from '.. /components/About' // Import components
Vue.use(VueRouter)
const routes = [
{
// The default route path
path: ' '.redirect: '/home'
},
{
path: '/home'.component: Home
},
{
path: '/about'.component: About
}
]
Copy the code
Route lazy loading:
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () = > import('.. /components/Home') // Dynamically import components
const About = () = > import('.. /components/About') // Dynamically import components
Vue.use(VueRouter)
const routes = [
{
// The default route path
path: ' '.redirect: '/home'
},
{
path: '/home'.component: Home
},
{
path: '/about'.component: About
}
]
Copy the code
3, Vue-router nested routine by
There are two more paths in the component home that correspond to two child components.
1. Create the corresponding sub-components (news. vue, message. vue) and configure the corresponding sub-routes in the route mapping:
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () = > import('.. /components/Home')
const News = () = > import('.. /components/News') // Dynamically import the child component News
const Message = () = > import('.. /components/Message') // Dynamically import the child component Message
const About = () = > import('.. /components/About')
Vue.use(VueRouter)
const routes = [
{
// The default route path
path: ' '.redirect: '/home'
},
{
path: '/home'.component: Home,
children:[
{
path:' '.redirect: News
},
{
path:'news'.// Don't add /
component: News
},
{
path:'message'.// Don't add /
component: Message
}
]
},
{
path: '/about'.component: About
}
]
Copy the code
2. Use router-link and router-view tags inside the parent of the two child components. Home.vue
<template>
<div>
<router-link to="/home/news">news</router-link>
<router-link to="/home/message">The message</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
Copy the code
4. Vue-router parameter transmission
URL: Protocol :// host: port/path? Scheme ://host:port/path? query#fragment
There are two main types of passing parameters: Params and Query
4-1 types of Params:
Set the route format to /router/: ID
How it is passed: Follow path with the corresponding value
The path is /router/123, /router/ ABC
See 2-4. Dynamic Routing
Alternative to router-link (see 2-3(2))
<template>
<div>
<button @click="userClick">The user</button>
</div>
</template>
<script>
export default {
name: 'App'.data(){
return {
userId: 'zhangsan'}},methods: {userClick(){
this.$route.push('/user'+this.userId)
}
}
</script>
Copy the code
4-2. Query type:
The route format is /router, which is the common configuration
Pass method: The object uses the Query key as the pass method
Route: /router? id=123, /router? id=abc
Index.js (don’t set it like params, just set it normally)
{
path: '/profile'.component: Profile
}
Copy the code
App.vue
<template>
<div>
<router-link :to="{path:'/profile',query:{name:'wu',age:20}}">my</router-link>
<router-view></router-view>
</div>
</template>
Copy the code
Profile.vue
<template>
<div>
<h2>{{$route.query}}</h2> <! -- {name:wu,age:20} -->
<h2>{{$route.query.name}}</h2> <! -- wu -->
<h2>{{$route.query.age}}</h2> <! -- -- -- > 20
</div>
</template>
Copy the code
The url is… /profile? name=wu&&age=20
Another way to switch to a router without router-link
<template>
<div>
<button @click="profileClick">my</button>
</div>
</template>
<script>
export default {
name: 'App'.methods: {profileClick(){
this.$route.push({
path: '/profile'.qurey: {name: 'wu'.age: 20}}}})</script>
Copy the code
There is a difference between a route and a router
Router is an instance of VueRouter and can be navigated to different urls using the $router.push/replace method
$route is the route to which the current router jumps (route is the active route on routes in the router). You can obtain name, path, query, and params
6. Vue-router navigation guard
How do you change the title of a web page in a SPA application? Page titles are displayed using the title tag, but SPA has only one fixed HTML and the title does not change when switching between pages. The navigational guard solves this problem.
What is a navigation guard?
- Vue-router provides a navigational guard that listens for incoming and outgoing routes.
- Vue-router provides beforeEach and afterEach hook functions that fire before and after a route is about to change.
- Both the front guard and the rear hook are global guards
- Exclusive route guard beforeEnter, the parameter is the same as beforeEach.
- The guards within the component beforeRouteEnter (called before rendering the corresponding route of the component), beforeRouteUpdate (called when the current route changes but the component is being re-used), beforeRouteLeave (called before navigating away from the corresponding route of the component)
Change the page title: index.js
const routes = [
{
path: '/home'.component: Home,
meta: { // Meta metadata (data describing data)
title: 'home'}}, {path: '/about'.component: About,meta: {title: 'about'}},
{path: '/user/:id'.component: User,meta: {title: 'users'}},
{path: '/profile'.component: Profile,meta: {title: 'archives'}}]// Guard
router.beforeEach((to, from, next) = > {
// Jump from from to to
document.title = to.matched[0].meta.title
// If the route is nested, it must be called meta only
// console.log(to); // Active routing
next() // beforeEach Must write, jump page
})
Copy the code
Three parameters of the navigation hook:
- ① To: Route object of the destination to be entered.
- ② From: Indicates the route object that the current navigation is about to leave.
- ③ Next: Call this method before going to the next hook. Next (‘/ path ‘) specify a path
Rear hook:
// add a hook.
router.afterEach((to, from) = > {
// console.log('----');
})
Copy the code
Route exclusive guard:
{
path: '/home'.component: Home,
meta: { // Meta metadata (data describing data)
title: 'home'
},
beforeEnter:(to,from,next) = > {
// ...
next()
}
}
Copy the code
7, keep alive
Keep-alive is a component built into Vue that can preserve the state of contained components or avoid re-rendering. Router-view is also a component. If it is wrapped directly in keep-alive, all view components matched by the path will be cached.
The activated and deactivated functions can be used only when keep-alive exists. Activated and deactivated app.vue
<keep-alive>
<router-view></router-view>
</keep-alive>
Copy the code
Home.vue
export default {
name: "Home".activated(){
console.log('Home activated')},deactivated(){
console.log('Home deactivated')}}Copy the code
Home Activated is printed when our page is at Home, and Home deactivated is printed when the page is away from Home. (This is, of course, in the presence of keep-alive)
After keep-alive is called, components are not frequently created and destroyed. It will leave it in state or avoid re-rendering. Without keep-alive, components are created when called and destroyed when switched.
Test: App. Vue
<keep-alive>
<router-view></router-view>
</keep-alive>
Copy the code
Home.vue
export default {
name: "Home".created(){
console.log('Home created')},destroyed(){
console.log('Home destroyed')}}Copy the code
Keep – the attribute of the alive
Include is a string or regular expression. Only matching components will be cached. Exclude is a string or regular expression
App.vue
<keep-alive exclude="Home,About"> <! --Home and About are created and destroyed frequently -->
<! -- Home/About is the component name -->
<router-view></router-view>
</keep-alive>
Copy the code
8. Create an alias
When you need to fetch files from multiple outer folders,.. /.. This is a taboo in development, and if you move the location of the file, you may need to change the call path code. So it’s very convenient to have individual names.
webpack.base.conf.js
module.exports = {
resolve: {
alias: {
The '@': resolve('src'), // SRC folder for the current project (layer 1)
'assets': resolve('src/assets'),
'components': resolve('src/components'),
'views': resolve('src/views'),}}}Copy the code
Call: there are two cases: ① call in HTML tag (image reference) ② call in import ① HTML tag (add ~)
<img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
<! -- Assets are SRC /assets, but to use an alias within an HTML tag, add ~ -->
Copy the code
② Call in import
import TabBar from 'components/tabbar/TabBar'
// component is SRC /component
Copy the code
9, Promise (ES6)
Promise is a solution to asynchronous programming.
When do we deal with asynchronous events? A very common scenario would be a network request. We encapsulate a function for a network request, and since we don’t get results immediately, we often pass in another function that calls back the data when the request succeeds. However, when the network request is very complex, callback hell (multiple callback functions) can occur.
The normal way of writing callback hell is, under normal circumstances, there’s nothing wrong, it works and it gets the result we want. However, such code is ugly and not easy to maintain.
9-1. The structure of Promise
// Promise takes a function (resolve,reject)=>{}
// This function takes two arguments: resolve and reject. These are functions themselves.
// reject reject when not needed
new Promise((resolve,reject) = > {
// Asynchronous events
setTimeout(() = > {
// Call resolve when the request succeeds
resolve()
Reject is called when the request fails
reject()
}, 1000)
}).then(() = > {
// 100 lines of processing code when the request succeeds
// ...
// Another asynchronous event, and a Promise
return new Promise((resolve) = >{}) Reject (reject
}).catch(() = > {
// The processing code when the request fails
// ...
})
Copy the code
SetTimeout: setTimeout: setTimeout
setTimeout(() = > {
console.log('Hello World');
console.log('Hello World');
console.log('Hello World');
setTimeout(() = > {
console.log('Hello Vuejs');
console.log('Hello Vuejs');
console.log('Hello Vuejs');
setTimeout(() = > {
console.log('Hello Python');
console.log('Hello Python');
console.log('Hello Python');
}, 1000)},1000)},1000)
Copy the code
Make a Promise
// chain programming
new Promise((resolve, reject) = > { Reject (reject
// The first asynchronous event
setTimeout(() = > {
resolve()
}, 1000)
}).then(() = > {
// The first asynchronous event handler code
console.log('Hello World');
console.log('Hello World');
console.log('Hello World');
// The second asynchronous event
return new Promise((resolve) = > { Reject (reject
setTimeout(() = > {
resolve()
}, 1000)
})
}).then(() = > {
// The code for the second asynchronous event handler
console.log('Hello Vuejs');
console.log('Hello Vuejs');
console.log('Hello Vuejs');
// The third asynchronous event
return new Promise((resolve) = > { Reject (reject
setTimeout(() = > {
resolve()
},1000)
})
}).then(() = > {
// The third asynchronous event handler code
console.log('Hello Python');
console.log('Hello Python');
console.log('Hello Python');
})
Copy the code
Note: The second then() is followed by the first then() and the third then() is followed by the second then(). Instead of following Promise()
9-2. Three states of Promise
9-3. Chain programming of Promise
Network request to AAA -> processed to AAA111 -> processed to AAA111222 -> Rejected to AAA111222Error -> Processed to AAA111222ERROR444. So there is only one asynchronous operation in the whole process.
General chain programming:
new Promise(resolve= > {
setTimeout(() = > {
resolve('aaa')},1000)
}).then(data= > {
console.log(data); // => aaa
// 2. Perform the first processing on the result
return new Promise(resolve= > {
resovle(data + '111')
})
}).then(data= > {
console.log(data); // => aaa111
return new Promise(resolve= > {
resovle(data + '222')
})
}).then(data= > {
console.log(data); // => aaa111222
return new Promise(reject= > {
reject(data + 'error')
})
}).then(data= >{
console.log(data); // There is no output here and it will not be executed
return new Promise(resolve= > {
resovle(data + '333')
})
}).catch(data= > {
console.log(data); // => aaa111222error
return new Promise(resolve= > {
resovle(data + '444')
})
}).then(data= > {
console.log(data); // => aaa111222error444
})
Copy the code
New Promise(resolve => resolve(result))
- ①Promise.resovle() : Wraps the data as a Promise object and internally calls the resolve() function
- ②Promise.reject() : Wraps the data as a Promise object and calls the Reject () function internally
new Promise(resolve= > {
setTimeout(() = > {
resolve('aaa')},1000)
}).then(data= > {
console.log(data); // => aaa
// 2. Perform the first processing on the result
return Promise.resovle(data + '111') // Short for promise. resolve
}).then(data= > {
console.log(data); // => aaa111
return Promise.resovle(data + '222')
}).then(data= > {
console.log(data); // => aaa111222
return Promise.reject(data + 'error') // Promise.reject
}).then(data= >{
console.log(data); // There is no output here and it will not be executed
return Promise.resovle(data + '333')
}).catch(data= > {
console.log(data); // => aaa111222error
return Promise.resovle(data + '444')
}).then(data= > {
console.log(data); // => aaa111222error444
})
Copy the code
Resolve If we want the data wrapped directly as promise.resolve, then we can return the data directly in then
new Promise(resolve= > {
setTimeout(() = > {
resolve('aaa')},1000)
}).then(data= > {
console.log(data); // => aaa
// 2. Perform the first processing on the result
return data + '111' // Short for promise. resolve
}).then(data= > {
console.log(data); // => aaa111
return data + '222'
}).then(data= > {
console.log(data); // => aaa111222
throw data + 'error' // Promise.reject
}).then(data= >{
console.log(data); // There is no output here and it will not be executed
return data + '333'
}).catch(data= > {
console.log(data); // => aaa111222error
return data + '444'
}).then(data= > {
console.log(data); // => aaa111222error444
})
Copy the code
9-4. Promise’s All
A request requires both requests to complete before it can proceed:
Promise.all([]) // Array type, because multiple requests are to be placed
Promise.all([
new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve({name: 'why'.age: 18})},2000)}),new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve({name: 'kobe'.age: 19})},1000)
})
]).then(results= > { // Call only when both requests are complete
console.log(results);
})
Copy the code
Display after two seconds:
Five, Vuex details
1. Know Vuex
Vuex is a state management mode developed specifically for vue.js applications. You can simply think of it as storing all the variables that need to be shared by multiple components in one object. This object is then placed in the top-level Vue instance and made available to other components. Vuex is responsive.
Information shared between multiple interfaces can be placed in Vuex, such as user login status, user name, profile picture, location information, and so on. Such as the collection of goods, items in the shopping cart and so on. All of this state information can be stored and managed in a single place, and it’s responsive
2. Basic use of Vuex
Install Vuex: NPM install Vuex –save
Create a folder under SRC: store
To build the index. Js
import Vue from 'vue'
import Vuex from 'vuex'
// Install the plug-in
Vue.use(Vuex)
const store = new Vuex.Store({
state{},
mutations{},
actions{},
getters{},
modules: {}})/ / export
export default store
Copy the code
Main.js reference (mounted to vue instance)
This way, in other Vue components, we can get the store object as this.$store
import Vue from 'vue'
import App from './App'
import store from './store' / / import store
Vue.config.productionTip = false
new Vue({
el: '#app',
store, / / import store
render: h= > h(App)
})
Copy the code
2-1 legend of Vuex status management
2-2. Small cases
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state{
count = 1000
},
mutations{
increment(state){ / / call the state
state.count++
},
decrement(state){
state.count--
}
}
})
export default store
Copy the code
Mount to the Vue
import Vue from 'vue'
import App from './App'
import store from './store' / / import store
Vue.config.productionTip = false
new Vue({
el: '#app',
store, / / import store
render: h= > h(App)
})
Copy the code
Using vuex
<template>
<div id='app'>
<h2>{{$store.state.count}}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
<script>
export default{
name: 'App'.methods: {add(){
this.$store.commit('increment') // Reference increment method by commit(mutation)
},
sub(){
this.$store.commit('decrement')}}}</script>
Copy the code
3. Core of Vuex
3-1, the State
3-2, Getters
Analogous to computed properties
Basic use: Getters is used to get some state variation from the store.
As arguments: Need to pass arguments: Getters cannot pass arguments by default. If you want to pass arguments, you have to make getters return another function
state:{
student: [{name:'durant'.age:35}, {name:'curry'.age:30}},getters: {more20stu(state){ // Basic usage
return state.students.filter(s= > s.age > 20)},more20stuNumber(state,getters){ // getters as a parameter
return getters.more20stu.length
},
moreAgeStu(state) { // How to pass arguments: return a function
return age= > {
return state.students.filter(s= > s.age > age)
}
}
}
Copy the code
Reference:
<template>
<div>
<h2>{{$store.getters.more20stu}}</h2>
<h2>{{$store.getters.more20stuNumber}}</h2>
<h2>{{$store.getters.moreAgeStu(32)}}</h2>
</div>
</template>
Copy the code
3, Mutation (status update)
(1) Basic use
The only way to update the store state of Vuex is to commit Mutation
mutations{
increment(state){ // The first argument must be state
state.count++
},
decrement(state){
state.count--
}
}
Copy the code
It must be called with commit
methods:{
add(){
this.$store.commit('increment') // Reference increment method by commit(mutation)
},
sub(){
this.$store.commit('decrement')}}Copy the code
(2) Pass parameters
Event name (state, payload) Payload. It can be a parameter or an object. When multiple parameters need to be passed, you can pass them in an object.
mutations{
incrementCount(state,counter){ // The first argument must be state
state.count += counter
}
}
Copy the code
call
methods:{
addCounter(counter){
this.$store.commit('increment',counter)
}
}
Copy the code
(3) Submission style
- ① Common: commit(‘ event name ‘, parameter)
- ② Commit ({type:’ event name ‘, parameter}) object
methods:{
addCounter(counter){
this.$store.commit({
type:'increment',
counter
})
}
}
Copy the code
mutations{
incrementCount(state,payload){ // Payload is an object. Payload is counter
state.count += payload.counter
}
}
Copy the code
(4) Response formula
The state in Vuex’s store is responsive, and the Vue component updates automatically when the data in the state changes. Vuex’s reactive rule: The required properties are initialized in store in advance.
state:{
info: {name:'durant'.number:7.height:2.11
}
},
mutations{
change(state){
state.info.name = 'curry' / / response type
state.info['address'] = 'Brooklyn' // Non-responsive, but info adds address:' Brooklyn '
Vue.set(state.info,'address'.'Washington') / / response type
delete state.info.number // Non-responsive, but info deletes number:7
Vue.delete(state.info,'number') / / response type
// The second argument to vue. set and vue. delete can only be string or number}}Copy the code
<template>
<div>
<h2>{{$store.state.info}}</h2>
<button @click='change'>change<button>
</div>
</template>
<script>
export default{
name: 'App'.methods: {change(){
this.$store.commit('change')}}}</script>
Copy the code
(5) Constant type
In mutation, we defined many event types (that is, method names within them).
As our project grew, there were more and more methods in Vuex managed Mutation, and there were too many methods. Users needed to spend a lot of experience to remember these methods, even switching back and forth between multiple files to check method names, and even writing errors might occur if it was not copied.
The official recommendation is to replace the Mutation event type with constants. We can place these constants in a single file for easy management and visibility of all event types throughout the app.
New mutations -type. Js
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
Copy the code
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT,DECREMENT} from "./mutations-types" // Import a constant type
Vue.use(Vuex)
const store = new Vuex.Store({
state{
count = 1000
},
mutations{
[INCREMENT](state){ // [constant](){}
state.count++
},
[DECREMENT](state){
state.count--
}
}
})
export default store
Copy the code
Using vuex
<template>
<div id='app'>
<h2>{{$store.state.count}}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
<script>
import {INCREMENT,DECREMENT} from "./mutations-types" // Import a constant type
export default{
name: 'App'.methods: {add(){
this.$store.commit(INCREMENT) // No longer a string
},
sub(){
this.$store.commit(DECREMENT)
}
}
}
</script>
Copy the code
(6) Only synchronous operation
Vuex requires that the methods in our Mutation must be synchronous methods.
The main reason is that devTools can help us capture mutation snapshots when we use devTools. However, if the operation is asynchronous, DevTools will not do a good job of tracking when the operation is completed.
3-4, the Action
Action is similar to Mutation, but is used instead of Mutation to perform asynchronous operations.
The first argument, context, is an object that has the same methods and properties as the Store object. You can also pass payload.
Call: is dispatch.We can use promises when we execute some code when our asynchronous operation or network request succeeds or fails. Put asynchronous operations or network requests in promises, butThen () and catch() follow dispatch.
3-5, the Module
Vuex allows us to divide the store into modules, and each Module has its own state, mutations, actions, getters, etc. But modules should be two at most.