当前位置:   article > 正文

vue3 + vite4.0 开发项目(PC端和移动端共用一套代码)_vue3+vite4

vue3+vite4

vue3 + vite4.0 开发项目(PC端和移动端共用一套代码)

做公司官网,为了实现PC端与移动端自适应的问题,决定使用 vue 开发项目,写两套代码,并***采用路由控制,加载PC端代码还是移动端代码,通过屏幕宽度大小来判断加载相应端的代码***。
其中产生的一些问题及难点在这里进行一些记录。

1、创建两套代码的文件夹

创建两套代码的文件夹,其中包含移动端、PC端的所有的内容。
在这里插入图片描述
其中的 index.vue 文件是用来存放 的,用于展示路由组件。
在这里插入图片描述

2、创建一个文件用于展示两个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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3、状态管理 devices

这里主要是使用 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
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

4、两套路由

将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')
          }
        ]
      },
    ]
  }
]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

这里也不需要进行路由守卫的检测,否则会陷入无限重定向的问题。

5、检测屏幕变化

最后是检测屏幕变化的这一部分,主要是放在了 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

这样就实现了实时根据屏幕大小变化路由的操作了,并且不需要手动刷新页面。

关于移动端适配的问题

这里采用的是 postcss-pxtorem 插件,

npm install postcss-pxtorem
npm install amfe-flexible
  • 1
  • 2

因为是使用 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
          }
        })
      ]
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

总结

耗费了两天终于实现了上面的效果,总之按照上述步骤就能完成操作,有需要的话可以留言,一起讨论。

2024-04-17修改优化

将动态路由的修改从 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/970906
推荐阅读
相关标签
  

闽ICP备14008679号