【Vue3】如何一个项目实现PC/移动端的多端适配

写在前面:

什么是多端适配?

前端的多端适配是指在开发前端网页或应用程序时,通过编写不同的布局和样式代码,使得同一个项目能够适应不同的终端设备,如PC端和移动端,以提供更好的用户体验。 由于PC端和移动端的屏幕尺寸、分辨率、交互方式等存在差异,为了使网页或应用程序在不同设备上都能正常显示和使用,需要进行多端适配。

效果如下:

实现步骤:

1.判断客户端是否为移动端设备

首先,创建一个工具类js,用于存放相关判断函数 创建isWap以及isWapPage函数,用于检测当前设备是否为移动端设备

1.函数 isWap 定义一个变量 userAgentInfo,它保存了浏览器的用户代理信息。然后,定义一个包含各种移动设备名称的数组 Agents。变量 flag 被初始化为 true,用于标记当前设备是否为移动设备。

接下来,通过遍历 Agents 数组,检查用户代理信息中是否包含其中任何一个移动设备的名称。如果包含,说明当前设备是移动设备,将 flag 设置为 false 并跳出循环。

flagtrue 的情况下,通过获取页面可视区域的宽度,判断当前设备是否为移动设备。如果宽度小于 840 像素,则被判定为手机设备,将 flag 设置为 false

最后返回 !flag,即返回当前设备是否为移动设备的布尔值。

2.函数 isWapPage 用于检测当前页面是否是移动端页面。首先创建一个空数组 routerNames,然后定义了一个递归函数 getAllRouterNames,用于遍历 routers 数组并将路由名称存储在 routerNames 中。

接着通过 window.location.href 获取当前页面的 URL,并使用 split('#')[1] 获取 URL 中的路径部分。然后,使用 router.resolve(path) 解析路径对应的路由信息,将结果保存在 curRoute 变量中。

最后判断 isWap() 是否为 true,以及当前路由名称是否包含 -wap 或者在 routerNames 中是否存在当前路由名称加上 -wap 的形式,来确定当前页面是否是移动端页面。如果是,则返回 true,否则返回 false。 代码如下:

js 复制代码
export const isWap = () => {
  var userAgentInfo = navigator.userAgent
  var Agents = [
    'Android',
    'iPhone',
    'SymbianOS',
    'Windows Phone',
    'iPad',
    'iPod'
  ]
  var flag = true
  for (var v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false
      break
    }
  }

  if (flag) {
    let width =
      document.documentElement.clientWidth || document.body.clientWidth
    if (width < 840) {
      //小于840px的屏幕,判定为手机
      flag = false
    }
  }
  return !flag
}

/** 当前url是否对应的wap页面 */
export const isWapPage = () => {
  const routerNames = []
  const getAllRouterNames = array => {
    array.forEach(element => {
      routerNames.push(element.name)
      if (element.children?.length) {
        getAllRouterNames(element.children)
      }
    })
  }
  getAllRouterNames(routers)

  const path = window.location.href.split('#')[1]
  const curRoute = router.resolve(path)

  if (
    isWap() &&
    ((curRoute.name.indexOf('-wap') < 0 &&
      routerNames.includes(curRoute.name + '-wap')) ||
      curRoute.name.indexOf('-wap') >= 0)
  ) {
    return true
  } else {
    return false
  }
}

2.判断是否为刘海屏并对iphone进行刘海屏优化

创建几个判断函数:

  • 1.函数 judgeClient 用于判断客户端类型,即判断当前设备是 Android、iOS 还是 PC。首先获取浏览器的用户代理信息,并根据用户代理信息中是否包含关键字 "Android" 或 "Adr" 来判断是否是 Android 终端。然后使用正则表达式匹配用户代理信息,判断是否是 iOS 终端。最后,根据判断结果返回相应的客户端类型。

  • 2.函数 isiPhoneX 用于判断当前设备是否是刘海屏(iPhone X 及其后续型号)。它通过调用 judgeClient 函数获取客户端类型,并根据一系列判断条件来确定是否是刘海屏设备。判断条件涉及设备的屏幕高度和宽度与特定型号的对比。

  • 3.函数 safeBottomHeight 返回一个安全区域底部高度,用于适配刘海屏设备。如果当前设备是刘海屏(通过调用 isiPhoneX 函数判断),则返回 44;否则返回 0。

  • 4.函数 safeTopHeight 返回一个安全区域顶部高度,用于适配刘海屏设备。如果当前设备是刘海屏(通过调用 isiPhoneX 函数判断),则返回 22;否则返回 0。

  • 5.函数 statusBarHeight 返回一个状态栏高度,根据客户端类型和是否是刘海屏来确定。如果客户端类型是 iOS 并且是刘海屏设备(通过调用 judgeClientisiPhoneX 函数判断),则返回 44;否则返回 20。

通过以上配置即可实现刘海屏iphone移动端页面适配,如果只适配移动端不专门进行优化这一步可以忽略 代码如下:

js 复制代码
/** 判断客户端:Android,IOS,PC */
export const judgeClient = () => {
  let u = navigator.userAgent
  let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 //判断是否是 android终端
  let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) //判断是否是 iOS终端
  if (isAndroid) {
    return 'Android'
  } else if (isIOS) {
    return 'IOS'
  } else {
    return 'PC'
  }
}

/** 是否是刘海屏 */
export const isiPhoneX = () => {
  return (
    (judgeClient() === 'IOS' &&
      ((D_HEIGHT === X_HEIGHT && D_WIDTH === X_WIDTH) ||
        (D_HEIGHT === X_WIDTH && D_WIDTH === X_HEIGHT))) ||
    (D_HEIGHT === XSMAX_HEIGHT && D_WIDTH === XSMAX_WIDTH) ||
    (D_HEIGHT === XSMAX_WIDTH && D_WIDTH === XSMAX_HEIGHT) ||
    (D_HEIGHT === p12_HEIGHT && D_WIDTH === p12_WIDTH) ||
    (D_HEIGHT === p12_WIDTH && D_WIDTH === p12_HEIGHT) ||
    (D_HEIGHT === p12_MAX_HEIGHT && D_WIDTH === p12_MAX_WIDTH) ||
    (D_HEIGHT === p12_MAX_WIDTH && D_WIDTH === p12_MAX_HEIGHT)
  )
}

export const safeBottomHeight = () => {
  return isiPhoneX() ? 44 : 0
}

export const safeTopHeight = () => {
  return isiPhoneX() ? 22 : 0
}

export const statusBarHeight = () => {
  return judgeClient() === 'IOS' ? (isiPhoneX() ? 44 : 20) : 0
}

3.全局引入isWapPage

main.js中添加以下代码:

js 复制代码
import { isWapPage } from './utils/index'
import './wap'

const wap = isWapPage()


if (wap) {
  app = createApp(WapApp)
  app.use(Vant)
} else {
  app = createApp(App)
  app.use(Antd)
}

4.配置全局前置路由守卫,不同设备将打开不同的页面

1.在路由index.js中,创建三个判断函数用于判断是否需要跳转到移动端页面或 PC 端页面。

函数 existWapPage 接收一个路由名称 routeName,它的作用是检查是否存在对应的移动端页面。首先创建一个空数组 routerNames,然后定义了一个递归函数 getAllRouterNames,用于遍历 routers 数组并将路由名称存储在 routerNames 中。最后,通过判断 routerNames 是否包含 routeName + '-wap',来确定是否存在对应的移动端页面,并返回相应的布尔值。

函数 needJumpToWap 接收一个路由名称 routeName,它判断是否需要跳转到移动端页面。首先通过调用 isWap() 函数判断当前设备是否为移动设备。如果是移动设备,并且 routeName 中不包含 -wap,并且存在对应的移动端页面(通过调用 existWapPage(routeName) 函数判断),则返回 true,否则返回 false

函数 needJumpToPC 接收一个路由名称 routeName,它判断是否需要跳转到 PC 端页面。首先通过调用 isWap() 函数判断当前设备是否为移动设备。如果不是移动设备,并且 routeName 中包含 -wap,则返回 true,否则返回 false

这些函数的目的是根据当前设备和路由名称,判断是否需要进行页面跳转,以适配不同的设备类型。

js 复制代码
const existWapPage = routeName => {
  const routerNames = []
  const getAllRouterNames = array => {
    array.forEach(element => {
      routerNames.push(element.name)
      if (element.children?.length) {
        getAllRouterNames(element.children)
      }
    })
  }
  getAllRouterNames(routers)

  return routerNames.includes(routeName + '-wap')
}

const needJumpToWap = routeName => {
  if (isWap() && routeName.indexOf('-wap') < 0 && existWapPage(routeName)) {
    return true
  } else {
    return false
  }
}

const needJumpToPC = routeName => {
  if (!isWap() && routeName.indexOf('-wap') >= 0) {
    return true
  } else {
    return false
  }
}

2.配置全局前置路由守卫:

代码如下:

js 复制代码
router.beforeEach(async (to, from, next) => {
  await init(to)

![录制_2023_09_11_14_56_41_178.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f1bdb228736445acbac90ff2e07af7d3~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=950&h=519&s=35324&e=gif&f=11&b=fcfcfc)
  /** 处理wap跳转PC,PC跳转wap逻辑 */
  if (!isWap() && ['approval-dap', 'approval-dap-wap'].includes(to.name)) {
    const { applyType, approvalId } = to.params
    if (window.location.origin === UCENTER_DOMAIN) {
      next(
        //替换为自己的url
      )
    } else {
      window.location.replace(
              //替换为自己的url
      )
      next()
    }
  } else if (isWap() && to.query.appId === '2' && to.query.applyType === '21') {
    window.location.replace(
             //替换为自己的url
    )
  } else if (needJumpToWap(to.name)) {
    window.location.replace(        //替换为自己的url)
  } else if (needJumpToPC(to.name)) {
    window.location.replace(        //替换为自己的url)
  } else {
    handleDashboardToBRAuthApply(to)
    next()
  }
})

在这段代码中,通过这个钩子函数来处理不同设备之间的页面跳转逻辑。

  • 首先,执行了一些初始化操作,然后进行设备判断和处理wap跳转PC、PC跳转wap的逻辑。
  • 如果当前设备不是移动设备,并且路由名为 "approval-dap" 或 "approval-dap-wap",则根据不同的条件进行页面跳转。
  • 如果当前设备是移动设备,并且路由参数中的 appId 为 "2",applyType 为 "21",则进行相应的页面跳转。
  • 如果满足 needJumpToWap(to.name) 的条件,表示需要跳转至移动端页面,则执行相应的跳转逻辑。
  • 如果满足 needJumpToPC(to.name) 的条件,表示需要跳转至PC端页面,则执行相应的跳转逻辑。
  • 如果以上条件都不满足,则执行其他逻辑,并进行下一步路由导航。

5.编写移动端/PC端两套代码

至此,已经完成了一个项对PC/移动端进行多端适配,并显示两套不同的页面,只需要将pc端以及移动端页面分开存放,进行路由跳转即可。

相关推荐
GIS之路2 分钟前
OpenLayers 调整标注样式
前端
爱吃肉的小鹿3 分钟前
Vue 动态处理多个作用域插槽与透传机制深度解析
前端
GIS之路3 分钟前
OpenLayers 要素标注
前端
前端付豪3 分钟前
美团 Flink 实时路况计算平台全链路架构揭秘
前端·后端·架构
sincere_iu4 分钟前
#前端重铸之路 Day7 🔥🔥🔥🔥🔥🔥🔥🔥
前端·面试
设计师也学前端4 分钟前
SVG数据可视化组件基础教程7:自定义柱状图
前端·svg
我想说一句7 分钟前
当JavaScript的new操作符开始内卷:手写实现背后的奇妙冒险
前端·javascript
chanalbert9 分钟前
AI大模型提示词工程研究报告:长度与效果的辩证分析
前端·后端·ai编程
爱吃肉的小鹿10 分钟前
UI 组件二次封装:方法与问题详解
前端