Breakpoints reactivity with Tailwind and VueJS
Tags: vue, tailwindcss, javascript, discuss
Published: 2019-05-14 16:07:17

# Hello VUEJS lovers ! ❤️

## TL:TR

Before [Tailwind](http://tailwindcss.com) I used [Vuetify](http://vuetifyjs.com). 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...

```jsx
<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](https://vuejs.org/v2/guide/plugins.html). 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.

```js
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...

```jsx
<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!

```jsx
<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](https://twitter.com/giraud_florent)
my linkedin: [https://www.linkedin.com/in/fgiraud42/](https://www.linkedin.com/in/fgiraud42/)