preface

Vue learning notes combined with official documentation and rookie tutorials.

Conditional statements

V – if with v – else

We can bind data not only to DOM text or attributes, but also to DOM structures.

The condition judgment uses v-if instruction

We can add an “else” block to v-if using the V-else directive

V-else -if was added in 2.1.0 as an else-if block for V-if, as the name suggests. Can be chain type multiple use

<div id="app">
    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    type: 'C'
  }
})
</script>
Copy the code

Because v-if is an instruction, it must be added to an element. But what if you want to switch between multiple elements? You can treat a

Manage reusable elements with keys

Vue gives you a way to say “These two elements are completely separate, don’t reuse them”. You simply add a key attribute with a unique value

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>
Copy the code

Note that elements are still reused efficiently because they don’t add key attributes.

v-show

You can also use the V-show command to display elements based on conditions, except that elements with v-show are always rendered and retained in the DOM. V-show simply toggles the element’s CSS property display.

Note that v-show does not support

<h1 v-show="ok">Hello! </h1>Copy the code

Difference between V-if and V-show

V-if is “true” conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch.

V-if is also lazy: if the condition is false during initial rendering, nothing is done — the conditional block is not rendered until the condition is true for the first time.

V-show, by contrast, is much simpler — elements are always rendered regardless of initial conditions and simply switch based on CSS.

In general, V-if has a higher switching overhead, while V-show has a higher initial rendering overhead. Therefore, v-show is good if you need to switch very frequently; It is better to use V-if if conditions rarely change at run time.

Looping statements

V-for iterated array

The V-for directive requires a special syntax in the form of site in Sites, which is the source data array, and site, which is an alias for iterating array elements.

You can also use of instead of in as a separator, since it is closer to the syntax of a JavaScript iterator

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.name }}
    </li>
  </ol>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    sites: [
      { name: 'Runoob' },
      { name: 'Google' },
      { name: 'Taobao' }
    ]
  }
})
</script>
Copy the code

V-for iterates

V-for can iterate over data via attributes of an object:

<div id="app">
  <ul>
    <li v-for="value in object">
    {{ value }}
    </li>
  </ul>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    object: {
      name: 'Rookie Tutorial',
      url: 'http://www.runoob.com',
      slogan: 'Not only technology, but also dream! '
    }
  }
})
</script>
Copy the code
<div id="app">
  <ul>
    <li v-for="(value, key, index) in object">
     {{ index }}. {{ key }} : {{ value }}
    </li>
  </ul>
</div>
Copy the code

When traversing an Object, the result of object.keys () is traversed, but its results are not guaranteed to be consistent across different JavaScript engines.

V-for iterates over integers

Similar to Java

<div id="app">
  <ul>
    <li v-for="n in 10">
     {{ n }}
    </li>
  </ul>
</div>

Copy the code

V-if is used with v-for

It is not recommended to use both V-if and V-for

When v-if is used with V-for, v-for has a higher priority than V-if. This priority mechanism is useful when you only want to render nodes for a subset of items

<li v-for="todo in todos" v-if=! "" todo.isComplete">
  {{ todo }}
</li>
Copy the code

The above code will only render the unfinished todo.

If your goal is to conditionally skip the loop, place v-if on the outer element

V-for Indicates the maintenance status

When Vue is updating a list of elements rendered using V-for, it defaults to the “update in place” policy. If the order of data items is changed, Vue does not move DOM elements to match the order of data items, but instead updates each element in place and ensures that they are rendered correctly at each index location.

This default mode is efficient, but only for list rendering output that does not depend on child component state or temporary DOM state (for example, form input values).

To give Vue a hint that it can track the identity of each node to reuse and reorder existing elements, you need to provide a unique key attribute for each item

It is recommended to provide key attributes whenever possible with V-for, unless traversing the output DOM content is simple or you deliberately rely on default behavior for performance gains. Use a string or numeric value as a key value.

Because it is a general mechanism for Vue to identify nodes, key is not specifically associated with V-for. As we will see later in the guide, it has other uses as well.

For details, see the official document: Official document — Key

Array update detection

Change the way

Vue wraps around the array change methods being listened for, so they will also trigger view updates.

push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Copy the code

Replace the array

Changing methods, as the name suggests, changes the original array from which they were called. In contrast, there are non-changing methods, such as filter(), concat(), and slice(). They do not alter the original array, but always return a new one. When using a non-change method, you can replace an old array with a new one

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
Copy the code

You might think that this would cause Vue to discard the existing DOM and re-render the entire list. Fortunately, this is not the case. Vue implements some clever heuristics to maximize the reuse of DOM elements, so it is very efficient to replace an array with one containing the same elements.

Due to JavaScript limitations, Vue cannot detect array and object changes

Display filtering results

Sometimes we want to display a filtered or sorted version of an array without actually changing or resetting the original data. In this case, you can create a calculated property to return a filtered or sorted array.

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
Copy the code

You can use a method in cases where computed attributes do not apply (for example, in nested V-for loops)

<ul v-for="set in sets">
  <li v-for="n in even(set)">{{ n }}</li>
</ul>
data: {
  sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
Copy the code

Use V-for on components

In version 2.2.0+, keys are now required when using V-for on components.

However, no data is automatically passed to the component because the component has its own independent scope. To pass iteration data to the component, we use prop

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index"
  v-bind:key="item.id"
></my-component>
Copy the code

The reason for not automatically injecting items into the component is that it tightly couples the component to the v-for operation. Knowing where component data comes from enables components to be reused in other contexts.

Calculate attribute

Computed properties are useful when dealing with some complex logic. They were originally designed for simple calculations. Putting too much logic into a template can make it too heavy and difficult to maintain.

<div id="app"{{reversedMessage}}</p> </div> <script> var vm = new Vue({el:'#app',
  data: {
    message: 'Runoob! '}, computed: {// Calculate the getter reversedMessage for attributes:function() {// 'this' points to the VM instancereturn this.message.split(' ').reverse().join(' ')
    }
  }
})
</script>
Copy the code

Vm. reversedMessage depends on VM. message and is updated when the VM. message changes.

Computed is different from methods

Instead of computed, we can use methods, which are the same in effect, but computed attributes are cached based on their responsive dependencies and reevaluated only when the dependencies change. With methods, functions are always called again when rendering again.

This means that as long as the Message has not changed, multiple visits to the reversedMessage computed property will immediately return the previous computed result without having to execute the function again.

This also means that the following computed attributes will not be updated because date.now () is not a reactive dependency:

computed: {
  now: function () {
    return Date.now()
  }
}
Copy the code

Arguably, using computed performance is better, but if you don’t want caching, you can use the Methods attribute.

Computed differs from Watch

Vue provides a more general way to observe and respond to changes in data on Vue instances: listening properties. It’s easy to abuse Watch when you have some data that needs to change with other data — especially if you’ve used AngularJS before. However, it is often better to use computed properties rather than imperative Watch callbacks

Var vm = new Vue({el:'#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' '+ val}}}) //computed attribute version code: var vm = new Vue({el:'#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})
Copy the code

computed setter

Computed properties only have getters by default, but you can provide a setter if you need one

var vm = new Vue({
  el: '#app',
  data: {
    name: 'Google',
    url: 'http://www.google.com'
  },
  computed: {
    site: {
      // getter
      get: function () {
        return this.name + ' ' + this.url
      },
      // setter
      set: function (newValue) {
        var names = newValue.split(' ') this.name = names[0] this.url = names[names.length-1]}}}}) // Call setter, vm.name and vm.url will be updated accordingly vm.site ='Rookie tutorial http://www.runoob.com'; / / usesetMethods the document. Write ('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);
Copy the code

Monitor properties

We can respond to data changes through watch. This approach is most useful when asynchronous or expensive operations need to be performed when data changes.

 <div id = "computed_props"> km: <inputtype = "text" v-model = "kilometers"> : < inputtype = "text" v-model = "meters">
      </div>
	   <p id="info"></p>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#computed_props',
            data: {
               kilometers : 0,
               meters:0
            },
            methods: {
            },
            computed :{
            },
            watch : {
               kilometers:function(val) {
                  this.kilometers = val;
                  this.meters = this.kilometers * 1000
               },
               meters : function(val) { this.kilometers = val/ 1000; this.meters = val; }}}); //$watchIs an instance method VM.$watch('kilometers'.function(newValue, oldValue) {// This callback will call document.getelementByid ("info").innerHTML = "The value before modification was:" + oldValue + ", the modified value is:" + newValue;
		})
      </script>
Copy the code

For details about the vm.$watch method, see the official API documentation vm.$watch