Vue
HTML
<div id="app">
<div class="wrapper">
<div class="container">
<div class="header">
<h2>Resize your window to see changes</h2>
<h3>Vuetify breakpoints</h3>
</div>
<div class="content">
<div class="item">
<div>Height:</div>
<div class="value">{{windowHeight}}</div>
</div>
<div class="item">
<div>Width:</div>
<div class="value">{{windowWidth}}</div>
</div>
<div class="item">
<div>Smartphones:</div>
<div
class="value"
:class="{'active': xs, 'disable': !xs}"
>{{createPromptDescription(breakpoints, 'xs')}}</div>
</div>
<div class="item">
<div>Tablets:</div>
<div
class="value"
:class="{'active': sm, 'disable': !sm}"
>{{createPromptDescription(breakpoints, 'sm')}}</div>
</div>
<div class="item">
<div>Small laptops:</div>
<div
class="value"
:class="{'active': md, 'disable': !md}"
>{{createPromptDescription(breakpoints, 'md')}}</div>
</div>
<div class="item">
<div>Desktops:</div>
<div
class="value"
:class="{'active': lg, 'disable': !lg}"
>{{createPromptDescription(breakpoints, 'lg')}}</div>
</div>
<div class="item">
<div>Large Desktops</div>
<div
class="value"
:class="{'active': xl, 'disable': !xl}"
>{{createPromptDescription(breakpoints, 'xl')}}</div>
</div>
</div>
</div>
</div>
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.wrapper {
display: flex;
justify-content: center;
width: 100%;
height: 600px;
background-color: #a7ffeb;
}
.container {
padding: 10px;
}
.header {
margin: 30px 0;
}
.content {
font-size: 20px;
font-weight: 600;
text-align: center;
}
.content div {
margin: 10px 0;
}
.value {
color: white;
background-color: #40c4ff;
border-radius: 4px;
padding: 1px 10px;
width: auto;
min-height: 24px;
}
.item {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.active {
background-color: #8bc34a;
}
.disable {
opacity: 0.5;
}
Vue
const breakpoints = {
xs: '576',
sm: '768',
md: '992',
lg: '1200'
}
const CONSTANTS = {
ONLY_NUMBERS: /^\d+$/
};
const WindowResizeMixn = {
data: () => ({
width: window.innerWidth,
height: window.innerHeight,
}),
mounted() {
this.$nextTick(() => {
window.addEventListener('resize', this.widthResizeHandler);
window.addEventListener('resize', this.heightResizeHandler);
});
},
destroyed() {
window.removeEventListener('resize', this.widthResizeHandler);
window.removeEventListener('resize', this.heightResizeHandler);
},
computed: {
breakpoints () {
let breakpointsObj = {};
Object.keys(breakpoints).map(key => {
breakpointsObj[key] = this._parseBreakpoint(breakpoints[key], key);
});
return breakpointsObj;
},
windowHeight() {
return this.height;
},
windowWidth() {
return this.width;
},
xs() {
return this.windowWidth < this.breakpoints.xs;
},
sm() {
return this.windowWidth >= this.breakpoints.xs && this.windowWidth < this.breakpoints.sm;
},
md() {
return this.windowWidth >= this.breakpoints.sm && this.windowWidth < this.breakpoints.md;
},
lg() {
return this.windowWidth >= this.breakpoints.md && this.windowWidth < this.breakpoints.lg;
},
xl() {
return this.windowWidth > this.breakpoints.lg
}
},
methods: {
_parseBreakpoint(breakpoint, type) {
if (typeof breakpoint === 'string') {
const stringIsCorrect = breakpoint.match(CONSTANTS.ONLY_NUMBERS);
if (!stringIsCorrect) {
throw `Breakpoint ${type} value should contains only numbers`;
}
return breakpoint;
}
return breakpoint;
},
widthResizeHandler() {
this.width = document.documentElement.clientWidth;
},
heightResizeHandler() {
this.height = document.documentElement.clientHeight;
}
}
}
new Vue({
el: "#app",
mixins:...