The Swiss Army knife of every Vue.js developer
Juan Andrés Núñez
Frontend Engineer
Content creator at
?
Composables
The Composable Pattern will help you build (more) Extensible, Adaptable, Controllable and Trustful Vue.js applications.
The Promise
A function that leverages Vue's Composition API to encapsulate and reuse stateful logic.
What
- Composition API
- Stateful logic (state)
- Reactivity
What
import { ref } from "vue"
// We always export a main function
export function useAlert() {
// Stateless: every instance holds its own state
const isVisible = ref(true)
// We craft our custom logic
const toggleVisibility = () => isVisible.value = !isVisible.value
// We expose what we want to consume
return {
isVisible,
toggleVisibility
}
}
What
- Convention is start with Use...
- Not the same as mixins
- You don't even need Vue 3
When
When
- State stores
- Controllers
- Reactive UI utils
- Any other creative use
Where
- Everywhere...
- Not only a UI concept
- Are omnipresent
- Local to a feature
- Global to a system
Why
The Composable Pattern will help you build (more) Extensible, Adaptable, Controllable and Trustful Vue.js applications.
Extensible: start small, grow with the project
- Stateless or stateful
import { ref } from "vue"
export function useAlert() {
// Stateless
const isVisible = ref(true)
...
}
import { ref } from "vue"
// Stateful
const isVisible = ref(true)
export function useAlert() {
...
}
Extensible: start small, grow with the project
- Options pattern
import { ref } from "vue"
const isVisible = ref(true)
// We expect an options object
export function useAlert(options) {
// We specify a default
const { isDanger = true, awaitResult = true } = options
...
}
Extensible: start small, grow with the project
- Composition
import { ref } from "vue"
import { useLocalStorage } from '@/composables'
const isVisible = ref(true)
export function useAlert() {
const { save, check, remove } = useLocalStorage({ key: 'my-app'})
...
}
Adaptable: fit in every app layer, work in every env.
- Domain / business logic
UseEvent
UseCalendar
UsePayment
- Native API's
UseDarkMode
UseIntersectionObserver
- Data modeling
UseFilter
UseUnique
UseReduce
Controllable: decide what to expose
- Explicit return
export function useAlert() {
const isVisible = ref(true)
const toggleVisibility = () => isVisible.value = !isVisible.value
return {
toggleVisibility
}
}
- Readonly properties
import { ref, readonly } from "vue"
export function useAlert() {
const isVisible = ref(true)
const toggleVisibility = () => isVisible.value = !isVisible.value
return {
isVisible: readonly(isVisible),
toggleVisibility
}
}
Controllable: decide what to expose
- Easy aliasing
import { useAlert } from '@/composables'
const { isVisible: isNotHidden, toggleVisibility } = useAlert()
export function useAlert() {
...
return {
isNotHidden:isVisible,
toggleVisibility
}
}
Controllable: decide what to expose
Trustful: easier to test, easier to maintain
import { useAlert } from '.'
describe('useAlert', () => {
it('has the initial state as visible', () => {
const { isVisible } = useAlert()
expect(isVisible.value).toBe(true)
})
it('toggleVisibility() mutates the state', () => {
const { isVisible, toggleVisibility } = useAlert()
toggleVisibility()
expect(isVisible.value).toBe(false)
})
})
How
How
- VueUse
- Build your own collection
Thank you 🙏
(See you in the workshop 🔥)
The Swiss Army knife of very Vue.js developer
By Juan Andrés Núñez
The Swiss Army knife of very Vue.js developer
- 21