Successfully reported this slideshow.

Vue.js 101

0

Share

1 of 54
1 of 54

Vue.js 101

0

Share

Download to read offline

Introduction to Vue.js. The first half consists of all slides, and the second half consists of all those slides along with detailed notes.

All the sample code can be found at https://github.com/MarkFreedman/VueJS101

Introduction to Vue.js. The first half consists of all slides, and the second half consists of all those slides along with detailed notes.

All the sample code can be found at https://github.com/MarkFreedman/VueJS101

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Vue.js 101

  1. 1. Vue.js 101 Will It Change Your Life? Dev Storyteller presents: Mark Freedman https://MarkFreedman.com @MarkFreedman
  2. 2. Vue.js 101 Who Am I to Speak About Vue.js?
  3. 3. Vue.js 101 Small Fast Easy Declarative Incrementally Adoptable
  4. 4. Vue.js 101 Preparing for Use vuejs.org
  5. 5. Vue.js 101 Canonical “Hello World” Example
  6. 6. Vue.js 101 Instantiation Main Wrapper Element Data Object Interpolation
  7. 7. Vue.js 101 Reacting to data changes
  8. 8. Vue.js 101 Methods
  9. 9. Vue.js 101 Vue Lifecycle
  10. 10. Vue.js 101 Rendering changes Virtual DOM
  11. 11. Vue.js 101 Events
  12. 12. Vue.js 101 Event Object Argument
  13. 13. Vue.js 101 Multiple Event Handler Arguments
  14. 14. Vue.js 101 Unidirectional Data Binding
  15. 15. Vue.js 101 Two-Way Data Binding
  16. 16. Vue.js 101 More Advanced Example
  17. 17. Vue.js 101 Components
  18. 18. Vue.js 101 List Processing v-for
  19. 19. Vue.js 101 Array Gotchas
  20. 20. Vue.js 101 Dynamic Classes :class
  21. 21. Vue.js 101 v-if v-show
  22. 22. Vue.js 101 Dynamic Styles :style
  23. 23. Vue.js 101 Custom Filters
  24. 24. Vue.js 101 Custom Components Props
  25. 25. Vue.js 101 Do we love Vue.js? Will it change your life?
  26. 26. Vue.js 101 Advanced Topics for Future Sessions?  Modifiers  Slots  Single File Components (.vue files)  Transitions and Animations  Custom Events  v-once  keep-alive  Mixins  Custom Directives  Plugins  vuex  vue-resource  vue-router
  27. 27. Vue.js 101 Learning Resources  Vue.js: https://vuejs.org/  Support Forum https://forum.vuejs.org/  Job Portal https://vuejobs.com/  My Favorite Tutorial https://www.udemy.com/vuejs-2-the-complete-guide/learn/v4/overview  awesome-vue: https://github.com/vuejs/awesome-vue  My Site: https://MarkFreedman.com  This Session’s Slides and Examples https://github.com/MarkFreedman/VueJS101
  28. 28. Vue.js 101 Will It Change Your Life? Dev Storyteller presents: Mark Freedman https://MarkFreedman.com @MarkFreedman You can find the sample code at: https://github.com/MarkFreedman/VueJS101 1
  29. 29. Vue.js 101 Who Am I to Speak About Vue.js? I’ve been developing web-based apps since the mid 90s, with heavy JavaScript development since 2011. Hated JavaScript until 2007 or so. Have loved it since. Never indifferent. I’ve been in software development for a few decades. 2
  30. 30. Vue.js 101 Small Fast Easy Declarative Incrementally Adoptable Small core library - 16kb gzipped and minimized Fast - many benchmarks show that Vue is faster than Angular 2/4 and React. Easy - easy to learn; easy to grow with. 3
  31. 31. Vue.js 101 Preparing for Use vuejs.org We can reference Vue.js in our apps either referencing a CDN (recommended), by downloading it, or by installing with NPM or Nuget, etc. We'll download for this session, to prevent against connectivity issues. The developer (non-minimized) version of the library will give us extra warning and error information. Although not required, we'll use some simple ES6 features today as well. 4
  32. 32. Vue.js 101 Canonical “Hello World” Example We’ll start with a very simple example. 5
  33. 33. Vue.js 101 Instantiation Main Wrapper Element Data Object Interpolation (vue1.html) We need to create a Vue instance in JavaScript. I’ll start simple by including the JavaScript in the HTML file. An options object is passed to the instantiation. We’ll first focus on these properties of this object: el – Here, using CSS selectors, we specify the root “wrapper” element Vue will control. data – This is an object where we define variables that Vue will “react” upon. We would initialize each data item with default values here as well.  Vue uses “templates” to generate HTML. Although it may appear the HTML would be displayed as-is, everything inside the el element is first "compiled" before it is displayed to the DOM. In our HTML, we assign an id of “app” to the main DIV element. We could have used a CSS class here, or even just an element without a class or id. The main thing to keep in mind is that the el value passed to the Vue instance should hold the selector. If multiple elements for the same selector are on the page, the first instance will be used by Vue. This is why 99.9% of the time we use an id. Vue controls everything inside this root element. It renders output, and reacts to events on this and all child elements. We’re using string interpolation to allow Vue to render our title. We use curly braces (or mustaches) – {{ }} – around an expression, similar to Angular string interpolation. Any simple JavaScript expression can be placed here. In other words, literals, variables, operations, and anything that isn’t a JavaScript statement, for the most part. Here, we are passing title, which Vue automatically searches for in the data property in the options object. If we used quotes around title, the literal “title” would be rendered. But because we used it as a variable, the current value assigned to that variable is rendered. Vue automatically protects against unintended XSS. For example, interpolating a URL to any HTML element will encode the URL. HTML will be treated as literal text. If we do need to render HTML, we would use the v-html directive instead of rendering with mustaches. 6
  34. 34. Vue.js 101 Reacting to data changes (vue2.html) Since Vue is “reactive” (no pun intended for React users), it listens for changes to the data properties to decide if and when to re-render. If we go to the Developer Tools, we can change the value of the data in the console, and Vue will re-render any place on the page that data was rendered before. How do we do that? How do we reference title from the console? Well, since we instantiated Vue without assigning the reference to a variable, we don’t have a direct way of doing so. So lets make a minor change to the JavaScript first, and assign the instance to a variable called “myApp”. After refreshing the page, now we can go to the console and type myApp.title = “My New Title”. It effectively changes the displayed title. What’s wrong with this picture? This shouldn’t have worked, right? There’s no title property in the Vue prototype, right? Well, this is some Vue “magic.” Vue automagically surfaces the data property to the top level of the instance for easy access. We’ll see more of this now… 7
  35. 35. Vue.js 101 Methods (vue3.html) Vue wouldn’t be very useful if we couldn’t throw logic around our components. The “methods” property of the options object is where we declare any methods we want Vue to use. You can consider these methods as members of a controller of the component. Let’s create a method called getTitle (using ES6 syntax), and instead of rendering title directly in the template, let’s use a call to getTitle(). Note that in JavaScript we’re using “this” to reference the method. Like data properties, Vue surfaces methods as well. Like “myApp” from outside the Vue instance, we would use “this” from inside the instance. If we look at the console, we can confirm that the method was called by the Vue rendering engine. How did we do that? 8
  36. 36. Vue.js 101 Vue Lifecycle (vue3.html) Vue wouldn’t be very useful if we couldn’t throw logic around our components. The “methods” property of the options object is where we declare any methods we want Vue to use. You can consider these methods as members of a controller of the component. Let’s create a method called getTitle (using ES6 syntax), and instead of rendering title directly in the template, let’s use a call to getTitle(). Note that in JavaScript we’re using “this” to reference the method. Like data properties, Vue surfaces methods as well. Like “myApp” from outside the Vue instance, we would use “this” from inside the instance. If we look at the console, we can confirm that the method was called by the Vue rendering engine. How did we do that? We hooked into the Vue lifecycle. Let’s take a look at the lifecycle diagram. Deep diving into this is more of an advanced feature, but we’ll just discuss a commonly used hook – created. This is automatically called when the component has been initialized and the DOM has been updated. We add our lifecycle hook functions to the options object. In this case, we’ll define a created function. All we’re doing here is displaying a message in the console for debugging purposes. 9
  37. 37. Vue.js 101 Rendering changes Virtual DOM As we have just seen, Vue immediately rendered the changed title to the page. But what if we had dozens of DOM elements on our page? Isn’t updating the DOM inherently slow? Yes it is, but like React, Vue actually updates an internal “virtual” DOM before making any physical changes to the rendered output. Once all updates are made to the virtual DOM, Vue then does a comparison of the virtual DOM to the actual DOM, and only updates the differences. Now that we got our introduction to methods, let’s take a look at event handling in Vue… 10
  38. 38. Vue.js 101 Events (vue4.html) You should feel comfortable with Vue built-in directives if you’re already familiar with Angular’s. The first one we’ll look at is the v-on directive. Vue built-in directives are prefixed with “v-”. The v-on directive is used for handling events on the element the directive is placed into. Let’s allow the user to change the title by clicking a button. We’re back to the version where we’re rendering the title data item. We’ll create a method called changeTitle(), which will simply change the value of title to another hard-coded value. Then we’ll add a button to the HTML, and add a v-on directive. Directives such as v-on accept parameters which follow the directive name and preceded by a colon. v-on always requires an event name (standard JavaScript event names), so we’re going to use v-on:click here. We’ll specify “changeTitle” as the value for the v- on directive. A parenthesis after the name is not required. Running the app, we can see that clicking the button changes the title. By the way, we didn’t need to create a method for this. Like with interpolation, we only need a valid JavaScript expression. We could have simply specified the handler like this: v-on:click=“title = ‘I changed this title’”, which does the same thing. Note that we did not have to prefix the method, nor the data item with “this” in the HTML. Vue recognizes its directives and interpolation statements, and understands any expression references items on the Vue instance. Since in the methods we can access any variable in scope, we must prefix a Vue item with “this” to clarify that we’re referencing a Vue data object’s variable. Because v-on is such a common directive in Vue, there’s a shorthand notation that I’ll use all the time going forward. Instead of typing v-on: before the event name, just type @ followed by the event name. In this example, it would be @click. 11
  39. 39. Vue.js 101 Event Object Argument (vue5.html) Vue always passes a DOM event object to the event handler if you specify no parameters for the function specified in the v-on directive. Just like any other event handler in JavaScript, jQuery, etc., it contains appropriate properties based upon the event. Let’s look at a simple example. We’ll add another event handler to our button for mouseover. Again, we don’t need to pass a parameter (or even parenthesis), because Vue automatically passes an appropriate event object to the handler. We’ll call it event but it could be called anything you like. Note that we’re using the @ shorthand. We’ll create another interpolated string for displaying the mouse coordinates. We’ll have to add another data item to hold the value, so we’ll initialize it to an empty string. In the event handler, we’ll simply use the x and y coordinates passed via the event object to our mouseover handler, onMouseOver. This is cool, but what if we want to pass other values to the event handler? What happens to the event object argument? It disappears. But don’t worry – we can get it back… 12
  40. 40. Vue.js 101 Multiple Event Handler Arguments (vue6.html) Let’s create a second button, where we can set a different title. This time we’ll pass an argument containing the new title. But in addition to changing the title, we want to pop up an alert displaying which button we clicked. Since we’re using the same event handler to handle both buttons, how are we going to know? Well, in our v-on (or @) directive, we also pass in a built-in Vue variable called $event. Built-in variables start with $ in Vue. So now our event handler will accept two parameters; the user-defined parameter we created, and the $event parameter because we’re overriding the default Vue behavior. 13
  41. 41. Vue.js 101 Unidirectional Data Binding (vue7.html) Instead of using a couple of buttons for pre-canned titles, let’s try an example where we want to accept input from the user in order to change the title. We’re using an input field with a new directive, v-bind, in order to initialize the value of the input field to the title data property. v-bind is always followed by a colon, and then the HTML attribute to bind to a data property. In this case, because we’re using v-bind:value=“title”, Vue will compile the template, binding the value held in the title data property to the value attribute. If we didn’t precede the value attribute with v-bind:, the literal, “title”, would be displayed instead. Don’t use the mustache syntax in the v-bind value. Vue already knows it’s an expression and not a literal. In order to capture our input and update the title on the page, we’ll need to tell Vue to react to the change of the input. Like we learned earlier, we simply add the @change directive (in other words, v-on:change) to handle the change to the input. We’ll create an onChange handler method to update the title on the page. This is great, but it’s so common Vue has a shortcut two-way binding option for this behavior… 14
  42. 42. Vue.js 101 Two-Way Data Binding (vue8.html) Sometimes two-way binding is considered a “bad” thing (see AngularJS 1.x). But it’s fine in Vue, because it’s only valid within the same component. You’ll still be using one-way data flow between components. Let’s change the prior example to use two-way binding instead of event handling. Similar to Angular, all you need is to use the v-model directive to wire up two-way binding. By specifying a property in the data object, Vue will automatically link up both the input and output. Let’s update the input text field from the prior example. Now, by replacing the v-bind directive with v-model, and setting it to “title”, we’re now binding the input field to the displayed and styled title. (vue9.html) When we run the page and modify the text field, we see the displayed title updated in real time. By default, this binding is on key press. If you want to retain the old way of only reacting on the loss of focus, we can add a modifier to the v-model directive: v- model.lazy. There are several built-in modifiers for Vue directives. The .lazy modifier changes the behavior of the event handling to the change event instead of the keypress event. 15
  43. 43. Vue.js 101 More Advanced Example (music-playlist-builder-1) At this point, we’ll look at a more involved application to learn some more interesting features. We’ll create an index.html file as the entry point for our site. We’ll also create subdirectories for CSS, JavaScript, and assets (an input file, in our example). We’ll be making use of Bootstrap to style our app. We’ll also add another CSS file with a few simple styles. We’ll also break our application into multiple JavaScript files, since we’re going to start using custom components, and keeping them separate from each other makes everything a lot cleaner. In a larger application, we’d make use of what is called “Single File Components,” which is more of a standard way of creating independent components in .vue files. But this is a more intermediate topic which we may not have time to cover in this intro. Let’s take a look at our root JavaScript file, main.js. Like we did in our other examples, this is where we instantiate our main Vue object. We’re also making use of a Vue plugin called vue-resource. This is a “promise” library we’ll be using to load a data file from the server. In Vue, in order to use plugins, we load them via the Vue.use function. Of course, don’t forget to include the JavaScript file when making use of plugins. We won’t cover this plugin in detail, as it’s beyond the focus of this session. 16
  44. 44. Vue.js 101 Components We’ll dive into this more in a bit, but let’s take another look at the index.html file. Note that in the root Vue element (id=“app”) we have an element called <app>. There is nothing significant about this name, except for the fact that you’ll notice it’s not a standard HTML element. It’s actually a custom Vue element. Let’s look at the app.js file. This file consists of a single JavaScript statement; a call to Vue.component. This is how we use JavaScript to create a custom component that we can place anywhere in our HTML nested somewhere within the element we map to Vue via the el property. The component function takes two parameters. The first parameter is the name of the component. If you are familiar with Angular, Vue also automatically converts camelCase references in JavaScript to kebab-case when used in HTML. Although it doesn’t matter here, since we’re just calling this component “app,” if we called it something like “myApp,” in the HTML, we’d call it <my-app>. The second parameter contains an option object, just like we pass when creating the main Vue instance. Let’s go through each property in this object. The template property contains the HTML rendered when Vue finds the component on a page. Remember, like I mentioned earlier, this isn’t really HTML, but is an HTML template that Vue “compiles” and renders in the virtual DOM before inserting into the actual DOM, because it still has to go through all the other Vue directives and string interpolation. The data property is very similar to the data property for the main Vue instance, with one significant difference – in components, we need to return the data object, so every property is wrapped in a return statement. All the data properties here are instance properties of the component. In other words, if you have multiple instances of this element through your web page, each will get its own copy of the data properties. Likewise, all these properties are local to the component instance. The methods property works the same as for the main Vue instance, except that the methods defined here are local to the component. We also have a created method for displaying a message to the console when the object is instantiated. 17
  45. 45. Vue.js 101 List Processing v-for Often, we need to generate multiple instances of HTML elements when building lists or other repeatable patterns. In Vue, we use the v-for directive. Let’s take a look at the app component again. We’re creating a music playlist builder, so we’ll obviously be rendering lists of songs. Take a look at the first <li> element. We’re using a v-for directive to loop through the tracks array we declared in the data property of our options object. When we want to loop through an array, the first parameter of the v-for statement is often the array item, followed by the in keyword and then the array name. But if we want to get access to the array index and use it within the loop, the first parameter is a pair of variables – the item followed by the index. For this, we will need the index at a later point, so we’re specifying it here. Let’s run the app. I’m using a Visual Studio Code plugin that quickly spins up a server for us. We’ll need to run this page in a server because of XSS restrictions on loading data. Note that there is no list displayed, because we don’t have any data yet. We rendered a button for loading tracks from an external source. In case we don’t have good Internet connectivity, I created a local JSON file in the assets folder. I got this data from the last.fm site. They have useful APIs if you’re a music fan. This is an intro course, so I’m not going to get too much into the promise library call we’re making to load the data, but let’s look at the button in the template. In addition to the hard-coded classes, we have the familiar @click directive to specify our event handler (loadAllTracks) for the click event. The most important line to look at is where we’re assigning the result to tracks array. When this happens, since tracks is a Vue data property, Vue will automatically react to it changing. Vue renders the change in the virtual DOM, and then compares the virtual DOM to the actual DOM. The only difference it will find is to the <li> items in our v-for list, so only that part of the DOM will be updated, and the rest of the DOM will remain untouched. Let’s click the button to make this happen, and then let’s inspect using the Developer Tools. Note that Vue rendered multiple <li> elements due to the v-for loop we created in our template. 18
  46. 46. Vue.js 101 Array Gotchas I need to take a moment to explain an idiosyncrasy of Vue. If we change an existing element in an array, Vue will NOT see and react to that change. It has no problem when adding or removing items from an array, but not when modifying an existing element. Vue does provide a built-in function for setting the value of an element that it will react to: arr. $set(index, value). This is simply syntactic sugar for arr.splice(index, 1, value), which removes, then re-adds an element, basically tricking Vue into seeing the change. 19
  47. 47. Vue.js 101 Dynamic Classes :class Let’s take a closer look at the first <li> template declaration. In addition to the hard-coded class of Bootstrap’s list-group-item, there is the :class declaration (a colon (:) being a shortcut for v-bind: since it’s used so often). This is where we can dynamically specify classes based upon expressions. In this case, we’re setting the class based on the value of track.class. The class parameter is not part of the downloaded track data, but we add it on the @click event. Let’s take a look at the handler for the @click event, addTrack(). We’re passing three of our own parameters to the handler, along explicitly with the $event object, as discussed earlier. We can see here why we are capturing the index in our v-for loop. We need the index in order to know which element we just clicked so we can mark it as selected. We’re also passing in the artist name and track title in order to add an item to the selectedTracks array used in the second defined <li> element. Yes, we could have passed in track[index] to save on a parameter as well. We’re also using the class property of the track as a flag to see if the track has already been selected. In addition to pushing the track to the selectedTracks array, we’re setting the class to “active”, which allows Bootstrap to highlight the selected track via the :class binding attribute. We’re also setting a modified flag that we’re making use of in a couple of other attributes in our template that we’re about to learn about. A bit more on the class binding attribute first, though. We are using it to bind to a string value to explicitly set the class. First, note that any classes specified here is in addition to any hard-coded classes added to the class attribute. Second, we can also pass in an object containing a collection of class/value pairs. We could have used :class="{ active: isActive }” instead, and if isActive is set to true, the “active” class would be applied. This is an especially useful option if we were dynamically manipulating multiple classes on an element. Let’s now look at how the modified flag is being used… 20
  48. 48. Vue.js 101 v-if v-show Often, we need to conditionally create or display a DOM element. Vue gives us a couple of helpful directives for this: v-if (and the corresponding v-else) and v-show. We’re using the modified flag to decide whether or not to display an asterisk above the selected tracks list indicating a “dirty” flag (unsaved changes were made to the list). In this situation, the element is always created in the DOM, but v-show simply decides on whether or not the element will be displayed. Effectively, it is setting the display style to “none” or “default”. We’re making use of v-if to decide whether or not to even render the “Save Playlist” button at all. When would you use one over the other? A good rule of thumb is to use v-show if the element display will often be toggled, but use v-if the rendering of the element is not likely to change during the session. v-if also has corresponding v-else and v-else-if directives, which must immediately follow the v-if, and are pretty self-explanatory. 21
  49. 49. Vue.js 101 Dynamic Styles :style Note that we’re also making use of the :style directive to modify the style of the page title based on the modified state of the data. As with the alternative syntax for :class, we pass in an object containing a collection of style/value pairs. We make use of the camelCase version of style names, which Vue converts to the standard kebab-style format when rendering the elements to the DOM. If we wrapped the style in quotes, we could have used ‘background-color’ instead of backgroundColor. For both :class and :style, we could use arrays of classes and styles, respectively, as well. Vue will also create style prefixes for each browser type from the styles you specify dynamically. 22
  50. 50. Vue.js 101 Custom Filters (music-playlist-builder-2) Like Angular, Vue supports filters when rendering. The difference is, there are no built-in filters in Vue. But they are simple to build. I know this example is derivative, but let’s build a filter that transforms the artist name before displaying it in the list. Our filter will wrap the first character of the name with brackets. Filters can be used in mustache interpolation and in v-bind expressions, and can be piped through other filters. 23
  51. 51. Vue.js 101 Custom Components Props (music-playlist-builder-3) Right now, we have a single component containing our entire template. In a larger application, we’d break this down into separate components. There are some key benefits: 1) it makes it a lot cleaner, 2) it encapsulates everything pertaining to a specific portion of the template, and 3) it allows for easy reuse. Let’s create and use a separate component for the Save button and the related modified indicator. We’ll create a new JavaScript file called save-tracks.js. Don’t forget to add the JavaScript file reference to index.html. Within the component, we’ll have the normal options object that defines the template and supporting data and methods. We’ll name the component “saveTracks.” Remember that Vue will treat this as “save-tracks” when used in a template. We can also move the supporting savePlaylist() function to this component, since it’s just there to support the functionality of this component. But how do we pass the modified state to this component, since the flag is based on data properties of the parent component, app? We make use of another option object property called props. This is an array of string values representing attributes passed to the component. The component looks for an expression assigned to that attribute, and applies it to an internal variable by that name (in this case, modified). We can now replace the <h2> and <button> elements in the main app component with this new <save-tracks> elements. Note that we’re binding the attribute modified (because it’s preceded by a colon or v-bind:) to an expression. The component captures the result and places it into the modified prop, where we can use it to control logic in the component and template. This is one-way data flow. Although we won’t cover it today, in order to communicate back to the parent or other sibling components, we’d raise custom events from the child component to keep the components loosely coupled. Also, note that components cannot be composed out of multiple elements at the root level. There must always be a container element. We can simply use a <div> in many cases, but we don’t need to here, because the <h2> element is our container for this component. 24
  52. 52. Vue.js 101 Do we love Vue.js? Will it change your life? Next steps. 25
  53. 53. Vue.js 101 Advanced Topics for Future Sessions?  Modifiers  Slots  Single File Components (.vue files)  Transitions and Animations  Custom Events  v-once  keep-alive  Mixins  Custom Directives  Plugins  vuex  vue-resource  vue-router Modifiers: dot-separated values to pass to event name. A common one is "stop" for stopPropagation. Also have "prevent" for preventDefault. Modifiers can be chained. Key modifiers for keyboard events. For example .enter for checking if the enter key was pressed. Computed properties are just referenced as pointers. The difference between computed and methods is methods always are re-evaluated. Computed are only re-evaluated if any data it contains has changed. More efficient. Could use "watch" object instead of "computed." Computed is more optimized, though. The watch properties need to be named the same as the data being watched for changes. Computed methods are run synchronously. So use watch when you need to check for changed properties asynchronously. For example, setTimeout or setInterval functions. When specifying callback functions in watch methods, we lose direct access to "this," so first assign "this" to a variable (normally called "vm") before defining the callback. Then you can reference this variable (vm) inside the closure. You can also take advantage of <template> to repeat multiple elements: v-for="value in valueObjects" or v- for="(value, key) in valueObjects". You can even access the index : v-for="(value, key, index) in valueObjects" You can also loop through numbers: v=for="n in 100" You can use the :key binding option to track and specify the key in an array or collection of objects, so if either changes, Vue keeps track of the position and value change, and will update the UI appropriately. Installing the Vue CLI npm install -g vue-cli vue init web pack-simple projectName cd projectName npm install npm run dev 26
  54. 54. Vue.js 101 Learning Resources  Vue.js: https://vuejs.org/  Support Forum https://forum.vuejs.org/  Job Portal https://vuejobs.com/  My Favorite Tutorial https://www.udemy.com/vuejs-2-the-complete-guide/learn/v4/overview  awesome-vue: https://github.com/vuejs/awesome-vue  My Site: https://MarkFreedman.com  This Session’s Slides and Examples https://github.com/MarkFreedman/VueJS101 27

×