2. Daniel Jimenez Garcia
● Tech Lead at Oliver Wyman Digital
● Technology enthusiast interested in all aspects of SW
● Regularly publishes on the DotNetCurry magazine
● Contact me at @Dani_djg
#JSDayIE2019
20th September 2019
Dublin, Ireland
● OSS contributor: sinon-mongo, mockgo, node-apn, vue-
autowire, vue-cli-plugin-jest-puppeteer
3. Back in early 2017…
● Existing web stack using Knockout.js
● Dozens of new projects started every year
#JSDayIE2019
20th September 2019
Dublin, Ireland
● New web stack should strike a balance between
simplicity and flexibility
● Get up to speed quickly…
● …but support the more complex projects
● Wide range of project complexity
5. Begin with the Vue CLI
#JSDayIE2019
20th September 2019
Dublin, Ireland
6. Think in Components
● Each component is a reusable
element containing a template,
behaviour and data
● The application is structured into a
tree of components
● Routes establish relation between
URLs and component trees
#JSDayIE2019
20th September 2019
Dublin, Ireland
7. Fundamental Libraries
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Routing: vue-router
● HTTP client: axios
● Data management: vuex
● UI libraries: vuetify (material design),
bootstrap-vue (bootstrap4), buefy
(bulma)
● Testing: @vue/test-utils, mocha-
webpack, jest
8. Fundamental Tools
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Vue CLI
● Visual Studio Code with the Vetur
extension
● eslint with Vue presets. Consider prettier
● webpack and babel
● DevTools for Chrome
● codesandbox.io for quick experiments
10. Component’s Data is Reactive
#JSDayIE2019
20th September 2019
Dublin, Ireland
11. Standard Data Flow
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Component at the root of the reactivity
chain owns the data
● Data is passed down to child
component using props
● Owner component can directly modify
the data
● Child component emits event for root
to modify the data
12. Gotchas and Limitations
#JSDayIE2019
20th September 2019
Dublin, Ireland
Reactivity works through getter/setters
added to component data
● Only component data will be reactive
● Need to update/remove array items by
reassigning the root array property or
using splice
● Need to reassign objects when adding
new properties to them
Reactivity chains can get very long!
● Need to pass down data as props
through multiple nested components
● Need to propagate events up
● It’s hard to keep the discipline of
emitting events…
● … but it’s even harder to debug changes
made directly by child components!
13. Vuex (1)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Single source of truth for data, the store:
● The store state contains the data,
which is reactive
● Components who need access to the
data, map the store state
● Components who change data
dispatch actions
● Actions commit mutations, the only
ones allowed to change the store state
14. Vuex (2)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Actions:
● Can return promises so other actions and
components known when its done
● Can dispatch other actions
Breakdown large store into modules:
● Independent state, actions, mutations
● Can access state, actions, mutations from
other modules
● Can be dynamically registered/de-registered
15. Vuex Tips
#JSDayIE2019
20th September 2019
Dublin, Ireland
● You don’t have to use Vuex for everything
● Remember that store state follows the
reactivity rules.
● Avoid modifying store state outside
mutations
● Consider using constants for actions and
mutations names to avoid magic strings
● Declare state using a function for modules
dynamically registered
16. Global Events
#JSDayIE2019
20th September 2019
Dublin, Ireland
Some interactions won’t fit well within the
standard/Vuex data flows
● Examples: open a modal, display a
notification, toggle the sidebar, …
● Define event names with an object map
● Roll your own using a Vue instance as
event bus and calling $on/$off during
lifecycle hooks…
● …or use a library like vue-events
18. Advanced Components (1)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Dynamic components let you dynamically
decide and change which component to
render
● The name is specified with the :is
special attribute
● Options can be passed normally
19. Advanced Components (2)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Async components let you register
components that aren’t resolved until
needed
● They are resolved asynchronously,
taking advantage of Webpack code-
splitting
● Wepback creates a separate chunk for
the component and its dependencies
● They can be used as route components
20. Advanced Components (3)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Functional components have no instance
nor data, thus are very fast to render
● Necessary data provided as props
● They can emit events
● They can have slots
● They cannot have computeds nor
watchers, but they can have methods
21. More than just Components
#JSDayIE2019
20th September 2019
Dublin, Ireland
Filters define functions used to format data
● Widely used for i18n
● Define expressive filters for rendering
units like distances, areas, heights, etc
Directives can be used to perform low-level
DOM handling
● Positioning content
● Conditional content rendering
● Adding overlays
● Lazy loading images
Mixins define reusable component options
like props, computeds or methods
● They can be as big or small as required
● Let you add functionality to
components without extending
Plugins encapsulate into a single package
any number of elements: components,
directives, filters and mixins
● The Vue API lets you add a plugin to
your application in one line
22. Component Tips
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Define and initialize data using a function
● Avoid constants as reactive data
● Avoid arrow functions when defining
computeds, methods, etc
● Learn when to use the component lifecycle
hooks, like created vs mounted
● Prefer small reusable elements, components
and mixins over component extension
23. Component Gotchas
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Components can only have a single root node
● Templates are not inherited when extending
● All computeds are run on creation. Watchers
aren't unless setting the immediate flag
● Components are reused by default with route
changes unless a :key is used within the
router-view
● Functional components are rendered every time
their parent renders. Use as leaf components
24. My component smells when…
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Uses watchers. Limited to side-effects outside
reactivity/Vuex rules (HTTP , browser APIs, …)
● Uses Vue.set to update parent data
● Uses $refs to access child component
instances. Limit it to DOM elements or
consider directives
● Uses Vue.nextTick(). Limit to very specific
cases requiring you to wait for DOM updates.
● Uses $emit to modify data mapped from Vuex
25. Be Production Ready (1)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Consider I18n from the beginning:
● Vue i18n provides translation and formatting
● Lazy load translation files
Add specific route(s) and page(s) for HTTP error
codes
Know about runtime errors:
● Combine window.onerror with Vue API for error
handling Vue.config.errorHandler
● At least include in error reports. Consider sending
to collection service
26. Be Production Ready (2)
#JSDayIE2019
20th September 2019
Dublin, Ireland
Take advantage of Axios interceptors:
● Send CSRF tokens on every request
● Automatically refresh expired JWT tokens
● Default handling of HTTP error codes
Use router guards and routes metadata
● Navigate to login when not authenticated
● Navigate to 403 when not authorized
● Provide loading feedback
● Registering/de-registering Vuex modules
27. Know your bundles
#JSDayIE2019
20th September 2019
Dublin, Ireland
● Use webpack-bundle-analyzer to
understand your bundles
● Use code-splitting and async
components
● Use named imports with ES modules
and webpack’s tree-shaking
● Avoid including full libraries like lodash
or moment. Solution varies per library,
like using lodash-es
28. Organize Large Projects
#JSDayIE2019
20th September 2019
Dublin, Ireland
Establish file and folder conventions:
● Structure files in vertical slices of functionality
rather than by type
● Kebab case file names
● Clearly identify file purpose with suffixes like
page, async or local
● Enforce and avoid plumbing using
require.context or a library like vue-autowire
/src
/global
/components
navbar.vue
footer.vue
/directives
...
/home
home.page.vue
/todos
todos.page.async.vue
todo-list.vue
add-todo.vue
todo.store.js
todo.router.js
app.vue
main.js
router.js
store.js
29. If you had to remember 3 things...
@Dani_djg #JSDayIE2019
20th September 2019
Dublin, Ireland
● Reactivity chain
● Vuex
● Use the right tool, it’s not just
components
Credit to my colleague Conor for suggesting the slide!