zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

Vue Study Notes (3) - Computed, Watch, Class, Style

1. Computed Properties#

1. Example#

<div id="app">
  <div>{{message}}</div>
  <div>{{revermessage}}</div>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'hello,wolrd'
    },
    computed: {
      revermessage: function() {
        return this.message.split('').reverse().join('')
      }
    }
  })
</script>

Declare a computed property revermessage that is assigned to the return value of performing some method operations on message in computed.

At this time, vm.revermessage depends on the changes of vm.message. Changing the data of message will cause the update of revermessage.

2. Computed Properties and Methods#

You can also achieve the desired effect by calling methods in expressions.

<div id="app">
  <div>{{message}}</div>
  <div>{{revermessage()}}</div>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'hello,wolrd'
    },
    methods: {
      revermessage: function() {
        return this.message.split('').reverse().join('')
      }
    }
  })
</script>

After testing, the results of the two methods are the same.

We can define the same function as a method instead of a computed property. The final results of the two methods are indeed exactly the same.

The difference is: computed properties are cached based on their reactive dependencies, and they are only re-evaluated when the reactive dependencies, that is, message, change. This means that as long as message has not changed, accessing the revermessage computed property multiple times will only return the cache of the previous calculation result, instead of directly executing the function of the computed property.

Methods, on the other hand, execute the function every time it triggers a re-render, which adds an extra cost.

Why do we need caching? Suppose we have a computed property A with a large performance overhead, which needs to traverse a huge array and perform a lot of calculations. Then we may have other computed properties that depend on A. Without caching, we will inevitably execute the getter of A multiple times! If you don't want caching, use methods instead.

3. Computed Properties and Watch Properties#

Vue also has another way to observe data changes on Vue instances: watch properties.

<div id="app">
  {{fullname}}
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      firstname: 'a',
      lastname: 'b',
      fullname: 'ab'
    },
    watch: {
      firstname: function(val) {
        this.fullName = val + ' ' + this.lastName
      },
      lastname: function(val) {
        this.fullName = this.firstName + ' ' + val
      }
    }
  })
</script>

The usage process is extremely cumbersome and repetitive. Let's try using computed properties again.

<div id="app">
  {{fullname}}
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      firstname: 'a',
      lastname: 'b'
    },
    computed: {
      fullname: function() {
        return this.firstname + this.lastname
      }
    }
  })
</script>

We quickly and easily obtained the desired function expression.

4. Setter of Computed Properties#

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]
    }
  }
}

Now enter vm.fullName = 'John Doe' in the console, the page will respond, and the setter will be called, vm.firstname and vm.lastname will also be updated accordingly.

2. Binding Class and Style#

1. Object Syntax#

You can pass an object to v-bind:class to dynamically toggle classes.

<div v-bind:class="{active: ok}"></div>

You can dynamically control the class by controlling the boolean value of ok.

You can also create multiple fields without affecting the existence of normal className.

HTML:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

Data:

data{
  isActive: true,
  hasError: false
}

The result is:

<div class="static active"></div>

When isActive or hasError changes, the class list will be updated accordingly. For example, if the value of hasError is true, the class list will become "static active text-danger".

The bound data object does not have to be written directly in the inline template.

<div id="app">
  <div v-bind:class="classobject"></div>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      classobject: {
        active: true,
        'text-danger': true
      }
    },
  })
</script>

<!-- <div class="active text-danger"></div> -->

If className has special symbols, you must add quotes '' or "".

2. Array Syntax#

You can pass an array to v-bind:class to apply a list of classes.

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

Rendered as:

<div class="active text-danger"></div>

3. Used on Components#

When using the class property on a custom component, these classes will be added to the root element of the component. The existing classes on this element will not be overwritten.

Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

Then add some classes when using:

<my-component class="baz boo"></my-component>

The HTML will be rendered as:

<p class="foo bar baz boo">Hi</p>

The same applies to class with data binding.

<my-component v-bind:class="{ active: isActive }"></my-component>

When isActive is truthy, the HTML will be rendered as:

<p class="foo bar active">Hi</p>

4. Binding Inline Styles#

The object syntax of v-bind:style is very intuitive—it looks very similar to CSS, but it is actually a JavaScript object. CSS property names can be written in camelCase or kebab-case with quotes.

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

js:

data: {
  activeColor: 'red',
  fontSize: 30
}

Or bind directly to an object, which makes the template clearer

<div v-bind:style="styleObject"></div>

js:

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

You can also apply multiple objects to an element

<div v-bind:style="[baseStyles, overridingStyles]"></div>

Automatic Prefixing

When v-bind:style needs to use browser prefixes, such as -webkit-, Vue will automatically detect and generate the corresponding prefixes.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.