Busy Javascript Developer's Guide to VueJS Ted Neward Neward & - - PowerPoint PPT Presentation
Busy Javascript Developer's Guide to VueJS Ted Neward Neward & - - PowerPoint PPT Presentation
Busy Javascript Developer's Guide to VueJS Ted Neward Neward & Associates http://www.tedneward.com | ted@tedneward.com VueJS: An Overview VueJS What is VueJS? "An incrementally adoptable ecosystem that scales between a library and
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
- nly, 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/cli vue --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
- r 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 syntax v-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> section
exports 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 {
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 registration
Vue.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 components
through 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 data
do 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 types
think "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 event
first 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