Chapter one, Vue core
1.1. Initial Vue
<div id="root"></div>
Is a container that does not write the original HTML code, but Vue template code- The so-called template code is a combination of HTML + JS
- {{XXX}} XXX automatically reads the XXX property in data
- A Vue instance can only serve one container
<body>
<! <div id="root"></div> is a container that contains Vue template code instead of original HTML code. {{XXX}} XXX automatically reads the XXX attribute in data. A Vue instance can only serve one container -->
<! -- Get a container ready -->
<div id="root">
<h1>{{school.message}}</h1>
<h1>I am studying in {{school.name}}</h1>
<h1>This school is located at {{school.address}}</h1>
<! If it is a function, it needs to be executed with parentheses.
<h1>My major is {{school.subject()}}</h1>
<hr>
<! Name = "home college "-->
<h1>{{school.name,school.subject}}</h1>
<! -- displayed address "Home Squat Province, China "-->
<h1>{{school.message && school.address}}</h1>
</div>
<! -- IMPORT JS -->
<script src=".. /js/vue.js"></script>
<script>
// Create a Vue instance and pass in the configuration object
new Vue({
el: '#root'.//el specifies which container is served by the current Vue instance. The value is a selector string
data: { // Data is the place where data is stored. It provides data for the container root, and its value is an object, similar to state in React
school: {
message: 'Hi, my name is Even.'.name: 'College at home'.address: 'Squatting at home in China'.subject: () = > 'Network programming',}}});</script>
</body>
Copy the code
1.2. Template syntax in Vue
- The interpolation of grammar
- Function: Used to parse the contents of the label
- Syntax: {{XXX}} will be parsed as an expression, and can automatically read data in the XXX attribute
- Command syntax
- Function: Used to parse tags “including: tag attributes, tag content, event binding……”
- For example: v-bind:href=” XXX”
:
<body>
<! {{XXX}} will be used as expressions to parse, and can automatically read data inside the XXX attribute + instruction syntax function: used to parse tags "including: Tag properties, tag content, event binding......" Example: v-bind:href=" XXX "or: : -->
<! -- Prepare a container -->
<div id="root">
<h1>{{message}}</h1>
<h1>{{message.toUpperCase()}}</h1>
<hr>
<h2>Command syntax</h2>
<a v-bind:href="url">Google it.</a>
<a :href="url">Click me to look at the cat</a>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
message: 'kele'.url: 'http://www.baidu.com'}});</script>
</body>
Copy the code
1.3. Data binding in Vue
- One-way data binding (V-bind): Data can only flow from data to pages
- Two-way data binding (V-Model): Data flows not only from data to pages, but also from pages to data
- Note:
- Two-way data binding is generally for values that can be entered, for example:
<input><select><textarea>
Etc. - V-model: Value can be shortened to V-model because v-model collects value values by default
- Two-way data binding is generally for values that can be entered, for example:
<body>
<! -- 1. V-bind: Data can only flow from data to page 2. Two-way data binding (V-model): Data flows not only from data to pages, but also from pages to data. 2. V-model: Value can be shortened to V-model because v-model collects value values by default -->
<! -- Prepare a container -->
<div id="root">
<! -- V-bind: <input type="text" V-bind :value='message'> <input type="text" v-model:vlue='message'> -->
<p>Single data binding (V-bind) :<input type="text" v-bind:value='message'>
</p>
<p>Two-way data Binding (V-Model) :<input type="text" v-model='message'>
</p>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
message: 'Data binding'}});</script>
</body>
Copy the code
1.4. Initial MVVM
Note: MVVM is data-binding and all data communication is bidirectional
- M: Model Model, corresponding to data in data
- V: View, corresponding to template code
- VM: ViewModel, corresponding to Vue instance object. It is the bridge between the View layer and the Model layer. On the one hand, it realizes Data Binding, which reflects the Data changes of the Model layer to the View layer in real time. On the other hand, it implements a DOM Listener, which can listen when some DOM event (click, scroll, touch, etc.) occurs and change the corresponding Model layer data if necessary.
<body>
<! -- MVVM: + M: Model corresponds to data in data + V: View corresponds to template code + VM: ViewModel corresponds to Vue instance object -->
<div id="root">
<h2>{{message}}, day day up</h2>
</div>! [1.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b5b911109b4e4ab888f4129299740999~tplv-k3u1fbpfcp-watermark.ima ge)<script src=".. /js/vue.js"></script>
<script>
// The first way to write data, data is an object
const vm = new Vue({
el: '#root'.data: {
message: 'Study hard',}});// The attributes in data can be seen through the VM.
setTimeout(function () {
console.log(vm.message); // Attributes in data can be read from vm
vm.message = 'Up every day'; // You can also modify the data in the DATA using the VM, and the data in the page is automatically updated after the modification
}, 1000);
</script>
</body>
Copy the code
1.5 Two ways of writing data and EL
There are two ways to write el
- When new Vue is passed the EL attribute “common”
- $mount(‘#root’);
There are two ways to write data
- Object: Non-component coding can write objects as well as functions
- Functional: Data must be written in functional form when the component is encoded and must return an object
One of the most important rules in Vue is that all functions called by Vue should not be written as arrow functions. Once arrow functions are written, this will refer to the wrong “undefined or window”.
<body>
<! 1. There are two ways to write el: $vm.$mount('#root') $vm.$mount('#root') $vm. (2) Functional: Data must be written as a functional Vue when composing code. One of the most important principles of Vue is: * * * * * * * * * * * * * * * * * * * * * * * *
<div id="root">
<h2>{{message}}, day day up</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
/* new Vue({el: '#root', data: {message: 'learn ',}}); * /
/* const vm = new Vue({el: '#root', data: {message: 'learn ',}}); vm.$mount('#root'); * /
// The first way to write data, data is an object
new Vue({
el: '#root'.data: {
message: 'Study hard',}});// The second way of writing data is that data is a function that returns an object.
new Vue({
el: '#root'./* Note: 1. Do not write data as an arrow function, write it as a normal function, otherwise this refers to window instead of Vue instance 2. If we use the data function, Vue will help us call the data function, and Vue will get the data object returned, thus using, this is Vue instance object */
data: function () { //
console.log(this); //Vue instance itself
return {
message: 'Study hard',}}});</script>
</body>
Copy the code
1.6. Data broker
In ve2. X, data hijacking is implemented using the Object.defineProperty API
Object.defineProperty(obj, prop, desc)
Copy the code
- Obj needs to define the current object of the property
- Prop Specifies the name of the property to be defined
- Desc attribute descriptor
<body>
<script>
let person = {};
// This in set and get is the current object
Object.defineProperty(person, 'name', {
set(value) { // When modifying person.name, set is called and the set receives the new value
console.log("I'm set. I'm called.", value);
},
get() { // When reading person.name, get is called,
console.log("I'm get, I'm called."); }}); person.name ='kele';
console.log(person.name);
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// Simulate the data broker
let _data = { message: "Study hard." };
let vm = {};
Object.defineProperty(vm, 'message', {
set(value) {
_data.message = value;
},
get() {
return_data.message; }})console.log(vm);
</script>
</body>
Copy the code
About the data broker in Vue
- What is a data broker?
- The data in the configuration Object is collected into vm._data, and then all the attributes in data are made available to the VM via Object.defineProperty
- When you access name in the VM, you return the value of the property of the same name in _data
- When you change the name in the VM, you change the value of the property of the same name in _data
- Why a data broker?
- In order to easily read and modify the data in _data, do not do the data proxy, you need to access the data through: vm._data. XXX
- Extended thinking: why collect data in _data and then delegate it out?
- “Collecting data directly on the VM is inefficient” for more efficient monitoring
<body>
<! -- About data brokers in Vue 1. What is data brokers? (1). Configure the data in the Object, the data will be collected in vm._data, and then use object.defineProperty to make the VM have all the attributes in data (2). When you access name in the VM, you return the value of the property of the same name in _data (3). When you change the name in the VM, you change the value of the _data attribute with the same name 2. Data proxy: vm._data. XXX data proxy: vm._data. XXX Extended thinking: why collect data in _data and then delegate it out? For more efficient monitoring data "it is inefficient to collect data directly from VM" -->
<! -- Prepare a container -->
<div id="root">
<h2>Company Name: {{name}}</h2>
<h2>Address: {{address}}</h2>
<h2>Position: {{job}}</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
const vm = new Vue({
el: '#root'.data: {
name: 'Zhongguancun Technology Co., LTD.'.address: Zhongguancun, Beijing.job: 'Front-end Development Engineer'}});console.log(vm);
</script>
</body>
Copy the code
1.7. Event handling
Binding to monitor
- v-on:xxx=”fun”
- @xxx=”fun”
- @ XXX = “fun (parameters)”
- The default event parameter is event
- Implied attribute object: $event
Event modifier
.prevent
: Prevent event’s default behavior “for native JS: event.preventdefault ()”.stop
“Corresponding to native JS: event.stopPropagation()”- Event modifiers can be written consecutively, and the order can be changed at will
Key modifier
- Keycode: A key that operates on a keycode value
- KeyName: the key (small part) of the keyName of the operation
<body>
<! -- Prepare a container -->
<div id="root">
<h2>{{message}}</h2>
<! -- Event binding -- standard way -->
<p>
<button v-on:click='show1'>Click me to display information (V-ON binding)</button>
</p>
<! -- Event binding -- short form -->
<p>
<button @click='show1'>Click display info (@ bound)</button>
</p>
<! -- Event bound -- pass parameters -->
<p>
<button @click='show2($event,666)'>Click display info (@ bound)</button>
</p>
<! Event-bound -- prevent prevents default behavior -->
<p>
<a href="https://www.baidu.com" @click.prevent='show3'>Click my jump link (@ bound)</a>
</p>
<! -- Event bound -- stop event bubbling, stop event modifier -->
<div @click='show4'>
<button @click.stop='show4'>Click my prompt message (to block default behavior)</button>
</div>
<! -- Event binding -- prevents events from bubbling, event modifiers can be written consecutively, and the order can be changed arbitrarily -->
<div @click='show4'>
<a href="https://www.baidu.com" @click.stop.prevent='show4'>Click my prompt message (to block default behavior, event modifiers can be conjoined)</a>
</div>
<hr>
<! -- Keyboard events -->
<! -- <input @keyup.enter='show5' type="text" placeholder=" placeholder ">
<! -- <input @keyup.13='show5' type=" placeholder "placeholder=" placeholder ">
<input @keyup.left='show5' type="text" placeholder="Please enter user name">
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: { // Used to configure data
message: 'the web front end',},methods: { // Used for configuration methods
show1(event) { // Show must not be an arrow function, otherwise this would point to the window
// console.log(this); This is: Vue instance
alert(event.target.innerText);
},
show2($event, number) {
console.log(event);
alert(event.target.innerText + number)
},
show3(event) {
// Block default behavior based on native JS
// event.preventDefault();
alert(event.target.innerText);
},
show4(event) {
// Prevent bubbling based on native JS
// event.stopPropagation();
alert('Click my prompt message (to block default behavior)');
},
show5(event) {
// It is up to the programmer to decide the keys
// if (event.keyCode ! == 13) return; Output key codealert(event.target.value); }}});</script>
</body>
Copy the code
1.8. Computed attributes
- Usage scenario: For computed attributes, data to be displayed does not exist and needs to be computed
- Advantages: Compared with methods,
Computed has an internal cache
More efficient - Note: The calculated property is for direct reading, do not add ().
<body>
<! -- 1. Computed data to be displayed does not exist, and needs to be computed. 2. Execution time: - will be executed once when initially displayed - will be called again when dependent properties change 4. Advantages: Compared with methods, computed with internal cache has higher efficiency. Note: Calculated properties are for direct read use, do not add () -->
<div id="root">Last name:<input type="text" v-model='firstName'><br />Name:<input type="text" v-model='lastName'><br />
<span>Full name: {{fullName}}</span><br />Full name:<input type="text" v-model='fullName'>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
firstName: ' '.lastName: ' ',},computed: {
/* who is calling fullName? ----> when is Vue instance fullName called? */ is called when the page is rendered for the first time. */ is also called when the dependent data changes
// Is a function that can only be read, but cannot be modified
// fullName() {
// console.log(this);
// return this.firstName + '-' + this.lastName;
// }
// Is an object that can be modified or read
fullName: {
set(value) { // Set is called when fullName is changed.
const arr = value.split(The '-');
this.firstName = arr[0];
this.lastName = arr[1];
console.log('Set is called');
},
get() { // When fullName is read, get is called, and this in set is vm,
console.log('Get is called');
return this.firstName + The '-' + this.lastName; }}}});</script>
</body>
Copy the code
1.9. Data Monitoring Watch
- When the detected time changes, the callback function is automatically called to perform the related operation
- Property must exist in order to monitor
- Two ways to write monitoring:
- The watch configuration item is passed in the new Vue
- Monitor through vm.$watch
The difference between computed and Watch
- What computed can do, watch can do
- Cpmputed can’t do what watch can do, for example, watch can do
Asynchronous operations
<body>
<! -- Check property watch: 1. When the detected time changes, the callback function is automatically called to perform related operations 2. Attribute must exist before monitoring. 3. Two ways of monitoring: a. Pass in the watch configuration item when new Vue b. Monitor the difference between computed and watch through vm.$watch 1. As long as it is computed, watch can do it. 2. What watch can do, cpmpuTED cannot do, for example, watch can perform asynchronous operations. Do not write all functions managed by Vue as arrow functions ---- for example: functions in watch, functions in computed 2. All functions not managed by Vue should be written as arrow functions ----, for example: callback of timer, callback of Ajax, etc. 3. Watch is a means provided by Vue to detect data changes. As for what to do after data changes, it depends on the business logic for example: You need a new value to compare with the old value, you don't need a value to decide what to do next, you send a request whenever the data changes, and so on -->
<div id="app">Last name:<input type="text" v-model="firstName"><br>Name:<input type="text" v-model="lastName"><br>Full name:<input type="text" v-model="fullName">
</div>
<script src=".. /js/vue.js"></script>
<script>
const vm = new Vue({
el: '#app'.data: {
firstName: '张'.lastName: '三'.fullName: ' '
},
watch: {
/* 1. When is firstName called in watch? When firstName in data is changed, who is this of firstName in watch? ---vm */
// Check for short names
// firstName(newValue, oldValue) {
// this.fullName = newValue + '-' + this.lastName;
// },
// Check the complete last name
// firstName: {
// immediate: true, // If immediate is true, this handler will be called once during initialization
// handler(newValue, oldValue) {
// this.fullName = newValue + '-' +this.lastName;
/ /}
// },
/ / testing
lastName(newVlaue, oldValue) {
this.fullName = this.firstName + The '-'+ newVlaue; }}}); vm.$watch('firstName', {
immediate: true.// If immediate is true, the handler is called once during initialization, depending on how firstName changes
handler(newValue, oldValue) {
setTimeout(() = > { // The timer must be an arrow function, otherwise this will point to the window
this.fullName = newValue + The '-' + this.lastName;
},1000); }});console.log(vm);
</script>
</body>
Copy the code
1.10. Binding styles
Bind class style
- Grammar:
:class="xxx"
XXX can be a string, an array, an object- String notation for class: this is useful when the class name is uncertain and needs to be obtained dynamically
- Object notation for class: applies to class names, but does not determine whether to use them
- Array notation for classes: This is useful for using multiple classes at the same time
Bind style styles
- Grammar:
:style="{color:activeColor, fontSize: fontSize + 'px'}"
- Where activeColor/fontSize is an attribute in data
- Note: The fontSize attribute should be written in the form of a small camel. Do not write font size as this will cause syntax errors
<! DOCTYPEhtml>
<html>
<head>
<title>Binding style</title>
<style>
.larger {
font-size: 24px;
}
.classA {
background-color: darkcyan;
}
.classB {
border: 3px solid darkorange;
}
.classC {
color: rgb(223.47.47);
}
</style>
</head>
<body>
<! -- 1. Bind class style :class=" XXX "XXX can be a string, array, object 2. Style ="{color:activeColor, fontSize: fontSize + 'px'}
<! -- Prepare a container -->
<div id="root">
<! -- class = string; -- class = string; -->
<h2 class="larger" :class="myStyle">{{title}}</h2>
<! Class (); class ();
<h2 class="larger" :class="{classB:hasB,classC:hasC}">{{title}}</h2>
<! Class = 'class'; class = 'class';
<h2 class="larger" :class="hasB? 'classB':''">{{title}}</h2>
<! Class array: use multiple classes at the same time
<h2 class="larger" :class="[a,b,c]">{{title}}</h2>
<! Style -->
<! Font size = "font size"; font size = "font size";
<h2 :class="[a,b]" :style="{fontSize:size + 'px'}">{{title}}</h2>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
title: "For god's sake, I'm pre-school.".myStyle: "classA".hasB: true.hasC: true.a: 'classA'.b: 'classB'.c: 'classC'.size: 40}});</script>
</body>
</html>
Copy the code
1.11 conditional Render “V-show/V-if”
V-show is similar to V-if
- Both v-show and V-if are used to show hidden elements. V-if and v-else are used together to achieve the same effect. There is a big difference in performance
v-show
- Features: Regardless of whether the condition is true or false, it is compiled the first time it is rendered, meaning labels are added to the DOM. And then when you switch, you use display: None; Style to show hidden elements. It is worth noting that DOM nodes that are not shown in v-Show are not removed, but are simply hidden with CSS style dispaly with little performance impact.
- Usage scenario: A scenario with high switching frequency
v-if
- Features: On the first rendering, if the condition is false and nothing is done, the current page will not render these elements. Elements are rendered when the condition is true.
- Usage scenario: The switchover frequency is not high
performance
- V-if is definitely more performance consuming, because v-IF adds and removes DOM during show and hide, causing DOM backflow and redrawing, whereas V-Show is much simpler, just manipulating CSS.
Pay special attention to
- When v-if is used, can the DOM node pit obtain “if the conditions do not meet the DOM node is directly deleted”? The DOM node can be obtained by using v-showv-show
- when
v-if
andv-for
When used together,v-for
Priority ratio ofv-if
higher
<! DOCTYPEhtml>
<html>
<head>
<title>Conditional render "V-show/V-if"</title>
<style>
img {
width: 400px;
}
</style>
</head>
<body>
<! -- Conditional rendering: V-show: suitable for: scenes with high switching frequency Features: Not shown DOM nodes are not deleted, just hidden with CSS style dispaly V-if: Suitable for: scenes with low switching frequency features: not shown DOM nodes are deleted directly; DOM nodes are deleted if the conditions are not met. DOM nodes are deleted if the conditions are not met. DOM nodes are deleted if the conditions are not met.
<div id="root">
<h2>Click me to switch sun Wukong skin: {{skin? 'Hellfire ':' Supreme Treasure '}}</h2>
<button @click="skin=! skin">Click me to switch skin</button><br><br><br><br>
<! -- Use v-show for conditional rendering: it controls the display property value in CSS styles to show or hide -->
<! - show - < div v = "skin" > < img SRC = "https://s3.jpg.cm/2021/08/30/IH0XXp.jpg" Alt = "" > < br > < span > success switch for hellfire skin < / span > < / div > -- >
<! -- <div v-show="! Skin "> < img SRC =" https://s3.jpg.cm/2021/08/30/IH0cv6.jpg "Alt =" "> < br > < span > success switch for the sovereign treasure skin < / span > < / div > -- >
<! - = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -- -- >
<! -- v -- if/v -- else -- if/v -- else -- if/v -- else
<div v-if="skin">
<img src="https://s3.jpg.cm/2021/08/30/IH0XXp.jpg" alt=""><br>
<span>Successfully switched to Hellfire skin</span>
</div>
<div v-else=! "" skin">
<img src="https://s3.jpg.cm/2021/08/30/IH0cv6.jpg" alt=""><br>
<span>Successfully switched to Supreme Treasure skin</span>
</div>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
skin: true}});</script>
</body>
</html>
Copy the code
1.12. V-for instruction
- grammar
v-for="(item,index) in arr" :key="item.id"
- You can iterate over groups, objects, strings…
It is recommended to provide keys whenever possible when using V-for
Do not use values of non-primitive types such as objects or arrays as v-for keys. Use a string or numeric value.
<! DOCTYPEhtml>
<html>
<head>
<title>List rendering "V-for command"</title>
</head>
<body>
<! Syntax: V-for ="(item,index) in arr" :key="item.id" 3. It is recommended that v-For keys be provided whenever possible. Do not use values of non-basic types such as objects or arrays as v-FOR keys. Use a string or numeric value. 3. You can iterate over groups, objects, and strings...... -->
<div id="root">
<! -- v-for: loop array -->
<h2>Personnel information</h2>
<ul>
<li v-for="(item,index) in persons" :key="item.id">. Name: {{item name}} - age: {{item. Age}} - work: {{item. Job}}</li>
</ul>
<! -- v-for: loop object -->
<h2>Cell phone information</h2>
<ul>
<li v-for="(value,key) in phone" :key="key">{{value}}</li>
</ul>
</div>
<script src=".. /js/vue.js"></script>
<script>
new Vue({
el: '#root'.data: {
persons: [{id: '001'.name: 'Joe'.age: '40'.job: 'teacher' },
{ id: '002'.name: 'bill'.age: '35'.job: 'lawyer' },
{ id: '003'.name: 'Cathy'.age: '33'.job: 'boss'},].phone: {
phoneModel: 'ipone12'.price: '6299 yuan'.color: 'purple'}}});</script>
</body>
</html>
Copy the code