深入探讨uniapp项目开发经验总结与最佳实践

2026-02-08 0 113

深入探讨uniapp项目开发经验总结与最佳实践

在软件开发过程中,我们经常会遇到各种各样的需求。比如,题目中提到的在应用中显示通知,这类需求实际上是项目需要与微信保持一致的特殊规定。这样的要求背后,蕴含着众多技术挑战和考量,同时也对项目的整体使用感受有着重要影响。

系统通知与应用内通知的差异

深入探讨uniapp项目开发经验总结与最佳实践

我们平时都习惯了系统通知的出现。但在这个项目中,我们需要在应用内部显示通知。系统自带的提醒在应用界面不会直接显示。不过,由于特定需求,我们不得不打破这一常规。如果用户感受到这种变化处理不当,可能会影响他们的使用体验。比如,某些新闻应用在用户阅读文章时突然弹出通知,可能会干扰阅读。同样,在办公应用中,如果在处理数据时突然出现通知,也可能打乱工作流程。对于开发者来说,要满足这一需求,必须完全放弃系统通知的常规做法。

我们需要注意各个平台的具体情况,例如iOS和安卓系统。在某些功能上,安卓系统可以轻松实现,但在iOS系统上可能遇到障碍,这是因为iOS的开发受到较多限制。

自定义组件解决方式的缺点

深入探讨uniapp项目开发经验总结与最佳实践

项目初期,我们采用自定组件来处理应用内的通知问题。但这种方法存在两个显著不足。首先,可能存在兼容性问题,某些手机型号或低版本系统可能无法正常使用这些组件。比如,一些旧款手机可能就无法正常显示自定义组件发出的通知。其次,性能也可能是问题之一,例如,可能会消耗过多内存或降低应用整体运行速度。如果手机内存本身就有限,再运行其他大型应用后,使用自定义组件通知可能会导致手机运行缓慢。

原生插件方式的尝试

深入探讨uniapp项目开发经验总结与最佳实践

针对自定义组件的缺陷,我们尝试采用原生插件技术,这种做法具有一定的创新点。我们借鉴了一些成功的做法,比如运用特定的Toast类,并结合独特的技术手段来模拟系统通知。这样做无需通知权限,可以完成一些基础功能。但这种方法也有其限制,并不适合完全取代系统通知,仅适用于应用内部的通知场景。此外,它的功能也相对不全面,若要实现更复杂的通知效果,可能无法满足需求。例如,涉及多种交互的通知,如点击后弹出菜单等,可能就无法实现。

/*
 * @Author: yuanyxh 
 * @Date: 2023-12-27 12:04:11 
 * @Last Modified by:   yuanyxh 
 * @Last Modified time: 2023-12-27 12:04:11 
 */
import Vue from \"vue\";
const ZERO = 0;
/** 最小左侧触摸开始位置 */
const MINIMUM_LEFT_DISTANCE = 100;
/** 最小移动距离 */
const MINIMUM_MOVE_DISTANCE = 50;
/** 最小间隔事件 */
const MINIMUM_TIME_INTERVAL = 100;
/**
 * 
 * @callback OnSideSlipListener
 * @param {number} sideTime 上次侧滑事件
*/
/**
 *
 * @description 侦听 ios 侧滑事件, 通过此工具配合 beforeRouteLeave 导航守卫判断是否侧滑返回
 */
const sideSlip = (function sideSlipListener(global) {
  let startX = 0,
    endX = 0;
  let sideTime = 0;
  const vm = Vue.prototype;
  /** @type {OnSideSlipListener[]} */
  const callbackList = [];
  function start(e) {
    const point = e.touches?.length ? e.touches[0] : e;
    startX = point.pageX;
  }
  function end(e) {
    const point = e.changedTouched?.length ? e.changedTouched[0] : e;
    endX = point.pageX;
    if (
      startX >= ZERO &&
      startX <= MINIMUM_LEFT_DISTANCE &&
      endX < ZERO &&
      vm.windowWidth - Math.abs(endX) > MINIMUM_MOVE_DISTANCE
    ) {
      sideTime = Date.now();
      callbackList.forEach((callback) => callback(sideTime));
    }
  }
  function isWithinValidityPeriod(time) {
    const interval = Date.now() - time;
    return interval >= ZERO && interval < MINIMUM_TIME_INTERVAL;
  }
  if (vm.isIos) {
    global.addEventListener(\"touchstart\", start);
    global.addEventListener(\"touchend\", end);
    global.addEventListener(\"touchcancel\", end);
  }
  return {
    /**
     * @description 是否左滑
     * @readonly
     */
    get isSideSlip() {
      if (vm.isIos) {
        return isWithinValidityPeriod(sideTime);
      }
      return false;
    },
    /**
     * @description 判断侧滑时间是否在有效期内
     * @param {number} time 侧滑时间
     * @returns {boolean} 是否有效
     */
    isWithinValidityPeriod: isWithinValidityPeriod,
    /**
     * 
     * @description 侦听侧滑
     * @param {OnSideSlipListener} callback 
     */
    on(callback) {
      if (typeof callback === 'function') {
        callbackList.push(callback);
      }
    },
    /**
     * @description 取消事件侦听
     * @param {OnSideSlipListener} callback 
     */
    off(callback) {
      const i = callbackList.indexOf(callback);
      if (i === -1) return;
      callbackList.splice(i, 1);
    },
  };
})(
  (function() {
    let global = {};
    if (typeof window !== \"undefined\") {
      return (global = window);
    }
    global = {
      addEventListener() {},
      removeEventListener() {},
    };
    return global;
  })()
);
export default sideSlip;

iOS端的解决思路推测

深入探讨uniapp项目开发经验总结与最佳实践

iOS开发方面,由于经验不足,我们尚未找到确切的方法。不过,一个大致的方向是增加一个视图。从理论上讲,这个方法是有可能实现的。然而,iOS对应用视图的管理非常严格,新增的视图必须遵循苹果的设计标准。例如,社交类应用若不符合这些标准,可能无法通过审核。此外,还需确保新增视图不会干扰到其他视图的正常运作,比如在iPad的多任务模式下,新视图不能影响到其他任务的显示效果。

定时器相关的使用情况

深入探讨uniapp项目开发经验总结与最佳实践

项目中常用定时器来处理动画或视图变动。程序后台运行时,会主动停止定时任务,而回到前台则恢复基础定时任务。确保多端任务执行逻辑一致是关键。比如,H5和App端采用不同定时器方法。在游戏或交互应用开发中,这种方法至关重要。若处理不当,动画效果可能不稳定,影响用户体验。以一款休闲游戏为例,后台切换多次后回到前台,动画流畅度会因定时器处理方式不同而受影响。

软键盘高度获取的差异

在App上获取软键盘的高度相对容易,但在H5上则较为复杂。不同浏览器对软键盘弹出时的页面模式没有统一标准。幸运的是,主流浏览器都提供了相应的接口支持。然而,在实际开发过程中,一些侧重商务功能的软件可能受到较大影响。比如,那些需要频繁输入长文本的商务邮件应用,若无法准确判断软键盘高度,可能会影响用户的输入体验。对于前端开发者而言,为了兼容各种浏览器,往往需要编写更多的代码来应对各种不同的情况。

import Vue from \"vue\";
const DELAY_TIME = 300;
let callbackList = [];
let unimplementedChangeList = [];
function emit(target, payload) {
  if (target.length) {
    for (let i = 0; i < target.length; i++) {
      target[i](payload);
    }
  }
}
// 页面原始高度
let windowHeight = 0;
function onKeyboardHeightChangeWithH5() {
  let extraHeight = 0;
  let hasFocus = false;
  let originScrollY = 0;
  let cancheHeight = 0;
  let keyboardChangeTimer = null;
  function exec(height) {
    const keyboardHeight = Math.max(0, windowHeight - height);
    if (cancheHeight === keyboardHeight) {
      return;
    }
    cancheHeight = keyboardHeight;
    const { isIos } = Vue.prototype;
    emit(callbackList, {
      extra: isIos ? extraHeight : 0,
      height: keyboardHeight,
    });
  }
  window.addEventListener(
    \"focus\",
    (e) => {
      if (
        e instanceof FocusEvent &&
        (e.target instanceof HTMLInputElement ||
          e.target instanceof HTMLTextAreaElement ||
          e.target.contenteditable)
      ) {
        hasFocus = true;
        originScrollY = window.scrollY;
        setTimeout(() => {
          hasFocus = false;
        }, 600);
      }
    },
    { capture: true }
  );
  window.addEventListener(
    \"blur\",
    (e) => {
      if (
        e instanceof FocusEvent &&
        (e.target instanceof HTMLInputElement ||
          e.target instanceof HTMLTextAreaElement ||
          e.target.contenteditable)
      ) {
        hasFocus = true;
        setTimeout(() => {
          hasFocus = false;
        }, DELAY_TIME);
      }
    },
    { capture: true }
  );
  window.addEventListener(
    \"scroll\",
    () => {
      if (hasFocus) {
        extraHeight = window.scrollY - originScrollY;
      }
    },
    { capture: true }
  );
  if (typeof window.visualViewport !== \"undefined\") {
    return window.visualViewport.addEventListener(\"resize\", (e) => {
      if (hasFocus === false) {
        return emit(unimplementedChangeList);
      }
      if (keyboardChangeTimer) {
        clearTimeout(keyboardChangeTimer);
      }
      keyboardChangeTimer = setTimeout(() => {
        exec(e.target.height);
      }, DELAY_TIME);
    });
  }
  window.addEventListener(\"resize\", () => {
    if (hasFocus === false) {
      return emit(unimplementedChangeList);
    }
    if (keyboardChangeTimer) {
      clearTimeout(keyboardChangeTimer);
    }
    keyboardChangeTimer = setTimeout(() => {
      exec(window.innerHeight);
    }, DELAY_TIME);
  });
}
let isInited = false;
function initKeyboardHeightChangeListener() {
  // #ifdef APP-PLUS
  uni.onKeyboardHeightChange((res) => {
    emit(callbackList, { extra: 0, height: res.height });
  });
  // #endif
  // #ifdef H5
  windowHeight = Vue.prototype.windowHeight;
  onKeyboardHeightChangeWithH5();
  // #endif
}
/**
 * @callback OnKeyboardHeightChangeCallback
 * @param {{ extra: number; height: number }} 键盘高度(ios 中还有底部块的高度)
 */
/**
 * @typedef Options
 * @type {Object}
 * @property {boolean} reset app 端对 uni.onKeyboardHeightChange 重置侦听
 */
/**
 *
 * @description 侦听键盘高度变化事件, 对多端做兼容处理
 * @param {OnKeyboardHeightChangeCallback} callback 键盘高度变化事件回调
 * @param {Options} options 额外参数
 */
function onKeyboardHeightChange(callback, options = {}) {
  const { isPc } = Vue.prototype;
  if (isPc) {
    return console.error(
      \"PC devices do not need to listen for soft keyboard height\"
    );
  }
  // #ifdef APP-PLUS
  if (options.reset) {
    isInited = false;
    callbackList = [];
  }
  // #endif
  if (typeof callback === \"function\") {
    callbackList.push(callback);
  }
  if (isInited === false) {
    isInited = true;
    initKeyboardHeightChangeListener();
  }
}
/**
 *
 * @description 移除事件侦听函数
 * @param {OnKeyboardHeightChangeCallback} callback 需要移除的已注册函数
 */
function offKeyboardHeightChange(callback) {
  if (typeof callback === \"function\") {
    const index = callbackList.indexOf(callback);
    if (index >= 0) callbackList.splice(index, 1);
  }
}
/**
 *
 * @description H5 页面高度变化但未执行键盘高度变化事件时触发
 * @param {OnKeyboardHeightChangeCallback} callback 需要添加的注册函数
 */
function onUnimplementedChange(callback) {
  const { isPc } = Vue.prototype;
  if (isPc) {
    return console.error(
      \"PC devices do not need to listen for soft keyboard height\"
    );
  }
  if (typeof callback === \"function\") {
    unimplementedChangeList.push(callback);
  }
  if (isInited === false) {
    isInited = true;
    initKeyboardHeightChangeListener();
  }
}
/**
 *
 * @description H5 页面高度变化但未执行键盘高度变化事件时触发
 * @param {OnKeyboardHeightChangeCallback} callback 需要添加的注册函数
 */
function offUnimplementedChange(callback) {
  if (typeof callback === \"function\") {
    const index = unimplementedChangeList.indexOf(callback);
    if (index >= 0) unimplementedChangeList.splice(index, 1);
  }
}
export default {
  onKeyboardHeightChange,
  offKeyboardHeightChange,
  onUnimplementedChange,
  offUnimplementedChange,
};

在进行项目开发过程中,大家是否遇到过不同平台间差异显著的难题?期待大家分享个人经历,同时也欢迎对这篇文章给予点赞和转发。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 深入探讨uniapp项目开发经验总结与最佳实践 https://www.zuozi.net/78636.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务