Vue is a progressive JavaScript framework that, unlike other large frameworks, is designed to be applied layer by layer from the bottom up. So you can embed it in an existing project and optimize some of the code; You can also develop and manage large projects based on three Vue suites.

series

  • Vue 2 basis
  • Vue 2 components
  • Vue 2 dynamic effect
  • Vue 2 plug-in
  • Vue Router
  • Vuex

reference

  • “Re Vue Starts All over again” series of tutorials from Alex’s Youtube channel
  • Vue 2 Official document

🔗 has a Built-in Youtube player to play the clip directly, while for this article, click the 🎬 icon to open the url of the corresponding Youtube video clip.

instantiation

The easiest way to introduce a Vue is to use a CDN

<! -- Development environment version, including helpful command line warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
Copy the code

Instantiate a Vue application using new Vue({}). The received parameter is an option object that sets options about the Vue instance, such as the EL attribute, which specifies the DOM node to mount, and the data attribute, which contains responsive data.

💡 From a componentization perspective, a Vue instance is also a root component

<body>
  <div id="app"></div>
  <script>
    // The variable name 'vm' is generally used to 'store' Vue instances, which is short for ViewModel
    const vm = new Vue({
      el: '#app'.data: {
          name: 'Ben'}})</script>
</body>
Copy the code

There are actually several ways to render a template:

  • When creating an application, you only have the EL option: specify the DOM node to mount and use the HTML content inside the node as the template

  • Mount the Vue application to the specified DOM node and replace the content of the DOM node specified by el with the template content

  • There is only the template option when creating the application: the vm.$mount(el) method must then be called to mount the application to the DOM node specified by el, replacing the contents of the DOM node specified by EL

So whenever the Template option is present, the Vue application replaces the contents inside the mounted DOM node

The 💡 Vue instance also exposes some useful instance properties and methods. They all have the prefix $

const vm = new Vue({
  el: '#app'.data: {
    name: 'Ben'
  }
})

vm.$data === data // true
vm.$el === document.getElementById('app') // true

// $watch sets a listener
vm.$watch('name'.function (newValue, oldValue) {
  // This callback will be called after 'vm.name' changes
})
Copy the code

🎬 video tutorial said a small trick:

But if the Vue is “embedded” into the original project, the immediately invoked function expression should be used. The IIFE wraps the code, emulates the block scope, and the code executes immediately and has its own private variables. Avoid contaminating global variables. And I’m going to add; This is to prevent some packers from mistakenly recognizing the immediate function as an argument to the function in the previous line of code when merging code.

; (function () {
  new Vue({
    el: '#section5'.data: {
      name: 'Ben'.year: new Date().getFullYear()
    },
  })
})()
Copy the code

🎬 however, after using the immediate call function expression to wrap the code, it is not convenient to debug (in the developer tool can not directly access the Vue instance VM), you can immediately debug the function expression annotation during development, and then wrap the code when online.

Template syntax

After you mount the Vue application to the DOM, the HTML inside that node supports Mustache, a section contained in double curly braces, where you can use simple JavaScript expressions.

The filter

Filters are used for some common text formatting. Filters can be used in two places:

  • Double curly brace interpolation
  • v-bindexpression
<! -- In double braces -->
<p>{{ message | capitalize }}</p>
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
Copy the code

Of the end of the filter should be added in the JavaScript expression, the “pipe” symbol indicating {{value | filterName}}, 🎬 filter is JavaScript function, so you can receive parameters, The value of the JavaScript expression before the pipe number is always received as the first argument, and the unsolicited data is passed as the second argument.

Global registration

You can define global filters using the method Filter in Vue prototype before creating a Vue instance

Vue.filter('filterName'.function () {... })Copy the code

Local registration

You can also define local filters in the filters option of a component

// ...
filters: {
  filterName: function() {...}
}
Copy the code

Evaluate properties and listeners

Create computed properties under the computed option and create listeners under the Watch option. Both perform operations based on changes in responsive data, but they have different uses.

computed

Attributes are often evaluated to extract complex and reusable data-processing logic from functional expressions in templates. It is used directly on the template as reactive data, just like the property of data.

🎬 The biggest advantage of evaluating attributes is caching for reactive dependencies. If you want the computed property to update in real time, it needs to have reactive dependencies (based on reactive data or other sources) and return a value.

In addition to using the function method, 🎬 can also use the object method by setting the get (default only getter) and set properties for the object.

  • A getter is a computed value returned based on the data property response
  • setterIs in response to the user directly assigning a value to the calculated propertycomputed_property = value.In turn, set the response data on which it depends (i.e., update data property)
// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]}}}Copy the code
// set computed property
// the setter will be invoked and vm.firstName and vm.lastName will be updated accordingly.
vm.fullName = 'John Doe';
Copy the code

watch

A watch is also dependent on responsive data (each watch can only target one responsive data, usually a data property, compared with computed, which can listen for multiple responsive data at the same time), but it is generally used to perform asynchronous operations based on changes in responsive data, and intermediate states can be set.

// ...
watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    Watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { / *... * / }
    // You can pass in an array of callbacks, which will be called one by one
    e: [
      'handle1'.function handle2 (val, oldVal) { / *... * / },
      {
        handler: function handle3 (val, oldVal) { / *... * / },
        / *... * /}}],Copy the code

💡 should not use the arrow function to define the Watcher function, because it is the arrow function that binds the context of the parent scope, so this within the function will not point to the Vue instance as expected.

💡 If the dependent reactive data is an object or array, you need to enable the deep listening option; If you want the listener to execute its callback function immediately after the instance is initialized, you can turn on the immediate option.

watch: {
    // This callback is called whenever the property of any object being listened on changes, no matter how deeply nested it is
    c: {
      handler: function (val, oldVal) { / *... * / },
      deep: true
    },
    // This callback will be invoked immediately after the listening starts
    d: {
      handler: 'someMethod'.immediate: true}}})Copy the code

Attributes bind

Using the directive V-bind in the template to bind the attributes of the tag to dynamic data, you achieve data-driven graphics (styles).

The instruction V-bind :attrName=”value” can be abbreviated to :attrName=”value”, binding values can be strings, objects, arrays, etc.

💡 If the bound data is an object, 🎬 because HTML and JavaScript support different case and hyphen, pay attention to the corresponding relationship, That is, the inline style font-size in HTML should be fontSize as an object property in JavaScript or wrap it around “font-size” as the property name in quotes.

For two special attributes, class and style, 🎬 Vue optimizes these attributes to merge dynamically bound data with static data for the attribute (the other attributes are “back to front”).

The class binding

In addition to binding strings, the class attribute of the tag can bind objects and arrays to set multiple classnames in batches, and concatenate == directly with static data ==

  • If the binding value is an object, multiple classnames can be set at the same time and the class of the label can be quickly and dynamically switched by the Boolean true/false of the attribute value of the object attribute. However, adding newClassName is not convenient

    <div :class="classObj">
      <! -- content -->
    </div>
    Copy the code
    // ...
    classObj: {
      className1: true.className2: false
    }
    Copy the code
  • If the binding value is an array and multiple classnames are set at the same time, you can easily add additional properties by pushing the newClassName to the array, but switching/deleting the className is not easy to recover

    <div :class="classArr">
      <! -- content -->
    </div>
    Copy the code
    // ...
    classArr: ['className1'.'className2']
    Copy the code

Style binding

The tag attribute style is used to add inline styles, which can be bound to objects or arrays.

🎬 has some details to note:

  • For styles that require units, you need to specify units

  • If the bound style conflicts with the static style, the == bound style takes precedence ==

  • Arrays are allowed to be objects as elements

Two-way binding

In the label of the template, the instruction V-model is used to realize the bidirectional binding between the value of the form and the dynamic data, and the input data of the ,

💡 does not work in the textarea

The V-Model internally implements bidirectional binding by listening for different properties and throwing different events for different form elements, and can modify the corresponding event handlers if customization is required.

💡 Vue has not updated the V-Model for languages that require input methods (such as Chinese, Japanese, Korean, etc.) during input method composition. If you also want to handle this process, use input events. In addition, when the input> element is entered in the Chinese input method, press Enter to confirm sending the form. 🎬 To distinguish the two cases, you can listen on @compositionStart and @compositionEnd to judge whether the input method is on or off.

🎬 form

<! -- a single check box, bound to a Boolean -->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
Copy the code
<! -- Multiple checkboxes bound to the same array -->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>

<script>
new Vue({
  el: '... '.data: {
    checkedNames: []}})</script>
Copy the code

🎬 If and set the value attribute to customize the value, because browsers do not submit forms with unchecked checkboxes (i.e., false-value is not submitted). If you want to ensure that one of these two values can be submitted when the form is submitted, Radio buttons should be used.

After the bidirectional binding of 🎬 element

<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option value="dataA">A</option>
    <option value="dataB">B</option>
    <option value="dataC">C</option>
  </select>
</div>
<script>
new Vue({
  el: '#example-6'.data: {
    selected: []}})</script>
Copy the code

Vue provides some modifiers that make it easy to set form input values:

  • Form values are strings by default, and you can use form modifiers if you want the bound dynamic data variable to hold a numeric typev-model.number
  • Form modifierv-model.trimAutomatically filter the first and last blank characters entered by the user
  • Form modifierv-model.lazychangeData synchronization occurs after the event (after losing focus) (default is ininputEvent triggered)

Conditions apply colours to a drawing

The instructions V-if and V-show can both implement conditional rendering.

Use the v-if directive in the template tag to control rendering of the DOM, rendering elements only if the conditional directive is true, otherwise the DOM is “pulled out”.

You can also use V-if, V-else, and V-else to set conditional rendering of parallel elements of the same level. The elements of these three instructions need to be consecutive and identical. If you conditionally switch multiple blocks of similar elements, you may cause some bugs due to reuse, so that you can set different key values for the elements so that Vue can distinguish between them. 🎬 However, it is not recommended to write the business logic directly in HTML, instead, it should generate the corresponding data directly in JS according to the conditions.

Using the directive V-show in the template tag also controls DOM rendering, showing elements only if the conditional directive is true, otherwise the DOM is hidden.

💡 v-if and V-show both control how DOM is displayed or hidden on a page, but the principle and usefulness are quite different:

  • V-if controls whether the DOM will render to show or hide elements based on conditions; V-show renders the DOM first, and then changes the value of the CSS property display according to the condition. If you want to hide it, set it to display: None. Therefore, it is more efficient to use V-show ** if ** requires frequent element show hide switches.

  • The 🎬 directive v-if can be used in conjunction with

The list of rendering

Using the directive V-for in a template tag, you can render an array or object in responsive data as a series of DOM elements, called list rendering, commonly in the form V-for Item in ARR or V-for Item of ARR

  • You can iterate over arR arrays, obj objects, and number (starting at 1) numbers
  • But when iterating through an objList (an array-like object), there is no guarantee of the order in which items are iterated each time

🎬 an important point is that == needs to set the key attribute == for the generated element. Generally, the binding is a unique identifier related to the element (do not directly use index), so as to improve the efficiency of DOM update.

💡 Because objects and arrays are reference data types, modifying them often causes problems that do not trigger reactive changes correctly, 🎬 Vue is specifically optimized for common array methods (push(), POP (), shift(), unshift(), splice(), sort(), reverse())). Changing the value of an array directly by subscript usually does not trigger the view to update in a responsive manner

🎬 v-if and v-for are not recommended together because the instruction v-for has a higher priority, so list rendering is performed regardless of the element’s v-if condition, and v-if is used to determine whether the rendered DOM should be “unscrambled”, which wastes Vue performance. V-for should be used in conjunction with V-show.

The event processing

Use the directive V-ON :eventName in the template’s tag to listen for events, using the shorthand @eventName, and trigger a callback function.

<div id="example-1">
  <! Run some JavaScript code directly after the event is triggered.
  <button v-on:click="counter += 1">Add 1</button>
  <! Call the greet function after the event is triggered.
  <button v-on:click="greet">Greet</button>
  <! Pass parameters to the handler function -->
  <button v-on:click="say('what')">Say what</button>
</div>
Copy the code

The 💡 handler defaults to taking the DOM event as an argument; If you need to pass both parameters and the original DOM event to the callback function, 🎬 can pass the special variable $event, which the event handler needs to set parameters to receive

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
Copy the code
// ...
methods: {
  warn: function (message, event) {
    // Now we can access the native event object
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}
Copy the code

Vue provides a variety of event modifiers to make it easier to set the behavior of events, and you can chain multiple calls

  • .stopStop the story from spreading
  • .preventPrevents the default behavior of an event, such as redirecting to a specified URL after a form submission
  • .selfEvent when the element itself firesBefore executing the event handler function
  • .onceInvalid after only responding to an event once
  • .captureUse event capture mode
  • .passiveforscrollEvents are optimized for improved performance. But don’t put the.passive.preventUse it together because.preventWill be ignored, and the browser may show you a warning.

For UI user interface interaction events that are most common, such as mouse events, button events, etc., Vue provides mouse and button modifiers

  • Key modifier: .Enter,.tab,.delete (capture “Delete” and “backspace” keys),.Esc,.space,.up,.Down,.left,.right,.Ctrl,.Alt,.shift,.meta (command on macOS, On Windows it’s the Win key.)

  • Mouse button modifiers:.left,.right,.middle

  • . Exact Specifies the key combination that triggers the event

💡 To simply listen for CTRL release, you need to listen for CTRL’s keycode, keyup.17

🎬 video tutorial says a trick: can listen to click.right. Prevent right-click events and prevent the default behavior of pop-up menus, so that you can customize web page right-click menus

💡 Event listeners set with the v-on directive will be automatically deleted after the ViewModel is destroyed, but if you set the event listener using addEventlistener or other methods, 🎬 Remember to manually unbind in the beforeDestroy() lifecycle function to release efficacy.

Custom instruction

Vue provides a variety of built-in instructions, such as V-if, V-bind, V-ON, V-model, for easy use in templates, and also allows the registration of custom instructions.

Global registration

DirectiveName: directiveName: directiveName: directiveName: directiveName: directiveName: directiveName: directiveName: directiveName: directiveName: directiveName 🎬 Vue provides five hook functions for custom directives that can be called at different stages of the bound element. This custom directive can then be used in any element of the Vue instance

Vue.directive('directiveName', {
  // Provides five alternative hook functions that are called at different stages of the bound element
  bind: function(el) {},
  inserted: function (el) {},
  update: function (el) {},
  componentUpdated: function (el) {},
  unbind: function (el) {},})Copy the code

💡 Many times you may want to use only bind and update hook functions, and to trigger the same behavior, you can use the short form vue. directive(‘directiveName’, function (el, binding) {… })

The 🎬 directive’s hook function passes in the following arguments to manipulate the bound DOM element and pass data:

  • El is the element bound by the directive and can be used to manipulate the DOM directly

  • Binding is an object containing the following properties:

    • nameInstruction name, not includedv-The prefix
    • valueThe binding value of the instruction, for examplev-directiveName="1 + 1", the binding value is 2
    • oldValueThe preceding value of the instruction binding, only inupdatecomponentUpdatedAvailable in the hook function. Available regardless of whether the value changes
    • expressionAn instruction expression in the form of a string, such asv-directiveName="1 + 1"Where, the expression is` 1 + 1
    • argPass to instruction (optional)parameter, such asv-directiveName:argumentWhere, the parameter isargument
    • modifiersAn object containing a modifier, such asv-directiveName.foo.bar, the modifier object is{ foo: true, bar: true }
    • defThe hook function used by the directive
  • Vnode Virtual node generated by Vue compilation

  • A virtual node on oldVnode, available only in update and componentUpdated hooks

⚠️ If you use both the arg parameter and the modifier when using directives, use the modifier in sequence (because there is only one ARG; And modifier can series more, should be in the last) v – directiveName: argument. The modifier

💡 Dynamic command parameters: V-directivename :param is the param part of the directive, which can be set to dynamic parameters. V-mydirective :[argument]=”value” This allows the user to pass various parameters (without prior restriction), which makes custom instructions flexible to use in the application.

Local registration

Registers local directives in the component’s option Directives, which also provide 5 hook functions. You can then use custom directives on any element in the component’s template

// ...
directives: {
  directiveName: {
    // Set the hook function
    inserted: function (el) {}}}Copy the code