How I learned to stop worrying and love components

By @pepf

Dr Strangelove or How I Learned to Stop Worrying and Love the Bomb (1964) still

face

About me

Pepijn Fens (@pepf)

UX Designer & Frontend dev

1

What got me worried?

2

How did we solve it?

3

Why everything is ok now

Current frontend structure

Codebase over time

delete_forever Clean slate

Maybe we should just start from scratch?

sentiment_dissatisfied More questions

  • React, Vue, Angular?
  • Maintaining multiple codebases?
  • Rethinking the tooling we use
  • What about browser support?
  • How do we make sure we don't end up with this complexity again?

extension Components

To make sure we won't mess it up again

Atoms

Basic building blocks of matter

Molecules

Atoms bonded together to form functional pieces

Organisms

Distinct part of the application with it's own behaviour

Atoms

Basic building blocks, not really useful on their own

Molecules

Functional piece made from atoms

Organisms

A clear & unique functional part of the application

Vue

Or, how to put this theory into practice

Vue

Component based frontend library

"Best bits of angular and react combined"

Render logic

Vue

React

if (bigbutton) {
	return ();
}
					

Transitions

Vue


	

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s
}
.fade-enter, .fade-leave-active {
  opacity: 0
}
				

Class and style binding


						
					

data: {
	classes: {
		active: true,
		primary: false
	}
}
					

Events

Default events


Custom events



Component <specialButton> JS .... Internal state Methods HTML <button :class=”classes” @click=”doThings”> {{ buttonText }}</button> CSS Or LESS / SASS / SCSS Props Events Component <specialForm> <specialButton buttonText="Click here"></specialButton>

restore_pageApplication state

How do all these components work together?

Vuex

Smart

  • Rely on global state
  • "Wrapper" components

Dumb

  • Don't rely on global state
  • "Visual" components

Interaction with components

Store (application state) { posts: [ ..., ...], user: { name: ‘sdfasd’, id: 1, avatar: ‘img/awesome.jpg’ }} UserInfo Avatar Post PostList Post Post

Connecting to the state


export default {
	name: 'UserInfo',
	store,
	getters: {
		user: state => { return state.user }
	},
	methods: {
		onClick () {
			this.$store.dispatch('logout')
		}
	}
}
						

const store = new Vuex.Store({
  // All application data
  state: {
    user: {id:1, name: "henk", avatar: 'me.jpg'},
    posts: []
  },
  // Called from the store
  mutations: {
    logoutMutation (state) {
      state.user = {}
    }
  },
  // Called from the component
  actions: {
    logout (context) {
      context.commit('logoutMutation')
    }
  }
})
					

Something about webpack & babel

hot_tub Advantages

Or, how components make your life easier

view_module

Reusability

Ensures consistent look&feel and prevents double code

textsms

Semantics

Common language to talk about components with techs and non-techs alike

all_inclusive

Maintainability

Enforce coding style that allows unit testing and iterative development


import myButton from 'myButton'
var Button = Vue.extend(myButton)

describe('myButton component', function () {
	it('should set the proper class', () => {
		// 1. Create the component
		var vm = new Button({
			propsData: {
				type: 'bigbutton'
			}
		}).$mount()

		// 2. Run your tests (Chai.js notation)
		const buttonEl = vm.$el.querySelector('button')
		expect(buttonEl).to.be.true
		expect(buttonEl.className).to.contain('bigbutton')

		// 3. Destroy the component
		vm.$destroy();
	})
})
						

Further reading

Thanks for listening!

help_outline

Questions?