关于小程序页面间传值和互操作的一个设计

本文介绍了在小程序开发中,如何通过在路由表数据域中添加属性,利用`AdvNavigation`类实现页面间的传值和互操作,以及在登录和编辑场景中的具体应用。
摘要由CSDN通过智能技术生成

背景

小程序凭借着“用完即走”的优势,获得了广大用户的青睐,国内的小程序主要有微信小程序、支付宝小程序、京东小程序和抖音小程序。这篇文章主要介绍一种小程序页面间传值和互操作的设计思路,我是基于下面2个场景非常希望有这样的一个机制:

        在资料列表页中,选择一个资料项跳转到资料编辑页去编辑,我们希望携带资料项到编辑页中

        在编辑页中,修改并提交资料项到后台保存成功后,返回到资料列表页中,我们希望资料列表页可以感知到修改项进而展示修改好的数据

对于问题的思考

在开发前端应用中,我们都会遇到上面的问题,我们可能会想到用父子组件来解决,在SPA页面中,我们确实是这样解决的,可是在小程序中它们之间是兄弟关系不是父子关系或者祖孙关系。

通过URL参数传资料项id到编辑页面,编辑页面在显示前去服务端取出资料项来编辑,编辑页面关闭后列表页在显示前去服务端重新加载数据。

把数据放到Redux这样的缓存中,编辑页面根据资料项id取到资料编辑,编辑页提交成功后更新缓存,由于列表页订阅了这些数据,列表页会自动刷新

使用消息事件总线的方式,事件的触发和接收需要进行巧妙的设计,有的小程序框架提供了相关的基础设施,会简化使用

上面几个方案可以部分或者全面地解决提出的问题,上面的几种方案各有优缺点,适合自己项目的方案可以了。我这里补充一种思路,利用在路由表的数据域中加入属性来解决提出的问题,这里把这个功能设计成一个类并提供简洁的方法以供使用。

实现代码

import Taro from '@tarojs/taro'

export type ToParams = {
    url: string;
    getData?: ()=>any;
    callBack?: (par: any)=>void;
};

export default class AdvNavigation{

    private static ToExtAttrName:string = "zzz";

    static to(params: ToParams){
        const {url} = params;
        Taro.navigateTo({url,
            success: function(){
                if(!!params){
                    const pages:Taro.Page = Taro.getCurrentPages();
                    const curPage = pages[pages.length-1];
                    const index = url.indexOf("?");
                    const url2:string = index==-1? url: url.slice(0, index);
                    curPage['data'][`${AdvNavigation.ToExtAttrName}-${url2}`] = params;
                    console.log("curpage:", curPage);
                }
            }
        })
    }

    static getParams(): ToParams{
        const pages:Taro.Page = Taro.getCurrentPages();
        const curPage = pages[pages.length-1];
        if(pages.length < 2){
            return {url: curPage['route']||''};
        }
        
        const prePage = pages[pages.length-2];
        const attr = `${AdvNavigation.ToExtAttrName}-${curPage['route']}`;
        return prePage['data'][attr];
    }

    static getAndClearParams(): ToParams | undefined{
        const pages:Taro.Page = Taro.getCurrentPages();
        const curPage = pages[pages.length-2];
        if(pages.length < 2){
            return {url: curPage['route']||''};
        }
        
        const prePage = pages[pages.length-2];
        const r = prePage['data'][`${AdvNavigation.ToExtAttrName}-${curPage['route']}`];
        delete prePage['data'][`${AdvNavigation.ToExtAttrName}-${curPage['route']}`];
        return r;
    }
}

使用

用户在个人页中点击登录跳转到登录页面的代码

      AdvNavigation.to({
        url: "/pages/login/index",
        callBack: (e: any) => {
          loadUser();
          loadAvator();
        },
      });

在登录页中,为了减少不相关的代码干扰,特只截取了相关的代码

  const [params, setParams] = useState<ToParams>({ url: "" });

  useEffect(() => {
    // 把列表页面的互操作保存起来
    setParams(AdvNavigation.getParams()||{url:""});
  }, []);

  const handleLogin = () => {
    console.log(phone, pwd, code);
    const reqDto: LoginRequestDto = {
      username: phone,
      password: pwd,
    };
    login(reqDto).then((res: ResultDto<LoginResponseDto>) => {
      if (res.success) {
        Taro.navigateBack().then(() => {
          if (params.callBack) {
            // 通知列表页
            params.callBack(undefined);
          }
        });
      } else {
        Taro.showToast({ icon: "error", title: res.errorMessage || "" });
      }
    });
  };

小结

在上面的使用例子中,列表页调用函数to打开编辑页面,编辑页面用getParams获取列表页传过来的信息,在登录成功后通知个人页加载用户和头像信息,可以看出使用上也比较简洁。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值