赞
踩
vue3 + vite4.0 开发项目(PC端和移动端共用一套代码)
做公司官网,为了实现PC端与移动端自适应的问题,决定使用 vue 开发项目,写两套代码,并***采用路由控制,加载PC端代码还是移动端代码,通过屏幕宽度大小来判断加载相应端的代码***。
其中产生的一些问题及难点在这里进行一些记录。
创建两套代码的文件夹,其中包含移动端、PC端的所有的内容。
其中的 index.vue 文件是用来存放 的,用于展示路由组件。
创建一个文件用于引入并展示两个index.vue组件,也就是用于判断是pc端、还是移动端的组件进行展示。我是放在了 views 文件夹下,直接创建了一个 index.vue 文件。
其中 devices 是用于获取当前的窗口状态,‘pc’则是PC端,‘mobile’是移动端。
代码如下:
<script setup>
import pc from './pc/index.vue'
import mobile from './mobile/index.vue'
import { deviceStore } from '@/stores/deviceStore'
const devices = deviceStore()
</script>
<template>
<div>
<pc v-if="devices.device === 'pc'" />
<mobile v-if="devices.device === 'mobile'" />
</div>
</template>
<style lang="scss" scoped>
</style>
这里主要是使用 pinia 创建了一个状态管理,用于存储,可以全局使用。
代码如下:
// 管理设备数据 import { defineStore } from 'pinia' import { ref } from 'vue' export const deviceStore = defineStore('devices', () => { const device = ref('pc') // 默认是PC端,====》 PC端:pc、移动端:mobile /** * 切换设备类型 * @param {*} type */ const handleToChangeDevice = (type) => { device.value = type } return { device, handleToChangeDevice } })
将PC端代码与移动端代码分别写在两套路由表里面,默认的 index.js 中如如这两套路由表,并且默认展示 PC 端的路由。
其中移动端的路由表,大概如下:
export const mobile = [ { path: '/', name: 'mobile', component: () => import('@/views/index.vue'), redirect: '/', children: [ { path: '/', component: () => import('@/views/MLayout/index.vue'), redirect: '/home', children: [ { path: 'home', component: () => import('@/views/mobile/Home/index.vue') }, { path: 'serve', component: () => import('@/views/mobile/Serve/index.vue') }, { path: 'product', component: () => import('@/views/mobile/Product/index.vue') }, { path: 'case', component: () => import('@/views/mobile/Case/index.vue') }, { path: 'about', component: () => import('@/views/mobile/About/index.vue') }, { name: 'detail', path: 'detail/:id', component: () => import('@/views/mobile/Detail/index.vue') } ] }, ] } ]
这里也不需要进行路由守卫的检测,否则会陷入无限重定向的问题。
最后是检测屏幕变化的这一部分,主要是放在了 APP.vue 里面。
<script setup> import { onBeforeUnmount } from 'vue' import { deviceStore } from '@/stores/deviceStore' import { throttle } from '@/utils/dt' import { useRouter } from 'vue-router' import { pc } from '@/router/pc' import { mobile } from '@/router/mobile' const { handleToChangeDevice } = deviceStore() const router = useRouter() function resizeChange() { if (document.documentElement.clientWidth > 750) { // 默认设置当屏幕宽度 > 750 时,为PC端 handleToChangeDevice('pc') document.querySelector('#app').style.minWidth = '1180px' } else { // 默认设置当屏幕宽度 <= 750 时,为移动端 handleToChangeDevice('mobile') document.querySelector('#app').style.minWidth = 'auto' } if (document.documentElement.clientWidth > 750) { // 移除移动端的路由 if (router.hasRoute('mobile')) { router.removeRoute('mobile') } // 新增PC端的路由 router.addRoute(pc[0]) } else { // 移除PC端的路由 if (router.hasRoute('pc')) { router.removeRoute('pc') } // 新增移动端的路由 router.addRoute(mobile[0]) } // 刷新页面,更新当前的页面 router.replace(router.currentRoute.value.href) } // 节流处理 const throttleResize = throttle(resizeChange, 200) throttleResize() window.addEventListener('resize', throttleResize, false) onBeforeUnmount(() => { window.removeEventListener('resize', throttleResize, false) }) </script> <template> <!-- 一级路由出口组件 --> <RouterView /> </template>
这样就实现了实时根据屏幕大小变化路由的操作了,并且不需要手动刷新页面。
这里采用的是 postcss-pxtorem 插件,
npm install postcss-pxtorem
npm install amfe-flexible
因为是使用 vite 创建的项目,里面支持 postcss ,可以直接在 vite.config.js 中直接进行配置:
css: { ... // pxtorem插件 postcss: { plugins: [ postCssPxToRem({ rootValue: 37.5, // 1rem,根据 设计稿宽度/10 进行设置 propList: ['*'], // 需要转换的属性,这里选择全部都进行转换 // 只有mobile端需要进行rem转换 exclude: (e) => { if (/src(\\|\/)views(\\|\/)mobile/.test(e) || /src(\\|\/)views(\\|\/)MLayout/.test(e)) { return false } return true } }) ] } }
耗费了两天终于实现了上面的效果,总之按照上述步骤就能完成操作,有需要的话可以留言,一起讨论。
将动态路由的修改从 APP.vue 中转移到 views/index.vue 中,使用 watch 进行监听,减少其执行次数,及修改窗口改变时回到页面顶部的问题。
<script setup> import { watch } from 'vue' import { useRouter } from 'vue-router' import pcv from './pc/index.vue' import mobilev from './mobile/index.vue' import { pc } from '@/router/pc' import { mobile } from '@/router/mobile' import { deviceStore } from '@/stores/deviceStore' const devices = deviceStore() const router = useRouter() watch( () => devices.device, () => { if (devices.device == 'pc' && router.hasRoute('mobile')) { // 移除移动端的路由 if (router.hasRoute('mobile')) { router.removeRoute('mobile') } // 新增PC端的路由 router.addRoute(pc[0]) } else if (devices.device == 'mobile') { // 移除PC端的路由 if (router.hasRoute('pc')) { router.removeRoute('pc') } // 新增移动端的路由 router.addRoute(mobile[0]) } // 刷新页面,更新当前的页面 router.replace(router.currentRoute.value.href) }, { immediate: true, deep: true } ) </script> <template> <div> <pcv v-if="devices.device === 'pc'" /> <mobilev v-if="devices.device === 'mobile'" /> </div> </template> <style lang="scss" scoped> </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。