$30 off During Our Annual Pro Sale. View Details »

Intro to VueJS

Matt Stauffer
February 22, 2017

Intro to VueJS

Casual meetup intro to VueJS. Scrapped together in a few hours for Gainesville JS (http://gnvjs.com/)

Many of the examples are just from the docs--consider this a draft of a potential future conference talk.

Matt Stauffer

February 22, 2017
Tweet

More Decks by Matt Stauffer

Other Decks in Technology

Transcript

  1. Introducing Vue.JS
    (A casual introduction)

    View Slide

  2. What is Vue?

    View Slide

  3. What is Vue?
    It's a JavaScript framework.
    It has a Virtual DOM and composable, reactive components.
    Its core is small and works well with companion libraries for routing,
    global state, and HTTP requests.
    It's light, fast, and flexible.

    View Slide

  4. How is it different from ...
    • jQuery? (jQuery is not a framework, it's a library)
    • Knockout? (more modern, lifecycle hooks, better component
    management, more active development)
    • AngularJS? (simpler, faster, less opinionated, more flexible, one-way
    data binding)
    • React? (faster, simpler tooling, and prefers HTML/CSS over JavaScript
    for templates)
    • Ember? (simpler, less opinionated, no need for Ember objects, faster)

    View Slide

  5. How is it different from ...
    Learn more: Vue's internal comparison with other frameworks
    https://vuejs.org/v2/guide/comparison.html

    View Slide

  6. What does the syntax look like?

    {{ message }}


    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>message: 'Hello World!'<br/>}<br/>})<br/>

    View Slide

  7. What did that just do?
    • Create a Vue instance that's bound to a div with an id of "app"
    • Interpret the contents of that div as its template
    • Read Mustache-style syntax ({{ message }}) and in response
    echo out the contents of the "message" variable

    View Slide

  8. Reactive data

    View Slide

  9. Reactive data
    The data in the previous example is "reactive"—if we change the
    message it'll update the template:
    <br/>var vm = new Vue({<br/>el: '#app',<br/>data: {<br/>message: 'Hello World!'<br/>}<br/>})<br/>// here, or in your console:<br/>vm.message = 'Goodbye World!'<br/>// ... template will update<br/>

    View Slide

  10. Data binding with v-model



    Message is: {{ message }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>message: ''<br/>}<br/>})<br/>

    View Slide

  11. V-model in action

    View Slide

  12. Options for templating

    View Slide

  13. What else can we do in our templates?
    • You could write your own render functions and even use JSX
    • mustache: {{ propertyName }}
    • v-bind for attributes:
    • expressions: {{ signedUp ? 'Cancel' : 'Sign up' }},

    • filters: {{ slug | capitalize }}

    View Slide

  14. Vue Directives: v-*
    • v-if / v-else:
    {{ message }}
    • v-show:
    {{ message }}
    • v-for:
    {{ dog.name }}

    View Slide

  15. Vue Directives: v-* (continued)
    • v-on:event:
    Do stuff
    • modifiers:
    v-on:submit.prevent="onSubmit"
    • v-bind:class:

    View Slide

  16. Methods

    View Slide

  17. Methods
    Defining repeated behavior once, with a name.

    {{ showThing() }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>message: 'Hello World!'<br/>},<br/>methods: {<br/>showThing: function () { return `THING SHOWN: ${this.message}` }<br/>}<br/>})<br/>

    View Slide

  18. Methods (continued)
    ... also can be used anywhere an expression is accepted in Vue
    templates. So this:

    [+]
    {{ counter }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>counter: 0<br/>}<br/>})<br/>

    View Slide

  19. Methods (continued)
    ... can become this:

    [+]
    {{ counter }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>counter: 0<br/>},<br/>methods: {<br/>increment: function () { this.counter++ }<br/>}<br/>})<br/>

    View Slide

  20. Methods (continued)
    ... or this:

    [+]
    {{ counter }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>counter: 0<br/>},<br/>methods: {<br/>increment: function (amount) { this.counter += amount }<br/>}<br/>})<br/>

    View Slide

  21. Interlude: shortcuts
    Commonly used directives often have shortcuts.
    • v-on:click can be represented as @click
    click me
    • v-bind:href can be represented as :href

    View Slide

  22. The event object in methods

    Do it.

    <br/>new Vue({<br/>el: '#app',<br/>methods: {<br/>doIt: function (event) {<br/>console.log(event.target)<br/>}<br/>}<br/>})<br/>

    View Slide

  23. Computed properties

    View Slide

  24. Computed properties
    Like decorators with magical listeners built in. Any property based
    on the content of another.
    What's different between a method and a computed property?
    Methods run every they're re-requested; computed properties are
    cached based on their dependencies, and only change when their
    dependencies change.

    View Slide

  25. Computed properties (continued)

    {{ messageReversed }}

    <br/>new Vue({<br/>el: '#app',<br/>data: {<br/>message: 'Howdy!'<br/>},<br/>computed: {<br/>messageReversed: function () {<br/>return this.message.split('').reverse().join('')<br/>}<br/>}<br/>})<br/>
    // @todo better example

    View Slide

  26. Computed properties (continued)
    Are "get"-only by default, but can be both get and set:
    // ...
    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]
    }
    }
    }
    // ...
    // @todo make this real example

    View Slide

  27. Lifecycle hooks
    • Callback hooks on given events for each component
    • beforeCreate, created
    • beforeMounted, mounted
    • updated
    • destroyed

    View Slide

  28. View Slide

  29. Lifecycle hooks (continued)
    new Vue({
    el: '#app',
    data: {
    topics: []
    },
    mounted: function () {
    this.topics = ajaxMethodFromElsewheregettingTopics()
    }
    })

    View Slide

  30. A few caveats
    (with Vue's reactive model)
    • If you set props on a instance after it starts up, those props won't
    be reactive
    (vm.newProperty = 'please-track-me')
    • If you're setting a prop of an array/object, you have to use
    Vue.set in order for it to be tracked/reactive
    Vue.set(myArray, itemIndex, value)

    View Slide

  31. Vue Components

    View Slide

  32. Defining and using Vue components
    Each component is a little Vue instance. Defining a global component
    named "todo-item":
    Vue.component('todo-item', {
    props: ['todo'],
    template: '{{ todo.text }}'
    })



    View Slide

  33. Defining and using Vue components
    You can also define components locally:
    var TodoItem = {
    props: ['todo'],
    template: '{{ todo.text }}'
    }
    new Vue({
    // ...
    components: {
    'todo-item': TodoItem
    }
    })

    View Slide

  34. Vue component caveats
    • data property must be a method, not an object:
    Vue.component('whatever', {
    // ...
    data: function () {
    return {
    propName: true
    }
    }
    })
    • If your template is in HTML, you may have to use is="todo-item">

    View Slide

  35. Props, events, and sync

    View Slide

  36. Props, events, and sync
    Pass property from parent to child using props. Send changes from
    child to parent using custom events. "Props down, events up"

    View Slide

  37. Passing props into a component
    Pass data into a component as a "prop" on the component instance—
    sort of like a constructor property.

    Vue.component('banner', {
    props: ['message'],
    template: '{{ message }}'
    })

    View Slide

  38. Passing dynamic props
    If the data is pulled from data on the parent, it's "dynamic":



    View Slide

  39. Side note: variable casing
    CamelCase in the JavaScript, kebab-case in HTML.

    View Slide

  40. Emitting and listening to custom events
    Vue.component('terms-of-service', {
    template: 'Accept',
    methods: {
    accept: function () {
    this.$emit('accept-terms-of-service')
    }
    }
    })
    new Vue({
    el: '#app',
    methods: {
    acceptTOS: function () {
    // ...
    }
    }
    })



    View Slide

  41. Passing data with custom events
    Vue.component('terms-of-service', {
    template: 'Accept',
    methods: {
    accept: function () {
    this.$emit('accept-terms-of-service', {'somedata': 'here'})
    }
    }
    })
    new Vue({
    el: '#app',
    methods: {
    acceptTOS: function (data) {
    // ...
    }
    }
    })

    View Slide

  42. Using a new Vue instance as an event bus
    var bus = new Vue()
    // in component A's method
    bus.$emit('id-selected', 1)
    // in component B's created hook
    bus.$on('id-selected', function (id) {
    // ...
    })

    View Slide

  43. Sync
    It's old. Don't use it anymore.

    View Slide

  44. Slots

    View Slide

  45. Simple slot


    Title of child

    Fallback content here




    Title of parent

    This is some original content


    View Slide

  46. Named slot











    Here might be a page title
    A paragraph for the main content.

    View Slide

  47. Other ways to load Vue
    vue-cli
    Simple CLI tool for scaffolding Vue projects
    https://github.com/vuejs/vue-cli
    Default templates:
    - Webpack
    - Browserify
    - Simple HTML

    View Slide

  48. Not going to cover in depth:

    View Slide

  49. Routing
    Vue-Router: http://router.vuejs.org/
    https://github.com/mattstauffer/suggestive

    View Slide

  50. State management
    If event bus isn't good enough, check out Redux or Vuex
    https://vuex.vuejs.org/

    View Slide

  51. Testing
    Many options, but first recommendation is Karma.
    https://vuejs.org/v2/guide/unit-testing.html

    View Slide

  52. Prerendering
    For SEO, marketing, etc. you can build pages to HTML:
    https://github.com/chrisvfritz/prerender-spa-plugin

    View Slide

  53. Server side rendering
    Actual live SSR using vue-server-renderer
    https://vuejs.org/v2/guide/ssr.html

    View Slide

  54. Mixins
    Like mixins in Ruby or traits in PHP; bring in a group of properties.
    // define a mixin object
    var myMixin = {
    created: function () {
    this.hello()
    },
    methods: {
    hello: function () {
    console.log('hello from mixin!')
    }
    }
    }
    // define a component that uses this mixin
    var Component = Vue.extend({
    mixins: [myMixin]
    })
    var component = new Component() // -> "hello from mixin!"

    View Slide

  55. Single-file syntax (Vueify)
    // component.vue


    {{ message }}


    export default {
    data: {
    message: 'Hello World!'
    }
    }
    <br/>.my-component {<br/>color: lighten(#175023, 20%);<br/>}<br/>

    View Slide

  56. Conclusion

    View Slide