1. What is Vue?#
For practice, use the latest version
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
For production, use a specific version number to avoid unforeseen issues
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
hello world
<div id="app">
{{message}}
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'hello,world'
}
})
</script>
1. v-Directive#
- v-bind - Bind attributes
<div id="app-2">
<span v-bind:title="message">
Hover for a few seconds to see the dynamically bound tooltip here!
</span>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Page loaded at ' + new Date().toLocaleString()
}
})
</script>
v-bind
is a property provided by Vue that applies a reactive operation on the DOM.
Open the console and type app.message = "hello"
, the page will change the content to display only hello
.
Or type app.message = false
, and the content will not display.
Example from the Vue official website:
<!-- Bind an attribute -->
<img v-bind:src="imageSrc">
<!-- Dynamic attribute name (2.6.0+) -->
<button v-bind:[key]="value"></button>
<!-- Shorthand -->
<img :src="imageSrc">
<!-- Dynamic attribute name shorthand (2.6.0+) -->
<button :[key]="value"></button>
<!-- Inline string concatenation -->
<img :src="'/path/to/images/' + fileName">
<!-- Class binding -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- Style binding -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- Bind an object with all attributes -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- Bind DOM attributes through prop modifiers -->
<div v-bind:text-content.prop="text"></div>
<!-- Prop binding. "prop" must be declared in my-component. -->
<my-component :prop="someThing"></my-component>
<!-- Pass parent component's props to child component via $props -->
<child-component v-bind="$props"></child-component>
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>
- v-if - Control the visibility of elements
As mentioned earlier, by using app.message = false
, you can hide the content represented by message
, but this only controls the content introduced by v-for
, and cannot directly hide elements.
In fact, Vue has a specific directive for controlling the visibility of elements - v-if
.
<div id="app">
<span v-if="show">
{{message}}
</span>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'hello,world',
show: true
}
})
</script>
Bind a directive v-if = "show"
to the element, and then control the boolean value of show
in data, true shows, false hides.
There is also a directive with this functionality called v-show
, which toggles the element's display
CSS property based on the truthiness of the expression, also controlled by a bound boolean value.
However, v-if
and v-show
have some differences:
(1) v-if controls whether the element is rendered, ultimately controlling the visibility of the element, suitable for low-frequency toggling scenarios.
(2) v-show renders regardless of visibility and uses a boolean binding to set display: none
, suitable for high-frequency toggling scenarios.
Note:
v-show
does not support<template>
elements and does not supportv-else
.
Combined usage
v-else
and v-else-if
You can achieve the effect of v-if
using v-else
, which must be used in conjunction with v-if
, for example:
<div v-if="1>2">
hello
</div>
<div v-else>
hi
</div>
If v-if
is not satisfied, v-else
will execute, displaying the content inside v-else
.
Doesn't it feel a bit like the if
function in JavaScript?
The usage of v-else-if
is similar, and it must be used in conjunction with v-if
and v-else
.
- v-for - Iterate over an array and display it on the page
v-for
is one of the core directives of Vue, mainly used to render a list of items.
<div id="app">
<div v-for="item in list">{{item.message}}</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
list: [
{message: 'html'},
{message: 'css'}
]
}
})
</script>
You can directly loop through the list data and output it.
And you can add new list items in the console using push()
.
app.list.push({message: "js"})
Vue's data manipulation is truly magical.
It is not recommended to use v-for
and v-if
together, as v-for
has a higher priority.
- v-on - Bind event listeners
This binds events. By using v-on
, a click event is bound to the div. Note that in the reverseMessage
method, we update the application's state, but we directly handle the DOM through Vue, allowing us to focus only on the logic layer when writing code.
v-on:click="messagenone"
, and then write the event method in methods
.
<div id="app">
<div v-on:click="messagenone" id="demo">{{message}}</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'hello,wolrd'
},
methods: {
messagenone: function() {
var demo = document.getElementById('demo');
demo.innerHTML = ''
}
}
})
</script>
- v-model - Two-way data binding
Vue also provides the v-model
directive, which easily achieves two-way binding between form inputs and application state.
Applicable scenarios: input, select, textarea, and components
<div id="app">
<div>{{message}}</div>
<input type="text" v-model="message">
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'hello,wolrd'
}
})
</script>
- v-text - Update the content of an element
<div id="app">
<div v-text="message"></div>
<div>{{message}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
}
})
</script>
The content of the above div and the below div changes consistently.
- v-html - Update the innerHTML of an element
It is not recommended to use this, as dynamically rendering HTML on a website is very dangerous and can lead to XXS attacks
. It should not be used on user-submitted content. If v-html
must be used, consider using components instead.
- v-pre
Skip the compilation of the bound element and its child elements, directly displaying the raw content.
Skip nodes without directives and do not compile them, directly displaying the content, which speeds up the page's response.
- v-cloak
The state of the template before compilation is complete.
<style>[v-cloak] {
display: none;
}</style>
<div v-cloak>
{{message}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
}
})
</script>
The above code means that if the network is poor and the {{message}}
template representing hello,world
has not been compiled successfully, {{message}}
is hidden. Once compilation is complete, the page directly displays hello,world
.
- v-once - One-time rendering
Elements bound with this directive and their child elements will only be rendered once. Subsequent renderings will treat them as static resources and skip them, which can be used to optimize performance.
<div id="app">
<span v-once>{{message}}</span>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd',
}
})
</script>
Applicable scenario: form submission. It can prevent users from submitting multiple times when the request has not responded in time.
2. Component-based Application Building#
Componentization is also one of the core mechanisms of Vue, allowing us to build large applications using small, reusable components.
In Vue, a component is essentially a Vue instance with predefined options. Registering a component in Vue is simple.
// Define a new component named todo-item
Vue.component('todo-item', {
template: '<li>This is a todo item</li>'
})
var app = new Vue(...)
Now we can use it to build another component template.
<ol>
<!-- Create an instance of the todo-item component -->
<todo-item></todo-item>
</ol>
However, this will render the same text for each todo item, which doesn't look cool. We should be able to pass data from the parent scope to the child component. Let's modify the component definition to accept a props
.
Vue.component('todo-item', {
// The todo-item component now accepts a
// "props", similar to a custom attribute.
// This prop is named todo.
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
Now, we can use the v-bind
directive to pass the todo item to each component in the loop.
Now we provide the todo object for each todo-item, which is a variable, meaning its content can be dynamic, and we also need to provide a key
for each component.
<div id="app-7">
<ol>
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Any other food that people eat' }
]
}
})
Although this is just a deliberately designed example, we have managed to split the application into two smaller units. The child unit is well decoupled from the parent unit through the prop
interface. We can further improve the <todo-item>
component, providing more complex templates and logic without affecting the parent unit.
In a large application, it is necessary to divide the entire application into components to make development more manageable.
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>