The official order
- The primary responsibility of a directive is to apply some behavior to the DOM when the value of its expression changes
v-model
- Data binding for forms (input)
- V-model implementation: value setting and input event monitoring
- Most forms-class components should have a V-Model, such as input fields, checkboxes, checkboxes, and drop-down selectors
V-html: outputs only HTML
- Note: If user-generated content is output using V-HTML, it may lead to XSS attacks.
- Therefore, to process user-submitted content on the server side, Angle brackets “<>” can be escaped
v-pre
- To display the {{}} tag without substitution, use the V-pre to skip compilation of this element and its children
v-bind
- Dynamically update attributes on HTML elements; Grammar sugar: 🙂
- V-bind binds to class and style
v-on
- Bind event listeners; Grammar sugar :(@)
v-cloak
- {{message}} will appear on the page when the Vue. Js file is not finished loading. DOM will not be replaced until the Vue instance is created and the template is compiled
- In the project, the HTML structure is just an empty div element, and the rest is done by routing to mount different components, so v-cloak is no longer needed
v-once
- A defined element or component is rendered only once, including all child nodes of the element or component. The first selection is then, no longer re-rendered as the data changes, treated as static content.
- Rarely used unless further performance optimization is required
v-if
- Reuse existing elements as much as possible rather than re-render them, which can be avoided by using keys
v-show
- Change the element’s CSS property display, which cannot be in
<template>
Use on labels
Difference between V-if and V-show:
- V-if is suitable for scenarios where conditions do not change often, because switching costs are relatively high
- V-show is suitable for frequent switching conditions
v-for
Vue maximizes the reuse of DOM elements. Items with the same elements in the replaced array are not rerendered, so you can boldly replace the old array with a new one without worrying about performance.
-
Problem: Array does not recognize app.books[3]= {… } operation
-
Fix: use vue. set or this.$set or app.books.splice
-
Problem: Array does not recognize app.books.length=1 operation
-
Solution: app. Books. Splice (1)
Custom instruction
website
Global definitions
Vue.directive('focus', {
// Command options
})
Copy the code
Local registration
let app = new Vue({
el: '#app'.directives: {
focus: {
// Command options}}})Copy the code
v-focus
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Vue sample</title>
</head>
<body>
<div id="app">
<input type="text" v-focus>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.directive('focus', {
inserted: function(el) { el.focus(); }})let app = new Vue({
el: '#app',})</script>
</body>
</html>
Copy the code
Use instruction parameters
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Vue sample</title>
</head>
<body>
<div id="app">
<div v-test:msg.a.b="message"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.directive('test', {
bind: function(el, binding, vnode){
let keys = [];
for(let i in vnode){
keys.push(i);
}
el.innerHTML =
'name: ' + binding.name + '<br>' +
'value: ' + binding.value + '<br>' +
'expression: ' + binding.expression + '<br>' +
'argument: ' + binding.arg + '<br>' +
'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' +
'vnode keys: ' + keys.join(', ')}})let app = new Vue({
el: '#app'.data() {
return {
message: 'message'}}})</script>
</body>
</html>
Copy the code
Pull-down menu that can be closed from outside (actual combat)
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Pull-down menu that can be closed from the outside</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="app" v-cloak>
<div class="main" v-clickoutside="handleClose">
<button @click="show = ! show">Click to display the drop-down menu</button>
<div class="dropdown" v-show="show">
<p>Drop down the contents of the box and click on the outer area to close it</p>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.directive('clickoutside', {
bind: function (el, binding, vnode) {
function documentHandler(e) {
if (el.contains(e.target)) { // The area clicked is inside the element where the instruction is located
return false
}
if (binding.expression) { // Whether there is an expression
binding.value(e)
}
}
el.__vueClickOutside__ = documentHandler
document.addEventListener('click', documentHandler)
},
unbind: function (el, binding) {
document.removeEventListener('click', el.__vueClickOutside__)
delete el.__vueClickOutside__
}
})
// Exercise 1: Support expression updates in update hooks
// Exercise 2: Extend clickoutside.js to display the dropdown menu by pressing ESC on the keyboard after clicking the button
// You can also close the drop-down menu
// Exercise 3: Make exercise 2's ESC button off optional. Prompt, use modifiers such as V-clickoutside. esc
let app = new Vue({
el: '#app'.data: {
show: false
},
methods: {
handleClose() {
this.show = false}}})</script>
</body>
</html>
Copy the code
[v-cloak] {
display: none;
}
.main {
width: 125px;
}
button {
display: block;
width: 100%;
color: #fff;
background-color: #39f;
border: 0;
padding: 6px;
text-align: center;
font-size: 12px;
border-radius: 4px;
cursor: pointer;
outline: none;
position: relative;
}
button:active {
top: 1px;
left: 1px;
}
.dropdown {
width: 100%;
height: 150px;
margin: 5px 0;
font-size: 12px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 1px 6px rgba(0.0.0.2);
}
.dropdown p {
display: inline-block;
padding: 6px;
}
Copy the code
Real-time time conversion command (actual combat)
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Time switch instruction</title>
</head>
<body>
<div id="app" v-cloak>
<div v-time="timeNow"></div>
<div v-time="timeBefore"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="time.js"></script>
<script>
Exercise 1: Develop a custom directive v-birthday that takes a timestamp of the date of birth and converts it to XXX days old
// Exercise 2: Extend exercise 1's custom v-birthday instruction to convert XXX days of birth to a specific age, such as 25
// 8 months and 10 days
let app = new Vue({
el: '#app'.data: {
timeNow: (new Date()).getTime(),
timeBefore: 1488930695721 / / 2017-03-08
},
methods: {
handleClose() {
this.show = false}}})</script>
</body>
</html>
Copy the code
let Time = {
// Get the current timestamp
getUnix() {
let date = new Date(a);return date.getTime();
},
// Get the timestamp of today's 0:0:0
getTodayUnix() {
let date = new Date()
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
return date.getTime();
},
// Get the timestamp of 00:00 00:00 on January 1 of this year
getYearUnix() {
let date = new Date()
date.setMonth(0)
date.setDate(1)
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
return date.getTime();
},
// Get the standard year month day
getLastDate(time) {
let date = new Date(time)
let month = date.getMonth() + 1 < 10
? '0' + (date.getMonth() + 1)
: date.getMonth() + 1
let day = date.getDate() < 10
? '0' + date.getDate()
: date.getDate()
return date.getFullYear() + The '-' + month + "-" + day;
},
// Convert the time
getFormatTime(timestamp) {
let now = this.getUnix(); // The current timestamp
let today = this.getTodayUnix(); // Today 0 o 'clock timestamp
let year = this.getYearUnix(); // This year 0 o 'clock timestamp
let timer = (now - timestamp) / 1000 // Convert to a second timestamp
let tip = ' '
if (timer <= 0) {
tip = 'just'
} else if (Math.floor(timer / 60) < =0) {
tip = 'just'
} else if (timer < 3600) {
tip = Math.floor(timer / 60) + 'Minutes ago'
} else if (timer >= 3600 && (timestamp - today >= 0)) {
tip = Math.floor(timer / 3600) + 'Hours ago'
} else if (timer / 86400< =31) {
tip = Math.ceil(timer / 86400) + 'days ago'
} else {
tip = this.getLastDate(timestamp)
}
return tip;
}
}
Vue.directive('time', {
bind: function (el, binding) {
el.innerHTML = Time.getFormatTime(binding.value)
el.__timeout__ = setInterval(() = > {
el.innerHTML = Time.getFormatTime(binding.value)
}, 60000);
},
unbind: function (el) {
clearInterval(el.__timeout__)
delete el.__timeout__
}
})
Copy the code