省流: device 提供了如
const { isMobile } = useDevice()的形式来判断设备类型。但需要注意的是,在nuxt build模式中使用v-if以及动态类名(如<div :class="{mobile: isMobile}">)的形式均可生效,而在nuxt build和nuxt generate模式中仅v-if生效,后者会有问题。
- 本人菜鸟前端一枚,在一个非互联网企业做前端开发,团队原本用的是 Angular ,最近几个项目因为甲方要求,换到了 Vue3+Nuxt3 ,SSR 模式,所以大家对 Nuxt 都了解不深
- 前两天我们在桌面端做完的情况下做响应式,但是桌面端和手机端的 DOM 差别比较大,而且页面内容比较复杂,如果还是按照媒体查询 CSS 的方式会让 CSS 和 HTML 很长,不太好维护,并且也影响加载速度(毕竟相当于加载两个版本的页面)。
- 我觉得比较好的处理方法是:对于 DOM 差别很大的,干脆写两种组件,使用 v-if 选择加载;而对于差别不大的,就加一个.mobile 的 class ,然后在原本的 CSS 基础上微调一下。
- 找了找相关的帖子还真发现了个插件,就是标题提到的这个@nuxtjs/device,看简介是通过检测 UA 判断设备类型的,那理论上在 DOM 挂载之前就能确定类型,试了一下给的 demo (如下)
<template>
<section>
<div v-if="$device.isDesktop">Desktop</div>
<div v-else-if="$device.isTablet">Tablet</div>
<div v-else>Mobile</div>
</section>
</template>
- 好像也没问题,就拿这个插件在 dev 环境下写了。在实际使用中,大概采用了以下两种写法,但在
dev模式下都能正常工作
<Dialog v-if="!isMobile" .../>
<DialogM v-else .../>
...
<Card :class="{mobile: isMobile}" .../>
- 今天写的差不多了试了试
nuxt generate,发现访问时,使用第二种写法的组件一律采用了手机端的样式(配置项里默认 UA 是手机版的),无视 UA ,这才发现官方文档里并没提第二种写法,但它在dev模式下确实能正常工作....没办法,现在只能尽力填坑。 - 好在填坑也不算太难,只要把
<Card :class="{mobile: isMobile}" .../>改为<Card v-if="isMobile" class="mobile" .../> <Card v-else ...>就行了,写法是有点傻,但也只能这样尽量找补了。 - 长教训了,下次要采用一个什么新东西时一定要充分测试....