vue: event handling, v-model, v-on, v-bind
<img v-on:[imgEvent]="imgWidth += 10" :width="imgWidth" src="../assets/logo.png"> <img @[imgEvent]="imgWidth += 10" :width="imgWidth" src="../assets/logo.png">
- dynamic event binding - uses v-bind longhand
<input v-model="val1"> <input v-bind:value="val1" v-on:input="val1 = $event.target.value"> <input :value="val" @input="val = $event.target.value">
- equivalent
<a v-on:click.prevent.self></a> <a v-on:click.self.prevent></a>
- chained modifier - order matters - first prevents all clicks - second only prevent elements on the element itself
<input @click="isRed = !isRed" type="checkbox">red background <p :class="isRed ? 'red' : null">some text</p> <p :style="isRed ? 'background-color: red;' : null">more text</p>
- class and style binding - uses v-bind shorthand - prefer class over style for SOC, reusability - but use style when CSS is computed (e.g. isRed, font size)
<button @click.once="say('click')">click multiple, get one alert</button>
- click event will be triggered at most once
<div v-on:scroll.passive="onScroll">...</div>
- communicates to browser that want event default behavior - scrolling will happen immediately instead of waiting for 'onScroll' to complete - overrides any event.preventDefault()
v-bind
- directive - brings a JS value into markup - JS -> markup - remember, v-model is shorthand for v-bind + v-on:input
v-on: input
- directive - takes input and events from markup into JS - markup -> JS - remember, v-model is shorthand for v-bind + v-on:input
v-model
- directive - enables 2-way binding for form input element (input, textarea, select) or component - shorthand for v-bind + v-on:input - extra smarts for text field handling (firing fewer events until user leaves field or space entered)
<img :[imgAttr]="imgWidth" src="../assets/logo.png">
- dynamic attribute binding - uses v-bind shorthand
$on(eventName, eventHandler)
- Vue events interface - listen for an event
$once(eventName, eventHandler)
- Vue events interface - listen for an event only once
$off(eventName, eventHandler)
- Vue events interface - stop listening for event
what happens to event listeners when ViewModel is destroyed
- automatically removed - don't need to clean up explicitly
VEventChildBackground.vue: <input @click="$emit('background')" type="checkbox"> red background VEventParent.vue: <VEventChildBackground @background="isRed = !isRed"/> <p :style="styleObj">foo</p>
- event emitter from child to parent - no params
VEventChildFontSize.vue: <button @click="$emit('bigger-font', sizeIncrease)">bigger text</button> <input v-model="sizeIncrease">% VEventParent.vue: <VEventChildFontSize @bigger-font="textSize += Number($event)"/> <p :style="styleObj">foo</p>
- event emitter from child to parent - with params
<a v-bind:['foo' + bar]="value"> ... </a>
- invalid - triggers a compiler warning
<input v-model.lazy="msg" >
- modifier - by default, v-model syncs data after each input event - can add 'lazy' to instead sync after change events
<input v-model.number="age" type="number">
- modifier - converts input to number using parseFloat()
<form v-on:submit.prevent="onSubmit"> ... </form>
- modifier - default HTML behavior with submit is to reload page - essentially a call to event.preventDefault() on triggered event - submit event will no longer reload the page
<div @click="say('outer div - SHOULD NOT GET THIS')"><button @click.stop="say('button click')">click</button></div>
- modifier - stop click event propagation
<input v-model.trim="msg">
- modifier - trims whitespace from input
<select v-model="sels2" multiple> <option v-for="option in sels2options" v-bind:value="option.value" v-bind:key="option.value" >{{ option.text }}</option> </select> sels2: [], sels2options: [ { text: "x", value: "x" }, { text: "y", value: "y" }, { text: "z", value: "z" } ]
- populate multi-select from data - must specify key - all are bound to same array called sels2 - array holds option values selected
<div @click.ctrl="doSomething">Do something</div>
- system modifier - trigger if anything combined with CTRL
<div @click.ctrl.exact="doSomething">Do something</div>
- system modifier - trigger if only CTRL is pressed
system modifier keys
- trigger mouse or keyboard event listeners only when a specific 'modifier' key is pressed - .ctrl, .alt, .shift, .meta (e.g. windows key)
<button @click.exact="onClick">A</button>
- trigger when NO system modifiers used
VModelComponent.vue: <input :value="val" @input="$emit('input', $event.target.value)"> EventParent.vue: <VModelComponent v-model="val"/>
- using v-model with a component - requires :value and @input=$emit attrs
<router-link :to="'/account/' + id + '/repos'">https://github.com/vuejs/vue</router-link>
- v-bind to construct attribute from data
<textarea v-model="multi"></textarea>
- v-model for multi line text box - single item stored in data 'multi' - Interpolation on textareas (<textarea>{{text}}</textarea>) won't work.
<select v-model="sels" multiple><option>A</option>option>B</option></select>
- v-model for multi select - all are bound to same array called 'sels' - array holds the options selected
<input type="checkbox" value="a" id="a" v-model="cboxes"> <input type="checkbox" value="b" id="b" v-model="cboxes">
- v-model for multiple cboxes - all are bound to same array called 'cboxes' - array will contain ids of items selected - needs to have 'value' attr
<input type="radio" value="c" id="c" v-model="val"> <input type="radio" value="d" id="d" v-model="val">
- v-model for radio buttons - single item selected stored in data 'val' - needs to have 'value' attr
<input type="checkbox" id="e" v-model="cb">
- v-model for single checkbox - t/f
<select v-model="sel"><option>A</option><option>B</option></select>
- v-model for single select - single item stored in data sel
Events.vue: <button v-on:click="cb">v-on:click</button> <button @click="cb">@click</button> props: { cb: Function } App.vue: <Events :cb="alert"/> methods: { alert: () => alert("alert") }
- v-on example - click handler to alert passed as prop to child - both longhand and shorthand example
<div v-bind:id="'list=' + id"></div>
- valid JS expression to craft id
<input type="radio" v-model="radio" v-bind:value="val">
- value bindings - define specific to return for radio buttons if selected
<input type="checkbox" id="vb1" v-model="val" true-value="yep" false-value="nope">
- value bindings - define specific values instead of t/f for checkbox
v-model ignores which attributes on HTML form elements, and why?
- value, checked, selected - Vue instance is source of truth, not HTML form
this.$emit('myEvent') <my-comp v-on:my-event="doIt"></my-comp> event names: kebab or camel case?
- won't work - recommend kebab-case (emit 'my-event') - no upper case, as transformed to lowercase because HTML is case-insensitive
event modifiers
.stop, .prevent, .capture, .self, .once, .passive
v-bind shorthand
: (think of binding to attribute :class)
v-on shorthand
@ (think of events and @click)