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