I've been developing a generic Field component for use in forms in a Vue web app I'm developing. In my EditProduct component, for example, I have multiple instances of the Field component, some of them of type 'checkbox', some 'text', etc. Effectively what the checkbox variant does is generate something like this:
<div class="col-xs-2">
<label>
<input id='organic' name='organic' type="checkbox" v-model="product.organic"/> Organic
</label>
</div>
from this:
<field :cols="2" name="organic" v-model="product.organic" type="checkbox"></field>
That's much simplified, but shows the general idea. What I'd like to be able to do is to pass something like a 'change' handler function name as a prop, like this:
<field :cols="2" name="organic" v-model="product.organic" type="checkbox" change="this.handleSomething"></field>
This would call a function in the EditProduct component. I'm not sure how to get this to work, though. I already have a change handler method in my Field component which is there to emit the notification event:
methods: {
handleCheckbox: function (event) {
this.$emit('input', event.target.checked);
if(this.change){
//do something here...
}
}
},
My idea was to test for the existence of a 'change' prop here and then do something, but all I have at this point is a string containing the name of a function. How do I actually use this to call a function, preferably with an argument derived from $event (such as $event.target.checked, say)?
js Dynamic Components allows the users to switch over the components without updating the route of the Vue. js application itself. It also keeps the data in its current state. It is useful when the user is in a tabbed interface.
Conclusion. Vue updates the DOM asynchronously; tests runner executes code synchronously instead.
A Watcher is a useful and special feature provided by VueJs to watch over a component or data property and perform specific actions when the value of the component or data property is changed. It is the most generic and recommended way to react over a data change in a vue instance.
Rather than passing in a handler, emit an event from your Field component when the internal value changes. Then, using v-on
, you can register a handler for that event.
Here is the documentation for $emit. Usage: this.$emit('event-name', arguments...)
Here is the documentation for v-on. Usage: <component v-on:event-name="handler">
You can also use v-on
to register handlers for default events. For example, an input
element will fire a change
event when it is changed. Thus,
<input type="checkbox" v-on:change="onChange"/>
will cause onChange
to fire when the checkbox changes. Note that arguments are automatically passed into the handler. So, in this case, the event is passed into onChange
.
Here is an example that puts it all together. In this example we see
field
component containing a single checkbox. It fires a change
event when the checkbox is changed, and passes on event.target.checked
event.target.checked
)field
components are created. Each one uses a different handlerVue.component('field', {
template: '#field',
data: function() {
return {
value: null
}
},
methods: {
onChange: function(event) {
// emit a change event
// Provide event.target.checked as an argument
this.$emit('change', event.target.checked);
}
}
})
new Vue({
el: '#app',
data: {
selected1: false,
selected2: false
},
methods: {
changeHandler1: function(selected) {
this.selected1 = selected;
},
changeHandler2: function(selected) {
this.selected2 = selected;
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="app">
<p>Selected1: {{selected1}}</p>
<p>Selected2: {{selected2}}</p>
<!-- Register a handler for the 'change' event -->
<field v-on:change="changeHandler1"></field>
<field v-on:change="changeHandler2"></field>
</div>
<template id="field">
<!--
By default, the input element fires a change event
when it is modified. The event is automatically passed
into the handler.
-->
<input type="checkbox" v-on:change="onChange"/>
</template>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With