Hello VUEJS lovers ! ❤️
TL:TR
Before Tailwind I used Vuetify. Vuetify is an incredible css framework!
But 🤔
I faced some issues with Vuetify:
- "Forced" to use Vuetify components
- Making changes in some cases could become really difficult....
Since then, I've discovered Tailwind!
Tailwind is what we call a "Css utility" which allows us to have much more modularity.
With that being said.
What I liked and didn't find with Tailwind are the Breakpoints Reactivity connected to VueJS. It let you change css classes dynamically or styles etc...
<template>
<div :class="{classCustom: breakpoints.xs}" ></div>
</template>
So I decided to do it myself.
Let's go connect Tailwind breakpoints reactivity with VueJS 😇
First, I was inspired by what Vuetify was doing, as integrate the breakpoints logic via Plugins. It is handy since it adds some "globals property" => The Breakpoints.
Yeah but it's "global". I don't like this aspect of globals, that mean you have to take that and ok... If I don't want them inside my component and save amount of code after transpilation.
On top of that, the customisation of the properties name etc are almost impossible.
So I decided to take advantage of the Vue Observable.
import Vue from 'vue'
const screens = {
sm: 640,
md: 768,
lg: 1024,
xl: 1280
}
const sm = val => val >= screens.sm && val <= screens.md
const md = val => val >= screens.md && val <= screens.lg
const lg = val => val >= screens.lg && val <= screens.xl
const xl = val => val >= screens.xl
const getBreakpoint = w => {
if (sm(w)) return 'sm'
else if (md(w)) return 'md'
else if (lg(w)) return 'lg'
else if (xl(w)) return 'xl'
else return 'all'
}
const debounce = function(func, wait) {
var timeout
return () => {
const later = function() {
timeout = null
}
const callNow = !timeout
clearTimeout(timeout)
timeout = setTimeout(later, wait)
if (callNow) func()
}
}
const breakpoints = Vue.observable({
w: window.innerWidth,
h: window.innerHeight,
is: getBreakpoint(window.innerWidth)
})
window.addEventListener(
'resize',
debounce(() => {
breakpoints.w = window.innerWidth
breakpoints.h = window.innerHeight
breakpoints.is = getBreakpoint(window.innerWidth)
}, 200),
false
)
export default breakpoints
And you can now use them just simply like this...
<template>
<div>{{ breakpoints.is }} {{ breakpoints.w }} {{ breakpoints.h }} </div>
</template>
<script>
import breakpoints from '@/plugins/breakpoints'
export default {
name: 'Component',
data: () => {
return {
breakpoints
}
}
}
</script>
And That's it! Since we are using Vue.observable, vue will automatically put those data reactive.
ps: It work's well with functional components!
<script>
import breakpoints from '@/plugins/breakpoints.js'
export default {
name: 'TitleXL',
functional: true,
props: {
text: {
type: String,
default: ''
}
},
render: (h, { data, props }) => {
const textW = breakpoints.mdAndUp ? 'text-5xl' : 'text-3xl'
return (
<div class={textW} {...data}>
{props.text}
</div>
)
}
}
</script>
Now you don't get data where you don't need it to be anymore ❤️
As you know, any code can be improved. If you have any suggestion,
Feel free to contact me or let a comment or just like the article :)
my twitter: https://twitter.com/giraud_florent
my linkedin: https://www.linkedin.com/in/fgiraud42/