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.