Introduction to vue
vue Chinese official website
An incremental JavaScript framework for dynamically building user interfaces
vue features.
- Follow the MVVM pattern
- Adopt componentization mode to improve code reuse rate and make code better maintained
- Declarative coding, no need to directly manipulate the DOM, improve development efficiency, coding simplicity, small size, high operational efficiency
- It focuses only on UI, but can also introduce other three-way library development projects
- Use virtual DOM + good Diff algorithm to reuse DOM nodes as much as possible
environmental preparation
1.import vue
-
Imported as a CDN package on the page
<! -- cdn links --> <script src="/npm/[email protected]/dist/"></script> <! -- production environment, it is recommended to link to an explicit version number and build file to avoid unanticipated damage caused by new releases -->! <script src="/npm/[email protected]"> </script>
-
Download Js source code file via script import
<script src="local source code path"></script>
-
npm
When building large applications with Vue, it is recommended to install npm. npm works well with packagers such as webpack or Rollup.
# Latest stable version npm install vue@next
-
Scaffolding tools (CLI)
Vue provides an official CLI for quickly building cumbersome scaffolding for single page applications (SPAs). It provides a full-featured build setup for modern front-end workflows. It takes just a few minutes to get up and running with hot reloads, save-time lint checksums, and build versions available for production environments!
npm install -g @vue/cli
-
Vite
Vite is a new web development build tool developed by YouYuxi, due to its native ES module import method, it can realize lightning fast cold server startup, by running the following commands in the terminal, you can use Vite to quickly build Vue projects
npm init vite@latest <project-name> --template vue cd <project-name> npm install npm run dev
global configuration
is an object that contains Vue's global configuration, which can be modified before starting the application.
Configuration Details
// Stop vue from generating production prompts at startup.
= false
vue example
- To make Vue work, you have to create a Vue instance and pass in a configuration object
- The code in the container still conforms to the html specification, just with some special Vue syntax mixed in
- The code in the container is called a Vue template
- Vue instances and containers are one-to-one correspondences, a vue instance can only correspond to one instance
- In real development there is only one instance of Vue and it will be used in conjunction with the component
- You can write js expressions (1+1, ()) in {{Interpolation Syntax}}, and the expression can automatically read all the attributes in the data
<body>
<! --Create container with ID root -->
<div >
<! -- Interpolation syntax to associate the name field in the data object of the created vue instance -->
<h1>{{name}}</h1>
</div>
</body>
<script>
// Stop vue from generating production prompts on startup.
= false
// Create a Vue instance, parameterized with a configuration object
new Vue({
// el is short for element. el is used to specify which container the current Vue instance serves, and is usually a css selector string.
// It is also possible to use el:("root").
// Associate the container whose ID is root
el: "#root", // data is used to store data.
// data is used to store data to be used by the container specified by el.
data:{
name: "vue"
}
})
</script>
Stencil syntax
There are 2 main categories of Vue template syntax:
Interpolation syntax:
Function: Used to parse the contents of the label body.
Write: {{xxx}}, xxxjs expression and can read all properties in data directly.Command syntax:
Function: for parsing tags (tag attributes, tag body content, binding events, etc.)Write:Vue has a lot of directives and the form is: v-xxxx: expression, xxx is a specific directive, the directive is also written in the js expression
<body>
<! --Create container with ID root -->
<div >
<! -- Interpolation syntax -->
<h1>{{name}}</h1>
<! -- Command syntax -- > <!
<! -- v-bind means bind, bind the url of data to href, after using v-bind the "" of href is no longer a string but a js expression -->!
<! -- Equivalent to <h2> <a href=""> Baidu</a> </h2> -->
<h2><a v-bind:href="url">Baidu it</a></h2>
<! -- v-bind shortened form, used directly: -->!
<h2> <a :href="url"> Baidu shorthand </a> </h2>
</div>
</body>
<script>
new Vue({
el: "#root",
data: {
name: "vue", url: "
url: ""
}
})
</script>
data binding
There are 2 ways of data binding in Vue:
- Unidirectional binding (v-bind): data can only flow from data to page.
- Bidirectional binding (v-model): data can flow not only from data to page, but also from page to data.
- Bidirectional binding is generally applied to form-like elements (input-like elements)
- v-model:value can be abbreviated to v-model because v-model collects value by default.
<body>
<div >
One-way data binding: <input type="text" v-bind:value="name">
Unidirectional data binding shorthand: <input type="text" :value="name">
<br>
Two-way data binding: <input type="text" v-model:value="">
<br>
Bidirectional data binding shorthand: <input type="text" v-model="" >
<! -- Bidirectional Data Binding -- When data changes in one place, it changes in all referenced places.
When the data in the data model changes, the views bound to it are automatically updated to reflect the new data state;
Conversely, when a user changes the data at the view level through an interaction (e.g., typing in an input box, selecting a drop-down menu option, etc.), the data model is updated accordingly - >
</div>
</body>
<script type="text/javascript"> </div> </body>
= false
new Vue({
el:'#root', data:{
data:{
name:'vue', info:{
info:{
category: "Category"
}
}
})
</script>
Two ways to write vue instance creation
- The first way
new Vue({
// The first way to write this is to mount the container directly when creating the instance
el:'#root', // First method: object-based.
// The first way to write it: object-style
data:{
name:'vue'
}
})
- The second way
// Create a Vue instance
const vm = new Vue({
// Second way: functional, must return an object
data:function (){
// here this is the Vue instance object
return{name: "vue"}
}
})
// Bind the container via the $mount method, which is a method on the vue prototype that mounts the vue with the specified container
vm.$mount("#root")
- el can be used either way, the creation of data for subsequent use of the component must be done using a functional
- Functions managed by Vue, be sure not to write an arrow function, once the arrow function is written, this is no longer a Vue instance, but Window
MVVM model
- M: model (Model): data in the data
- V: View (View): Template Code
- VM: ViewModel: Vue Example
- All the attributes in data end up on the vm.
- All properties on the vm and all properties on the Vue prototype can be used directly in the Vue template.
Js's
Used to define a new property on an object or modify an already existing property. It allows precise addition or modification of an object's attributes, including the attribute's value, enumerable, configurable, and read-write.
// Create an object
let user = {
name: "test",
age: 18
}
// Use: (obj, prop, descriptor)
// Parameters
// obj: is the target object on which the property is to be defined.
// prop: is the name of the property to be defined or modified on the target object.
// descriptor: is an object that describes the various characteristics of the property. It can contain the following key-value pairs:
// value: the value of the property. For example, { value: 42 } would set the value of the property to 42.
// writable: a boolean value indicating whether the property is writable. The default is false, and the value cannot be reassigned. For example, { writable: false, value: 'immutable' } defines a property that is not writable.
// enumerable: a boolean value indicating whether the property is enumerable. Defaults to false when using a for... . in loops or () methods, etc., the property will not be enumerated.
// configurable: a boolean indicating whether the property is configurable. Defaulting to false prevents the property from being deleted and property descriptors other than value and writable (such as enumerable and configurable) from being modified
//
// The getter and setter methods, read and write, are mutually exclusive with some of the above properties.
// Add a num attribute to the user object with a value of 20
(user, "num", {
value: 20,
writable: true,
enumerable: true,
configurable: true,
})
let test = 10
// Add a test attribute to the user object
(user, "test", {
// value/writable and get/set are mutually exclusive.
// When using define attributes, you cannot specify both value (or writable) and get/set.
// The reason for this is that they represent two different modes of defining attributes. value and writable are used to define a simple data attribute, where the value is stored directly, and the read and modify operations are basic assignment and retrieval.
// whereas get and set define accessor attributes, where the logic for reading and writing the attribute is controlled by custom functions, and the value of the attribute may be stored elsewhere, not simply by value.
configurable: true,
// The get function is called when the user's test attribute is read, and the return value is the value of num.
get: function () {
("The test property was called.")
return test
}, // When the user's test property is modified, the return value is the value of num.
// The set function is called when the user's test property is modified and receives the modified value
set: function (value) {
(`The test attribute was modified with value ${value}`)
test = value
}
})
data broker
Data proxies: Proxy operations (read/write) on properties in one object through another object.
The Data Agent Concept
let user1 = {num:100}
let user2 = {}
// Add a num attribute to user2
(user2, "num",{
// When reading the num attribute of user2, the return is the num of user1
get() {
return
},
// When modifying user2's num property, user1's num is modified.
set(value){
= value
}
})
Data proxies in vue
- Data proxies in Vue:
Proxy operations (read/write) on attributes in the data object through the vm object- Benefits of data proxies in Vue:
Easier manipulation of data in data- Fundamentals:
Add all attributes in the data object to the vm via ().
Specify a getter/setter for each property added to the vm.
Manipulate (read/write) the corresponding attributes in data within the getter/setter.
- Principle Example
// 1. The data object is stored in the _data property when the vue instance is created.
// 2. Define getter and setter methods that add properties from the _data object to the vue.
// The defined getter and setter methods return and modify the corresponding properties in _data, so we can access the proxy data through the vue instance object.
// Simulating the vue proxy mechanism
// Simulating a Vue instance (reduced to a normal object here to understand the principle), the actual _data implements the data hijacking
const vm = {
// Properties used to store data, simulating Vue's _data property
_data: {},
// Constructor to simulate the Vue instance creation process
constructor() {
// Assign the incoming data object to the _data property, similar to how Vue handles it internally
this._data = {. .dataObject };
// Iterate over all the properties in _data and create data proxies for them.
for (let key in this._data) {
(this, key, {
get() {
return this._data[key];
},
set(v) {
this._data[key] = v; }, set(v) { return this._data[key]; }, set(v)
}
});
}
}
}
- Using proxy data
// Combined with the principle that vue implements a data proxy, we can access and modify data in the following two ways
const vm = new Vue({
el: "#root",
data: {name: "vue"}
})
// via the _data object
(vm._data.name)
//
()
event processing
- Bind events using v-on:xxx or @xxx, where xxx is the event name;
- The callbacks for events need to be configured in the methods object of the Vue options parameter and will end up on the vm;
- Functions configured in methods, don't use arrow functions! Otherwise this is not a vm;
- The functions configured in methods are functions that are managed by Vue, and this points to the vm or component instance object;
Basic use
<div >
<! -- Binding click events -- way one -- >
<button v-on:click="info"> Show info </button>
<! -- Binding a click event -- way two -- >
<button @click="info">Show info2</button>
<! -- Bind to click event -- Callback function passing parameters Pass event object using $event, if you don't need to use event, you can leave it out and just pass custom parameters -- >!
<button @click="info2($event,66666)"> Display info3</button>
<! -- The callback function can pass no event object, which can then be used directly inside the function -- >
<button @click="info3"> display info4</button>
</div>
</body>
<script type="text/javascript">;
const vm = new Vue({
data: {name: "vue", }
data: {name: "vue"}, // configure the callback method.
// Configure the callback method, which is also ultimately stored on the vm, no data proxy is done
methods: {
// Callback methods
info() {
alert("hello world")
}, // The callback method is also ultimately stored on the vm.
info2(event,number){
(this) // here this is the vm, if you use the arrow function this is the window
alert( + ())
}, info3(e){
info3(e){
()
}
}
})
</script>
event modifier
- prevent: block default events
- stop: stops the event from bubbling
- once: the event is triggered only once
- capture: use the capture mode of the event
- self: the event is triggered only if it is the currently operated element.
- passive: the default behavior of the event is executed immediately, without waiting for the event callback to finish execution
<! -- a tag configured for clicked event callbacks - triggered info method - clicked event behavior set prevent, -->.
<! -- prevent-Blocks the default event, i.e. clicking on a hyperlink does not trigger the jump effect -->!
<a href="" @="info"> Baidu</a>
<a href="" v-on:="info">Baidu2</a>
<! -- A div with a click event bound to it and a button inside with a click event bound to it triggers event bubbling -->!
< div @click="info" style="width: 100px;height: 100px;background-color: yellow">!
<! -- stop - stops the event from bubbling - >!
<button @="info"> dot</button>
</div>
<! -- The button is bound to a click event -- >!
<! -- once-event will only fire once -->!
<button @="info"> only once</button>
<! -- div binds the click event -- >!
<! --Using the event's capture mode, the capture phase triggers the event -->
<div @="info" style="width: 100px;height: 100px;background-color: yellow">
<div @click style="width: 50px;height: 50px;background-color: gold"></div>
</div>
<! -- Event is triggered only if it is the currently operated element -- >
<div @="info" style="width: 100px;height: 100px;background-color: yellow">
<button> button</button>
</div>.
<! -- The default behavior is triggered immediately when the event is triggered, without waiting for the event callback to finish executing -->!
<div style="height: 200px; overflow: auto" @="handleScroll">
Keyboard Events
Keyboard events are available:
keyup: triggered when a key on the keyboard is pressed and released.
keydown: triggered when the user presses a key on the keyboard.
keypress: triggered by pressing and releasing a key that prints characters (e.g. letters, numbers, punctuation marks, etc.)
Basic use
<body>
<! -- keyboard event - print keyup pressed - >
<input type="text" @keyup="info">
</body>
<script type="text/javascript">
const vm = new Vue({
data: {name: "vue", }
data: {name: "vue"}, // configure the callback method.
// Configure the callback methods
methods: {
// Callback methods
info(e) {
()
},
}
})
</script>
Key aliases for keyboards
<! -- vue's common key aliases -- >!
<! -- enter => enter -->
<! -- delete => delete (captures "delete" and "backspace" keys) --> <!
--<! -- exit => esc--> <!
<! -- space => space--> <!
<! -- line feed => tab (special, must be used with keydown)--> <!
<! -- up => up--> <!
up--> <! -- down => down--> <!
down--> <! -- left => left--> <!
left-->! -- right => right--> <!
<! -- keyboard events -- not triggered when key is pressed, need to be triggered when enter is pressed--> <!
< input type="text" @="info" >
<! --Also can be triggered by keycode - not recommended - deprecated --> < input type="text" @="info" > <!
< input type="text" @keyup.20="info"> <!
Trigger events by key name
<div >
<! -- Vue does not provide an alias for the key, you can use the key's original key value to bind -- >!
<! -- Get the key name and key code in the callback via and respectively -->!
<! -- You can get the key name via key-name(), which needs to be converted to lowercase each word -separated if it's a big hump name -->
<! --Triggered when pressing case-sensitive keys - CapsLock === caps-lock -->!
< input type="text" @-lock="info">
</div>
</body>
<script type="text/javascript">; </div> </body>
const vm = new Vue({
data: {name: "vue", }
data: {name: "vue"}, // configure the callback method.
// Configure the callback methods
methods: {
// Callback methods
info(e) {
() // Key CapsLock
() // Keycode 20
},
}
})
Customizing custom key names
. Custom key name = keycode, can go to customize key aliases
// Set case-sensitive aliases to daxiaoxie
= 20
const vm = new Vue({
el: "#root",
data: {name: "vue"}, // configure the callback method.
// Configure the callback methods
methods: {
// Callback methods
info(e) {
() // Key CapsLock
() // Keycode 20
},
}
})
System modifier keys for the keyboard
System modifier keys (special usage): ctrl, alt, shift, meta
(1). Use with keyup: press the modifier key while pressing other keys, and then release the other keys before the event is triggered.
(2). Used with keydown: triggers events normally
Calculating Properties
- Definition: The attribute to be used does not exist, and has to be calculated from existing attributes, i.e., a new attribute is generated by calculating existing attributes.
- Principle: The underlying method provides getters and setters.
- Advantage: compared with the methods implementation, there is an internal caching mechanism (reuse), higher efficiency, easy debugging
- Calculated properties end up on the vm, just read and use them directly
- If the computed property is to be modified, then the set function must be written to respond to the modification, and the set must cause the data on which the computation depends to change.
Basic use
<body>
<div >
Last name:<input type="text" v-model="firstName">
<br>
First Name:<input type="text" v-model="lastName"> <br>
<br>
Full name: <span>{{allName}}</span>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
data: {firstName: "vue",lastName: "html"},
methods:{}, // configure the computed attributes
// Configure the computed property
computed:{
// Define an allName computed property
allName:{
// get is called when someone reads allName, and the return value is used as the return value of allName.
// When it is called: 1. when allName is first read 2. when the dependent data has changed
// The data is cached after the initial computation, so subsequent calls don't have to repeat the computation unless there is a change in the dependent data.
get(){
// this is vm
return + "-" +
}, // set when allName is changed.
// set is called when allName is changed.
set(v){
// String in abc-bcd format, cut by -
const arr = ("-")
// Assign the two values from the cut to each of the two attributes, then calculate the attribute linkage change
= arr[0]
= arr[1]
}
}
}
})
abbreviated form
If the compute attribute is only read, not modified, it can be abbreviated
<body>
<div >
Last name:<input type="text" v-model="firstName">
<br>
First Name:<input type="text" v-model="lastName"> <br>
<br>
Full name: <span>{{allName}}</span>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
data: {firstName: "vue", lastName: "html"}, methods: {}, const vm = new Vue({ el: "#root", })
methods: {}, // configure the computation properties
// Configure the computed property
computed: {
// Define the property as a function, which is what the getter does
allName() {
// Return the computed property directly
return + "-" +
}
}
})
</script>
Monitor Properties
- When the monitored property changes, the callback function is automatically called to perform the relevant operation.
- Attributes must be present for monitoring to take place
- Two ways to write a watch.
- Pass in the watch configuration when new Vue
- Monitoring via vm.$watch
Basic use
-
The first way of writing
const vm = new Vue({ el: "#root", data: {firstName: "vue", lastName: "html"}, methods: {}, {} // Configure the computed property computed: { allName() { return + "-" + } }, // Configure the watch property watch:{ // The name of the property to watch firstName:{ // Whether or not to have the handler called once during initialization, default value is false immediate: true, // If the handler is called once during initialization, the default value is false. // When the watched property changes, the handler is called. handler(newValue,oldValue){ (`firstName has been changed`,newValue,oldValue) } } } })
-
Second writing style
// Configuration monitoring properties // The name of the property to watch, the configuration object vm.$watch("firstName",{ immediate: true, handler(newValue,oldValue){ handler(newValue,oldValue){ (`firstName was modified`,newValue,oldValue) } })
deep monitoring
- By default, Vue's watch does not monitor changes to the internal values of an object, but only one layer.
- Configuring deep:true allows you to monitor internal value changes within an object, watch for multiple layers of
- Vue itself can monitor changes to values inside an object, but the Vue-supplied watch does not by default
- Depending on the specific structure of the data, you can decide whether or not to use in-depth monitoring when using watch.
- When the object being watched is a complex object (e.g., one that contains nested attributes), by default, watch will only watch for changes to the object's references. Instead, deep watch recursively monitors every property inside the object and triggers the listener's callback function once the internal property has changed
const vm = new Vue({
el: "#root",
data: {
info: {
a: 1, b: 2
b: 2
}
},
methods: {},
// Configure the computed property
computed: {}, // Configure the computed property.
// Watch properties
watch:{
// Watch the entire info, if you don't watch deeply, you'll only watch for changes to the value reference of the info's corresponding object address, not to any specific value within it.
info:{
// Enable deep watch - watch for changes to every property in the hierarchy.
deep:true, handler(){ // Enable deep monitoring - watch for changes to each attribute in the hierarchy.
handler(){
("info-",)
}
},
// Monitor for changes to a property in a hierarchical structure - only the a property in info is monitored.
// The key of the object is a string, so it needs to be written as a string
'':{
handler() {
("a",)
}
}
}
})
Monitor Attribute Abbreviation
If deep monitoring and initialization-time calls are not required, you can abbreviate the
// The watch attribute
watch:{
// watch info, as a function, which is equivalent to a handler
info(newV,oldV){
(newV,oldV)
}
}
// Properties to watch, callback functions, no arrow functions allowed
vm.$watch("info",function (newV,oldV) {
(newV,oldV)
})
Comparison of Computational and Surveillance Properties
Difference between computed and watch:
- What computed can do, watch can do.
- What watch can do, computed can't necessarily do, e.g., watch can do asynchronous operations.
- Two important little principles:
- Functions that are managed by Vue should be written as normal functions so that this points to the vm or component instance object.
- All functions that are not managed by Vue (timer callbacks, ajax callbacks, Promise callbacks, etc.) should preferably be written as arrows so that this points to the vm or component instance.
Binding Style
In the application interface, some elements are styled to be variable
The class/style binding is a technique used to implement dynamic styling effects.
Class Binding
Binding with :class
<style>
.box {
width: 100px;
height: 100px;
}
.box-color {
background-color: yellow; }
}
.box-border {
border: 1px solid black; }
}
</style>
<body>
<div >
<! -- Bind class style, ex is a string, for styles that are indeterminate and need to be specified dynamically -- >!
<! -- Eventually the class and :class counterparts will be spelled out into a class that ends up being class="box box-color" -->!
<div class="box" :class="ex"> box</div>
<! -- Bind class styles, exArr is an array for an indeterminate number of styles to be used with indeterminate names -->
<div class="box" :class="exArr">box</div>
<! -- Bind class styles, exObj is an object for the number of styles to be bound is determined, the name is also determined, but to be dynamically decided to use or not -- >!
<div :class="exObj"> box</div>
</div>
</body>.
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
exArr: ["box-color", "box-border"], {
exObj:{
box:true, // decide whether to activate the style based on true, false
// For key values with special characters, use either of the following two ways
"box-border":true
}
}
})
</script>
Style Binding
<body>
<div >
<! -- bind style style -- object write, single dynamic style -- > <!
<div :style="styleObj">box</div>!
<! -- Bind style styles -- array writeup, multiple dynamic styles -->
<div :style="styleArr">box</div>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
styleObj:{
width: "100px",
height: "100px",
},
styleArr: [
{
width: "100px",
height: "100px",
},
{
// The background-color attribute should be written as a small camel.
// You can also use the string key "background-color".
backgroundColor: "yellow"
}
]
}
})
</script>
conditional rendering
v-show
<div >
<! -- v-show controls showing and hiding elements -- >!
<! -- v-show doesn't remove, just the page doesn't show, equivalent to the operation display: none; -->!
<! -- For scenarios with high switching frequency -->!
<! -- Boolean, true to show, false to hide -- > <!
<h1 v-show="false"> title1</h1>
<! --Or you can write the expression value to be a boolean value-->
<h1 v-show="2>1">title2</h1>
<! -- set dynamically from vue data -->
<h1 v-show="showIf">title3</h1>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
showIf: true
}
})
</script>
v-if
<body>
<div >
<! -- v-if removes elements instead of page hiding, for: scenarios with less frequent switching -- >!
<! -- boolean, true to show, false to hide -- > <!
< h1 v-if="false"> title1</h1>
<! --Or you can write the expression value as a boolean-->
<h1 v-if="2>1">title2</h1>
<! -- set dynamically from vue data -->
<h1 v-if="showIf">title3</h1>
<! -- v-if can be used with v-else-if and v-else, but requires that the structure not be interrupted -->!
<! -- if 1 is equal to "1" show title4 -->
<h1 v-if="num===1"> title4</h1>
<! -- if 1 is greater than 2 show title5-->
< h1 v-else-if="num>2">title5</h1>
<! -- Otherwise display title6,,neither the 4 nor the 5 conditions hold -->
<h1 v-else>title6</h1>
<! -- Equivalent to
if(num===1){
}else if(num>2){
}else {
}
-->
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
showIf: true,
num:10
}
})
</script>
<! -- v-if only works with template's, not with v-show -->
<template v-if="num === 20">
<h2>1</h2>
<h2>2</h2>
<h2>3</h2> </h2>
</template>.
- template is used to define a template fragment, the content in this template fragment will not be rendered directly to the page by default, but will be stored as a "template", so that the content can be used by JavaScript for cloning or other operations when needed.
- For example, when building a dynamic list, you can define the template for the list items in the
<template>
tags, and then dynamically clone and populate this template based on the data
list rendering
basic rendering (computing)
<body>
<div >
<! -- Traversing the array -- >
<ul>
<! -- Equivalent to for (let u of users)--> <!
<! -- how many data will populate how many li -- > <!
<! -- can also be used with u in users --> <!
<! -- :key is used to specify a unique identifier for this li node -->!
< li v-for="u of users" :key="">
{{}} --- {{}}
</li>
</ul>
<ul>
<! --index is the subscript -->
<li v-for="(u,index) of users" :key="">
{{}}---{{}}---{{index}}
</li>
</ul>
<! -- Traversing objects -->
<ul>
<li v-for="(value,key) of info" :key="key">
{{key}} -- {{value}}
</li> </ul>
</ul>
<! -- Iterate over strings -->!
<ul>
<li v-for="(char,index) of strFor" :key="index">
{{char}} -- {{index}}
</li>
</ul>
<! -- Iterate through the specified number of times -->
<ul>
<! -- iterates through 5 times, number is the value from 1, index is the subscript -->
<li v-for="(number,index) of 5" :key="index">
{{number}} -- {{index}}
</li>
</ul>
</div>.
</body>.
<script type="text/javascript"> </ul> </div> </body>
const vm = new Vue({
el: "#root", data: {
data: {
users: [
{id: 1, name: "vue", "tag": "js"}, {id: 2, name: "python", "tag": "py"}, }
{id: 3, name: "golang", "tag": "go"}, {id: 3, name: "golang", "tag": "go"}
], {id.
info: {
name: "vue", {id: 3, name: "golang", "tag": "go"}, ], info: {
name: "vue", count: 10, price: 1000
price: 1000
}, strFor: "helloworld
strFor: "helloworld"
}
})
</script>
Principles and effects of the v-for key
The role of key in the virtual DOM:
key is the identity of the virtual DOM object, when the data changes, Vue will be based on the [new data] to generate the [new virtual DOM, and then Vue carries out a comparison of the differences between the [new virtual DOM] and the [old virtual DOM], the comparison rules are as follows:
-
The same key is found in the old virtual DOM as in the new virtual DOM:
-
If the content of the virtual DOM remains unchanged, the previous real DOM is used!
-
If the content in the virtual DOM changes, a new real DOM is generated, which then replaces the previous real DOM in the page.
-
-
The same key as the new virtual DOM was not found in the old virtual DOM
- Creates a new real DOM, which is then rendered to the page.
Problems that may arise from using index as a key:
-
If the data is subjected to: reverse-order addition, reverse-order deletion, and other out-of-order operations.
Generates unnecessary real DOM updates ==> Interface is fine, but inefficient. -
If the structure also contains a DOM for the input class:
Will generate error DOM update ==> Problems with the interface
How to choose a key in development.
- It is best to use the unique identifier of each piece of data as the key, e.g. id, cell phone number, and other unique values.
- If there are no out-of-order operations such as adding data in reverse order, deleting data in reverse order, etc., and the data is only used to render a list for display, it is fine to use index as the key.
- If you don't specify :key, vue uses subscripts as key by default.
List Filtering
Implemented using watch
<body>
<div >
<! -- Two-way binding filters keywords -- >
<input type="text" v-model="keyWord">
<ul>
<! -- Iterate through the array of fuzzy search filters -->
<li v-for="u of filUsers" :key="">
{{}} --- {{}}
</li>
</ul>
</div>
</body>.
<script type="text/javascript"> </ul> </div> </body>
const vm = new Vue({
el: "#root", data: {
data: {
// Filtered keywords
keyWord: "",
users: [
{id: 1, name: "vue", "tag": "html", "price": 30}, {id: 2, name: "python", "tag": "server", "price": 30}
{id: 3, name: "golang", "tag": "server", "price": 50}, {id: 2, name: "python", "tag": "server", "price": 40}
]
// Define a new array for storing the filtered data
filUsers: []
}, // Define a new array to store the filtered data.
// Configure the watch property
watch: {
keyWord:{
// Called on initialization to filter out empty strings and show all data at first glance.
immediate: true, handler(newValue) {
handler(newValue) {
// Filter all data containing newValue from the users' tag and reassign to
= ((p) => {
// Return the data whose tag contains newValue.
// indexOf does not contain return -1 empty string return 0
return (newValue) ! == -1
})
}
}
}
})
</script>
Implemented with computed
const vm = new Vue({
el: "#root",
data: {
// Filtered keywords
keyWord: "",
users: [
{id: 1, name: "vue", "tag": "html", "price": 30}, {id: 2, name: "python", "tag": "server", "price": 30}
{id: 3, name: "golang", "tag": "server", "price": 50}, {id: 2, name: "python", "tag": "server", "price": 40}
]
}, // Configure the calculation properties.
// Configure the computed property
computed:{
// The computed attribute relies on the keyword and triggers the computation of a new array when the keyword is changed.
filUsers(){
return ((p)=>{
return () ! == -1
})
}
}
})
List Sorting
<body>
<div >
<! -- Two-way binding filters keywords -- >
<input type="text" v-model="keyWord">
<! -- button @click Modify sortType value -->
<button @click="sortType = 2"> price ascending</button>
<button @click="sortType = 1">price descending</button>
<button @click="sortType = 0">original order</button>
<ul>
<! -- Iterate through the array of fuzzy search filters -->
<li v-for="u of filUsers" :key="">
{{}} --- {{}} --- {{}}
</li>
</ul>
</div>.
</body>.
<script type="text/javascript"> </ul> </div> </body>
const vm = new Vue({
el: "#root", data: {
data: {
// Filtered keywords
keyWord: "", // Define a keyword, 0 for original order 1 for descending 2 for ascending
// Define a keyword, 0 for original order 1 for descending order 2 for ascending order
sortType: 0, // Define a keyword.
users: [
{id: 1, name: "vue", "tag": "html", "price": 30}, {id: 2, name: "python", "price": 30}
{id: 3, name: "golang", "tag": "server", "price": 50}, {id: 2, name: "python", "tag": "server", "price": 40}
]
}, // Configure the calculation properties.
// Configure the computed property
computed: {
// The computed attribute relies on the keyword and triggers the computation of a new array when the keyword changes.
filUsers() {
// Define an array to receive the filtered data
const arr = ((p) => {
return () ! == -1
})
// Filter first, then sort
// Determine if sorting is needed
if () {
((a, b) => {
// if type === 1 descending otherwise ascending
return === 1 ? - return === 1 ?
})
}
// Return the sorted array
return arr
}
}
})
</script>
Vue Monitoring Data Principles
Vue Monitoring Objects
-
Principles of Vue Monitoring Objects
When a Vue instance is created, Vue traverses the
data
option for all attributes. For each attribute, it uses themethod to perform data hijacking. This method allows Vue to redefine the attribute's
get
cap (a poem)set
interviewervm's data agent, data data to the
_data
Before the data is processed and then assigned to _data, a better implementation of responsive, each property in the object has a corresponding getter and setter// Simulate the implementation of a vm for data monitoring function Observer(obj){ // Get all the attributes of the object and generate an array const keys = (obj) // Iterate over all properties ((k)=>{ // Add the corresponding property to the current instance (this,k,{ get(){ // Return the corresponding value return obj[k] }, set(v){ // The data has been changed, parse the template, generate a virtual DOM match, and update the page. obj[k] = v } }) }) } let data = { name: "vue", tag: "js" } // Create an instance of the observer object to watch for changes to the attributes in data const obs = new Observer(data) // Prepare an instance of vm let vm = {} vm._data = data = obs // You can access and modify properties via vm._data.
-
Sample Problem:Clicking a button triggers a callback to update data, the first method can be updated successfully, the second method is unsuccessful (the data is changed but not responsive)
<button @click="updateInfo1" type="button"> button</button>
<button @click="updateInfo2" type="button"> button</button>
<ul>
<! -- Iterate through the array of fuzzy search filters -->
<li v-for="u of users" :key="">
{{}} --- {{}} --- {{}}
</li>
</ul>.
</div>.
</body>.
<script type="text/javascript"> </ul> </div> </body>
const vm = new Vue({
el: "#root", data: {
data: {
users: [
{id: 1, name: "vue", "tag": "html", "price": 30}, {id: 2, name: "python", "tag": "server", "price": 40}
{id: 3, name: "golang", "tag": "server", "price": 50}, {id: 2, name: "python", "tag": "server", "price": 40}
]
}, // Callbacks.
// Callbacks
methods:{
updateInfo1(){
// Can be updated successfully
[0].name = "js"
[0].price = 40
},
updateInfo2(){
// The data is updated successfully, but the page is not responsively updated, see the monitoring array principle for the reason
[0] = {id: 1, name: "css", "tag": "html", "price": 40}
}
}
})
</script>
(method
If we want to give the vm or
_data
Adding a new attribute via = xxx or vm._data.xxx = xx is not responsiveThe responsiveness of Vue's data is accomplished through the
to realize that each attribute has a corresponding getter and setter, and that adding attributes directly is not implemented with data
Vue gives us the set and $set methods to add properties to vm or _data, and to process the data.
-
is the global API, which is called as (target, key, value)
- where target is the target object (responsive object) to which the attribute is to be added, key is the name of the attribute to be added, and value is the value of the attribute
- This type of call does not depend on a specific Vue component instance, and is suitable for use in scenarios such as outside of a component or in some utility functions.
-
this.$set is an instance method of a Vue instance (component), and it can only be used inside a Vue component
- Called via this.$set. this points to the current instance of the Vue component and is called as this.$set(target, key, value)
- The parameter meaning is the same as the same. This approach is more in line with the habit of manipulating data inside the component, as it is closely related to the component instance and allows easy access to this context of the component, such as the component's data, computed attributes, etc.
-
() and vm.$set() cannot add properties to vm or vm's root data object.
const vm = new Vue({
el: "#root",
data: {
user:{
name:"vue",
info:{
price:100
}
}
},
methods:{
// event callback do sth (for sb)infoDays to add atagmath
addInfo(){
(,"tag1","html")
this.$set(,"tag2","html")
}
}
})
Vue Monitoring Arrays
Data in arrays on vm without getter and setter
vm monitors array data changes to achieve responsiveness, which is achieved by calling the Vue array (non-native method) method
- Vue implements array addition, deletion, and modification methods (push, pop, etc.) on the data prototype
- Internally, the add, delete, and check methods of the native array are called first to implement data changes
- Then parse the template to achieve responsive
Modifying the data through the array index only modifies the data and does not re-parsing the template, so the page will not follow the update
// Use this.$set to update array elements for responsive updating
this.$set(, 0, 10);
// Use the splice method to update the array elements for responsive updating
this.$set(, 0, 10); // Use the splice method to update the array elements for responsive updating.
vue collects form data and modifiers
<body>
<div >
<form>
<! -- There are input box related, v-Model collects the value value, and what the user enters is the value value -- >
<! --
The .trim modifier
Removes the first and last spaces of collected data
-->
Account: <input type="text" ="account"> <br/> <br/>
Password: <input type="password" v-model="password"> <br/><br/>
<! -- The .number modifier converts user input collected by vue to a number type by default.
type="number" means only number can be entered.
If you enter the string "123" for any other type, the modifier will be collected and converted to number123.
If you type 123abc, the modifier will be 123.
-->
Age: <input type="number" = "age"> <br/> <br/> <br/>
<! -- radio type has no input box v-model collects value values, need to configure value values for tags -->
Gender:
Male< input type="radio" name="sex" value="male" v-model="sex" >
Female<input type="radio" name="sex" value="female" v-model="sex"> <br/> <br/>
<! --
checkbox type
If the value attribute is not configured, the v-model collects the label's checked attribute, true or false.
If the value attribute is configured
1. the initial value of the v-model is non-array, then the collection is checked (checked or unchecked, boolean)
2. the initial value of the v-model is an array, then the collection is an array of values.
The initial value is the initial value given by the vue two-way binding.
-->
Hobby:
Studying<input type="checkbox" v-model="hobby" value="study">
Playing games<input type="checkbox" v-model="hobby" value="game">
Eating<input type="checkbox" v-model="hobby" value="eat">
<br/> <br/>
School District
<select v-model="city"> <select v-model="city" >
<option value=""> Please select a school district</option>
<option value="beijing">Beijing</option> <option value="beijing" > <option value="beijing" >Beijing</option>
<option value="Shanghai">Shanghai</option> <option value="Shanghai">/option>
<option value="shenzhen">Shenzhen</option> <option value="shenzhen">/option
<option value="wuhan">Wuhan</option> <option value="wuhan">Wuhan</option> </select
</select>
<br/> <br/>
Additional Information:
<! --
The .lazy modifier
By default data is collected in real time, directly with each character entered
With the .lazy modifier, it will be collected uniformly when the focus is lost, rather than in real-time
-->
<textarea ="other"></textarea> <br/> <br/>
<input type="checkbox" v-model="agree">Read and accept <a href="">The User Agreement</a>
<button>Submit</button>
</form>
</div>.
</body>.
<script type="text/javascript"> </form> </div> </body>
const vm = new Vue({
el: "#root", data: {
data: {
account: "", password: "", {
password: "",
age: 20, // default 20
sex: "male", // check value is male by default
// check:v-model initial value is set to an array to collect the selected data
hobby: [], // check
city: "beijing", // selects Beijing by default
other: "", agree: "" // check
agree: "" // check:don't need to collect specific number, set it to string, collect checked state
}
})
</script>
(machine) filter
The filter does not change the original data, it generates new corresponding data.
Local filters
<body>
<div >
<! -- Attributes to display | Filters to use -->!
<! -- Filter principle: read time, pass time as parameter to filter, filter return value replaces {{}} interpolation syntax --> <!
<h2> {{time | timeFormat }}</h2>
<! -- The filter can pass parameters, the first parameter is value by default and then the second parameter needs to be accepted using a formal parameter -- >
<h2> {{time | timeFormat(true) }}</h2>
<! -- Multiple filters can be used together Multiple filters use | split , interpolate | filter | filter ... -->
<! -- Principle:First hand time to timeFormat for processing, then hand the result of timeFormat processing to testFilter, and finally use the value of testFilter for replacement -->!
<h2>{{time | timeFormat | testFilter}}</h2>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
time: () // timestamp of the current time
}, // Configure a local filter that only the current vue instance can use.
// Configure localized filters so that only the current vue instance can use them and no other instance can use them
filters: {
// Filters are functions
timeFormat(value, status) {
if (status) {
(value)
}
// Format the timestamp and return it
return dayjs(value).format("YYYY year MM month DD day HH:mm:ss")
},
testFilter(value) {
return value[0]
}
}
})
</script>
Global Filter
// Global filters must be configured before the Vue instance is created.
("myFilter", function (value) {
return (0, 4)
})
// If you want more than one global filter, you need to declare more than one
("myFilter2", function (value) {
return (0, 4)
})
const vm = new Vue({
el: "#root",
data: {
time: () // timestamp of the current time
}, // Configure a local filter that only the current vue instance can use.
// Configure localized filters so that only the current vue instance can use them and no other instance can use them
filters: {
// Filters are functions
timeFormat(value, status) {
if (status) {
(value)
}
// Format the timestamp and return it
return dayjs(value).format("YYYY year MM month DD day HH:mm:ss")
},
testFilter(value) {
return value[0]
}
}
})
<! --Filters can also be used when unidirectional data binding -->
<input :value="time | timeFormat">
built-in instruction
v-bind : one-way binding resolution expression, can be abbreviated as :xxx
v-model : two-way data binding
v-for : traversing arrays/objects/strings
v-on : binds an event listener, which can be abbreviated as @.
v-if : conditional rendering (dynamically control whether a node exists or not)
v-else : conditional rendering (dynamically controlling whether a node exists or not)
v-show : conditional rendering (dynamically control whether a node is shown or not)
v-text
Role: Renders the text content into the node where it is located.
Difference from interpolation syntax: v-text replaces the contents of a node, interpolation syntax does not.
<body>
<div >
<! -- 123vue-->
<h1>123{{name}}</h1>
<! -- vue -->
<! -- v-text will get the value in data and replace the entire contents of the tag -->!
<! -- v-text renders the data as a string, it doesn't parse the label, and if the value is the label content it is also displayed as a string -->!
<h1 v-text="name">123</h1>
</div>.
</body>.
<script type="text/javascript">;
const vm = new Vue({
el: "#root", data: {
data: {
name: "vue"
}
})
</script>
v-html
Renders the content containing the html structure into the specified node
v-html has security issues.
- Dynamically rendering arbitrary HTML on a website is very dangerous and can easily lead to XSS attacks
- Always use v-html on trusted content, never on user-submitted content
<div >
<! --<h1>666</h1>-->.
<div>{{name}}</div>
<! -- <h1>666</h1>-->
<div v-text="name"></div>
<! --h1 effect of 666 , v-html can parse the label , if there is other content in the label , it will also replace the whole , and v-text the same -->!
<div v-html="name"></div>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
name: "<h1>666</h1>"
}
})
</script>.
v-clock
Essentially it's a special property that deletes the v-cloak property after the Vue instance is created and takes over the container.
Use css with v-cloak to solve the problem of pages showing {{xxx}} when the internet is slow.
<style>
/* When the vue is not created successfully, the interpolation syntax does not have a value yet, and the tags have v-cloak attributes, so selecting these tags will hide the element */
/* When the vue is created, the v-cloak of the tags is removed and the elements are not hidden */
[v-cloak] {
display: none; }</style
}</style>
<body>.
<div >
<! -- in-tag v-cloak when the vue instance is not created successfully, when the instance is created successfully, it removes all All in-tag v-cloaks -->
<h1 v-cloak>{{name}}</h1>
<h1 v-cloak>{{name}}</h1>
</div>
</body>.
<script type="text/javascript"> </body>
const vm = new Vue({
el: "#root", data: {
data: {
name: "vue"
}
})
</script>
v-once
The node where the v-once is located is considered static content after the initial dynamic rendering.
Future changes to the data will not cause an update to the structure where the v-once is located, which can be used to optimize performance
<! -- With v-once, the num value will only be read once and will not be updated subsequently -- >
<h2 v-once>{{num}}</h2>
<! -- Every time the button is clicked num is increased by 1 -->
<h2> The current value of n is:{{num}}</h2>
<button @click="num++"> Tap me for n+1</button>
v-pre
- Skips the compilation process of the node it is on
- It can be used to skip: nodes that do not use directive syntax, do not use interpolation syntax, will speed up compilation
<! -- page display {{name}}} won't parse anymore Interpolation syntax, directives, not used -->
<div v-pre>{{name}}</div>
<! -- For those that don't need vue rendering you can use this directive -->
<div v-pre>content</div>
customizable command
This is Window for methods and functions in the directive object style.
functional
<div >
<div style="height: 100px" v-test="num" ></div>
</div>
</body>.
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
num: 10
}, // Configure custom directives.
// Configure custom directives
directives:{
// Write as a function - customize a test directive that doesn't require a v- for the function name, but does require a v- for use.
// element: the DOM element to which the directive is bound, e.g. <div style=""></div>, a real DOM, not a virtual one.
// binding: an object that contains information about the directive
// def: contains functions that are executed at different stages of the directive's lifecycle, mainly bind and update.
// update: The update function is called when the data bound to the directive changes. It is used to update the operations associated with the directive based on the new data. For example, if the directive is binding data to the textual content of an element, the update function will update the textual content to reflect the change in data
// expression: the expression used in the directive, xxx in v-directive="xxx".
// modifiers: an object that stores the modifiers of the directive. When a directive has modifiers in a template, this object will record the relevant information
// name: the name of the custom instruction, in this case test.
// rawName: the raw name of the custom instruction, including v-, in this case v-test.
// value: the value bound to the directive's expression, usually computed by the expression or obtained directly from the bound data, which is used in the directive's logic for various purposes, such as updating an element's attributes or as the basis for a conditional judgment.
// Specify when to trigger 1. When the directive is successfully bound to the element (the element may not have already been placed on the page).
// If an action such as using element to get focus fails if the element is not already on the page, it will fail
// Functionality has the problem that the directive binds to the element successfully, but vue hasn't rendered the template yet.
// 2. When the directive's template is re-parsed
test(element,binding){
(binding)
// The element's corresponding dom element, writes data to the element, gets the value from it, and then processes it
= *10
}
}
})
</script>
object-oriented
<body>
<div >
<div style="height: 100px" v-test="num"></div>
<! -- For directive names that are multiple words, use the v-xxx-xxx naming convention, not the little hump naming -- >!
< input type="text" v-test-obj:value="num">
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el: "#root", data: {
data: {
num: 10
}, // Configure custom directives.
// Configure custom directives
directives: {
test(element, binding) {
// The element's corresponding dom element to which to write data, get the value from, and then process it.
= * 10
}, // Object-based - can solve for function style.
// Object-based - this solves the problem of timing the binding element & page element not being put in by the function-based
// The bind and update methods are mostly the same, the functional equivalent implements the bind and update methods without the inserted method
testObj: {
// Timing of the call - when the directive is successfully bound to the element
bind(element, binding) {
= * 10
}, // Call timing - when the directive is bound to the element.
// Called when the element the directive is on is inserted into the page.
inserted(element, binding) {
// Get the focus of the input, triggered when the element is inserted into the page, so some of the dom's operations will succeed.
()
}
// Called when the template where the directive is located is parsed again.
update(element, binding) {
= * 10
}
}, }
// The official recommendation is to just use the multiple-word-conjugation approach
"test-object":{
bind(element, binding) {
},
inserted(element, binding) {
},
update(element, binding) {
}
}
}
})
</script>
Custom commands - global commands
Directives that are configured on a vue instance are localized and can only be used on the current vue instance
// Before the vue instance
// Directive name, configuration object
("test",{})
// Directive name, callback function
("test1",function () {})
life cycle
Vue's lifecycle is the series of stages that a Vue component goes through from creation to destruction. At each stage, the component triggers the appropriate lifecycle hooks, and developers can write code in these hooks to implement specific functionality, such as initializing data, sending network requests, manipulating DOM elements, cleaning up resources, and so on.
- AKA: lifecycle callback functions, lifecycle functions, lifecycle hooks.
- Some specially named functions that Vue helps us call at critical times
- The names of the lifecycle functions cannot be changed, but the specifics of the functions are written on demand
- This in a lifecycle function points to either a vm or a component instance object.
const vm = new Vue({
el: "#root",
data: {
opacity: 1 // set transparency
}, // mounted is a lifecycle hook function.
// mounted is a lifecycle hook function.
// When Vue finishes parsing the template and puts the initial real DOM into the page (mounted) call mounted
mounted() {
setInterval(()=>{
-= 0.01
if( <= 0)
= 1
},16)
}
}
)
Mounting process
// new vue instance
const vm = new Vue({
el: "#root",
data: {},
/** mount process **/
// 1. Call this method after initializing the lifecycle and events, this data proxy hasn't started yet, you can't access data, methods through vm
beforeCreate() {
("beforeCreate")
},
// 2. Call this method after the initialization of the data inspection and data proxy is complete, then you can access the methods in data and methods through the vm.
created() {
("created")
}, }
// Start parsing the template and generating the virtual DOM (in memory), at this point the page can't display the parsed content yet
// Determine if there is an el option when the new vue instance is created, if not, wait for vm.$mount to be called and then execute it later.
// Determine if the new vue instance has the template option, and if so, compile the template into the render function.
// 4. Calling this method after the above steps renders the page with a DOM structure that has not been compiled by Vue, and all operations on the DOM will not work at this point.
beforeMount() {
("beforeMount")
},
// 5. Insert the page from the in-memory virtual DOM to the real DOM
// 6. When Vue finishes parsing the template and puts the initial real DOM into the page (after it's mounted), call mounted
// All operations on the DOM are valid at this point, but try not to manipulate the DOM at this point.
// This is the time to start timers, send requests, target messages, bind custom events, and other initialization operations.
mounted() {
("mounted")
}, }
/** Update process **/
// 1. Call this method when there is a change in the data (before the update).
// At this point, the data is new, but the page is still old, and the page is not yet synchronized with the data.
beforeUpdate() {
("beforeUpdate")
},
// 2. Generate a new virtual DOM based on the new data, compare it to the old virtual DOM, and then complete the page update, Model->View update
// 3. After the update is complete, call this method, when the data is new and the page is also new
updated() {
("updated")
}, }
/** Destroy process **/
// Trigger the destruction process after calling vm.$destroy()
//
//
// 1. A hook function called just before the component is about to be destroyed. At this stage the component is still intact and the actual destruction process has not yet begun.
// At this point, the methods, properties, etc. in the vm are in a usable state, but modifications will no longer take effect, so it's generally a good time to turn off timers, unbind custom events from messages, and so on.
beforeDestroy() {
("beforeDestroy")
},
// 2. Completely destroy an instance, clean up its connections to other instances, and unbundle all of its directives and listeners.
// vue no longer manages the page, but the previously generated data is still there.
// 3. After the component has been completely destroyed, call the
destroyed() {
("destroyed")
}
}
)