busy developers guide to vuejs - jax london · – angular: •angular is much ... – typically...
TRANSCRIPT
Busy Javascript Developer's Guideto VueJS
Ted NewardNeward & Associates
http://www.tedneward.com | [email protected]
VueJS: An Overview
VueJS
What is VueJS?"An incrementally adoptable ecosystem that scales between
a library and a full-featured framework.""Vue is a progressive framework for building user interfaces.
... Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries."
VueJS
But how is it like....?– React:
•runtime perf is a wash (for the most part)•in React, everything is JS; Vue "embraces classic [Web] technologies"•Vue supports JSX (but suggests it's a touch simpler)•both scale up (code-wise) well; Vue "scales down" better•native rendering (ReactNative) doesn't really match well to Vue (yet)•React has larger/richer ecosystem (for now)
VueJS
But how is it like....?– Angular:
•Angular is much more opinionated than Vue•Angular's learning curve is much steeper•Angular requires TypeScript; Vue can use it or not as you choose
Objectives
In this presentation, we want to:– take a quick pass through VueJS– see how it differs from React or Angular
Getting Started
Bringing VueJS into your life
Getting Started
For the simplest use possible...– incorporate Vue directly as a script-tag href– this brings Vue onto the page on a per-page basis
Getting Started
Simplest Vue usage<html><head><title>VueJS simple HTML use</title></head><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><body><h1>This is a straight HTML page!</h1>
<div id="app">{{ message }}
</div><script>
var app = new Vue({el: '#app',data: {
message: 'Hello Vue!'}
})</script></body></html>
Getting Started
If you know you want to do Vue as a SPA...– ensure you have Node v8.x (or later) installed
– install the Vue CLI tool
npm install -g @vue/clivue --version (should be 3.x or newer)
– NOTE: vue-cli tool (2.x and older) uses different npm package
•uninstall vue-cli before installing @vue/cli•these slides assume @vue/cli (3.x and newer) only
Getting Started
Use the CLI to scaffold out your project– vue create {project-name}
follow the interactive prompts– vue ui
use the launched web GUI to create the project– each has "presets" of configurations for the project
or you can make manual choices, and save those as a preset
Getting Started
Vue CLI– vue serve: compiles and hot-reloads
particularly useful for per-component execution– vue build: compiles and minifies for production– vue inspect: inspect the resolved configuration/build– fully documented at https://cli.vuejs.org
Getting Started
App.vue<template>
<div id="app"><img alt="Vue logo" src="./assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/>
</div></template>
<script>import HelloWorld from './components/HelloWorld.vue'export default {
name: 'app',components: {
HelloWorld}
}</script>
Getting Started
App.vue styling (CSS)<style>#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}</style>
Getting Started
HelloWorld.vue<template>
<div class="hello"><h1>{{ msg }}</h1>
</div></template>
<script>export default {
name: 'HelloWorld',props: {
msg: String}
}</script>
Getting Started
HelloWorld.vue styling (CSS)<!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>h3 {
margin: 40px 0 0;}ul {
list-style-type: none;padding: 0;
}li {
display: inline-block;margin: 0 10px;
}a {
color: #42b983;}</style>
Vue Template Syntax
Vue Views
Templates
Two means of providing views– HTML templates
this is the usual path– hand-written render functions
for those familiar with Virtual DOM concepts and the raw power of code
Templates
Declarative rendering<div id="app">
{{ message }}</div><script>
var app = new Vue({el: '#app',data: {
message: 'Hello Vue!'}
})</script>
Templates
Declarative rendering– use {{ }} to declaratively render data– binds to a Javascript data element (object, variable, etc)– reactive: if the data changes, the rendering will as well
Templates
Binding attributes<div id="app-2">
<span v-bind:title="message">Hover your mouse over me for a few seconds
</span></div><script>var app2 = new Vue({
el: '#app-2',data: {
message: 'You loaded this page on ' + new Date().toLocaleString()}
})</script>
Templates
Binding attributes– mustaches ("{{ }}") cannot be used inside of HTML
attributes– use v-bind: to bind an attribute to a Javascript expression
without this, can't determine literal value from expressions– also reactive– v-bind is a directive
all directives are prefixed with "v-"– some directives take an "argument"
•denoted by a colon after the directive name•for example, v-bind:href="..."
Templates
Conditional<div id="app-3">
<span v-if="seen">Now you see me</span></div><script>var app3 = new Vue({
el: '#app-3',data: {
seen: true}
})</script>
Templates
Conditionals (v-if)– v-if binds to a Javascript expression
•if true, displays the attached element•if false, hides/removes the attached element
– again, reactive, so changes after definition are rendered– v-else-if provides "else-if" functionality
must immediately follow v-if– v-else provides "else" block
must immediately follow v-if or v-else-if
Templates
Iteration<div id="app-4">
<ol><li v-for="todo in todos">
{{ todo.text }}</li>
</ol></div><script>var app4 = new Vue({
el: '#app-4',data: {
todos: [{ text: 'Learn JavaScript' },{ text: 'Learn Vue' },{ text: 'Build something awesome' }
]}
})</script>
Templates
Iteration (v-for)– v-for binds to a Javascript expression
typically a "for-in" expression– element is repeated for each element in the iteration– frequently combined with v-bind:key to obtain key for loop– or use tuple-style syntaxv-for='(item, index) in collection'– also works to iterate properties of an object
Templates
Event-handling<div id="app-5">
<p>{{ message }}</p><button v-on:click="reverseMessage">Reverse Message</button>
</div><script>var app5 = new Vue({
el: '#app-5',data: {
message: 'Hello Vue.js!'},methods: {
reverseMessage: function () {this.message = this.message.split('').reverse().join('')
}}
})</script>
Templates
Events– v-on directive binds events to Javascript expression
expression can either be inline or call to a Javascript method– original DOM event can be accessible via $event object– v-on:keyup has suffixes to track only specific key codes
".enter", ".tab", ".delete", ".esc", ".space", ".up", ".down", ".left", ".right" or the numeric key code
Templates
Form input<div id="app-6">
<p>{{ message }}</p><input v-model="message"><br/><input type="checkbox" id="jack" value="Jack" v-model="checkedNames"><label for="jack">Jack</label><input type="checkbox" id="john" value="John" v-model="checkedNames"><label for="john">John</label><input type="checkbox" id="mike" value="Mike" v-model="checkedNames"><label for="mike">Mike</label><br><span>Checked names: {{ checkedNames }}</span>
</div><script>var app6 = new Vue({
el: '#app-6',data: {
message: 'Hello Vue!',checkedNames: []
}})</script>
Templates
Forms and models– v-model binds object to user input– the Javascript object/property as the single-source-of-truth– most of the time, this will "do the right thing"
but in cases where strings aren't desired, Vue has customizations
Templates
Raw HTML binding<div id="app-7"><p>Using mustaches: {{ rawHtml }}</p><p>Using v-html directive: <span v-html="rawHtml"></span></p></div><script>var app7 = new Vue({
el: '#app-7',data: {
rawHtml: `<span style="color:red">This shold be red</span>`}
})</script>
Templates
"Raw" HTML binding– v-html informs Vue to interpret expression as HTML– without it, HTML is just displayed as raw text
Vue Components
How Vue views the world
Components
VueJS suggests organizing concerns into components– a Vue component has:
•a template•code•style
– organized into a single named concept– instantiatable into distinct/separate instances
reusable Vue instances– often organized into ".vue" files for convenience– ... or define using Vue.component() method
Components
Defining a component– three sections
•template: HTML layout and organization•script: Javascript code/structure definition•style: CSS styling
– component must be registered before use
Components
Defining a component: .vue file– typically lives in src/components– <template> section
uses template syntax for HTML "extensions" and declarative syntax
– <script> sectionexports JSON object with predefined names
– <style> section
Components
ButtonCounter component: src/components/ButtonCounter.vue<template><button v-on:click="count++">You clicked me {{ count }} times.</button></template>
<script>export default {
name: 'ButtonCounter',data: function() {
return {count: 0
}}
}</script>
<style scoped></style> <!-- No styling -->
Components
ButtonCounter component: usage from src/App.vue<!-- {{## BEGIN usage ##}} --><template>
<div id="app"><Message msg="Welcome to VueJS Components"/><button-counter></button-counter>
</div></template>
<script>import Message from './components/Message.vue'import ButtonCounter from './components/ButtonCounter.vue'export default {
name: 'app',components: {
Message,ButtonCounter
}}</script><!-- {{## END usage ##}} -->
<style>#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
Components
Defining a component: Vue.component() method– typically used for non-scaffolded Vue apps– Vue.component() takes a name and JSON object
•name: the 'kebab-named' name to use in the HTML•object: anonymous JSON object with named properties defining the component's behavior
– object property names•data: function returning a data object used for the component instance•template: HTML template for display
Components
ButtonCounter component: Vue.component registrationVue.component('button-counter', {
data: function() {return {
count: 0}
},template: `<button v-on:click="count++">You clicked me {{ count }}
times.</button>`})var app = new Vue({
el: '#app',data: {
message: 'Hello Vue!'}
})
Components
ButtonCounter component: Usage<div id="app">
{{ message }}<button-counter></button-counter>
</div>
Components
Components form a parent-child relationship– App component uses components, which each use
components, which...this is how we decompose an application into smaller, manageable parts
– parent components need to pass data to child componentsthrough props
– child components need to pass events back up to parent components
through custom events
Components
Initial component state: Props– custom attributes registered for a component– passed in on instantiation (usually in HTML template)– can be of any Javascript type (strings, objects, or others)
•Vue recommends the more detail and typing, the better•user-defined types are acceptable here too
– becomes part of the component's datado not attempt to modify props, however; Vue will warn if you do
Components
Content body: Slots– "body" of the component tag can be obtained as a "slot"– the template will replace "<slot></slot>" with the body
inside the usage– slots can be named if it's important to distinguish different
content typesthink "header", "body", "footer" in certain HTML elements
Components
BlogPost component: Definition<template>
<div><h3>{{ title }}</h3><slot></slot>
</div></template>
<script>export default {
name: 'BlogPost',props: {
title: {type: String,required: true
}},data: function() {
return {}
}}</script>
Components
Usage (template)<template>
<div id="app"><Message msg="Welcome to VueJS Components"/><blog-post v-for='post in posts'
v-bind:key="post"v-bind:title="post.title">{{ post.content }}</blog-post>
<blog-post>You should not see this since title was missing</blog-post>
</div></template>
Components
Usage (script)<script>import BlogPost from './components/BlogPost.vue'import Message from './components/Message.vue'
export default {name: 'app',data: function() { return {
posts: [{ title: "Hello world", content: "This is a post" },{ title: "Hello again", content: "This is another post" },{ title:" Hello yet again", content: "You get it" }
]} },components: {
Message,BlogPost
}}</script>
Components
Custom events– use $emit() function (of each Vue instance) to emit an
eventfirst parameter is the name, second is any value for the event
– parents can then capture the event using v-on:
Summary
Wrapping up
Summary
VueJS is...– a progressive Web framework– slightly opinionated– scalable both up and down (in terms of code size)
Summary
Some additional VueJS resources– https://vuejs.org
canonical reference for VueJS
Credentials
Who is this guy?– Principal -- Neward & Associates
– Director, Smartsheet.com
•Developer Relations•Solutions Engineering
– Microsoft MVP; Java Expert
– Author
Professional F# 2.0 (w/Erickson, et al; Wrox, 2010)Effective Enterprise Java (Addison-Wesley, 2004)SSCLI Essentials (w/Stutz, et al; OReilly, 2003)Server-Based Java Programming (Manning, 2000)
– Blog: http://blogs.tedneward.com
– Twitter: @tedneward
– For more, see http://www.newardassociates.com