Skip to content

Instantly share code, notes, and snippets.

@foozlereducer
Last active February 23, 2024 14:56
Show Gist options
  • Save foozlereducer/66d125a790bc252467b3805ae3335b57 to your computer and use it in GitHub Desktop.
Save foozlereducer/66d125a790bc252467b3805ae3335b57 to your computer and use it in GitHub Desktop.
Vue Device Switching
/** ---------------------------------------------------------------*/
// app/src/views/SampleMetric.vue
/** ---------------------------------------------------------------*/
<script setup>
import { deviceSize } from '../composables/deviceSize.js'
import HomeView from './Home.vue';
import Phone from './Phone.vue'
import Tablet from './tablet.vue'
import {devices} from '../composables/devices.js'
const sizes = deviceSize(devices)
</script>
<template>
<h2>{{ sizes.browserWidth }} pixels: Browser</h2>
<h2>{{ sizes.deviceWidth }} pixels: Device</h2>
<h2>{{ sizes.device.value }} type of Device </h2>
<Phone v-if="sizes.device.value == 'phone'" />
<Tablet v-else-if="sizes.device.value == 'tablet'" />
<HomeView v-else />
</template>
/** ---------------------------------------------------------------*/
// app/src/composables/deviceSize.js
/** ---------------------------------------------------------------*/
import { onUnmounted, onMounted, reactive, toRefs } from "vue";
export const deviceSize = (deviceSizes) => {
const sizes = reactive ({
browserWidth: window.innerWidth,
deviceWidth: screen.width,
device: 'desktop' // Default to desktop
});
const browserResized = () => {
sizes.browserWidth = window.innerWidth;
sizes.deviceWidth = screen.width;
sizes.device = getDevice();
}
console.log('screen.width:', screen.width);
const getDevice = () => {
let type = 'desktop'; // Default to desktop
if (window.innerWidth <= deviceSizes.phone.size) {
type = deviceSizes.phone.type;
} else if (window.innerWidth < deviceSizes.desktop.size) {
type = deviceSizes.tablet.type;
}
return type;
}
onMounted(() => {
window.addEventListener('resize', browserResized)
})
onUnmounted(() => {
window.removeEventListener('resize', browserResized);
})
return {
...toRefs(sizes)
}
}
/** ---------------------------------------------------------------*/
// app/src/composables/devices.js
/** ---------------------------------------------------------------*/
export const devices = {
phone: {
size: 480,
type: 'phone'
},
tablet: {
size: 768,
type: 'tablet'
},
desktop: {
size: 1024,
type: 'desktop'
}
}
/** ---------------------------------------------------------------*/
// app/src/components/__test__
/** ---------------------------------------------------------------*/
import { mount } from '@vue/test-utils';
import { devices } from '../../composibles/devices';
import { deviceSize } from '../../composibles/deviceSize.js';
import { describe, expect, it } from 'vitest';
// Mock screen object
global.screen = {
width: 1366, // Set to a valid width for testing purposes
};
describe('deviceSize composable', () => {
it('returns expected values', async () => {
const wrapper = mount({
template: `
<div>{{ sizes.browserWidth }}</div>
<div>{{ sizes.deviceWidth }}</div>
<div>{{ sizes.device.value }}</div>
`,
setup() {
const sizes = deviceSize(devices);
return { sizes };
},
});
// Check initial values
expect(wrapper.text()).toContain('1024'); // Browser width
expect(wrapper.text()).toContain('1366'); // Device width
expect(wrapper.text()).toContain('desktop'); // Device type
// Simulate browser resize
global.window.innerWidth = 600;
window.dispatchEvent(new Event('resize'));
// Wait for DOM to update
await wrapper.vm.$nextTick();
// Check updated values after resize
expect(wrapper.text()).toContain('600'); // Browser width
expect(wrapper.text()).toContain('phone'); // Device type
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment