zoukankan      html  css  js  c++  java
  • 让微信小程序页面之间的通信不在变得困难

    一个开始

    小程序开发者总会碰到各种页面之间的通信问题,实现方式也五花八门,比如...

    场景还原

    首先这是一个电商小程序。

    有这样一个需求:

    1. 首页某个地方要展示购物车商品数量。
    2. 当我在其他页面加购了商品,首页数量刷新。

    实现方式

    1. 方式一:onShow直接请求接口
    Page({
        onShow() {
            // ...一些逻辑
            
            // 后端请求新的购物车数量
            this.requestCartNum();
        }
    })

    不足: 每次onShow都要请求接口,浪费资源。

    1. 方式二:globalData存储购物车数量,onShow中做刷新

      

    // 主页.js
    Page({
        onShow() {
            // 在globalData获取到购物车数据
            let num = globalData.cartNum;
            if (num !== this.data.cartNum) {
                this.setData({
                    cartNum: num,
                });
            }
        }
    });
    
    // 加购页.js
    Page({
        // 加购后改变globalData的值
        cartAdd(num) {
            globalData.cartNum = globalData.cartNum + num;
        }
    })
    1. 方式三:加购后获取首页实例,调用首页方法
    // 首页.js
    Page({
        onCartAdd(num) {
            this.setData({
                cartNum: this.data.cartNum + num,
            });
        },
    });
    
    // 加购页.js
    Page({
        onCartAdd(num) {
            // 加购后获取到首页的实例,调用首页onCartAdd方法
            let pages = getCurrentPages();
            let curPage = pages[0];
            curPage.onCartAdd(num);
        }
    })

    不足:不确定能不能准确拿到首页的实例,如果换做其他页面就很难复用

    1. 方法四:事件订阅与发布
    // 首页.js
    Page({
        onLoad() {
            // 首页监听事件
            this.$bus.on('cart_add', (num) => {
                this.setData({
                    cartNum: this.data.cartNum + num,
                })
            })
        }
    })
    
    // 加购页.js
    
    Page({
        // 加购成功后触发cart_add事件
        onCartAdd(num) {
            this.$bus.emit('cart_add', num);
        }
    })

    此方法用事件系统,订阅发布模式去做的处理。

    以上几种方法中最优解决方案是方法四,利用事件的订阅与发布,逻辑清晰兼容性好。但是都不可避免的不足是:每一个需要动态显示购物数量的页面都需要添加相同的逻辑代码。

    状态管理方案

    单页应用中最常用的就是组件之间的通信,由此诞生了不同的状态存储方案: react用redux, vue用vuex。他们的思路都是类似的。都有一个核心 store 存储着一切要管理的状态。

    那么,其他框架可以,小程序也可以。以redux为例,实现一套简单的状态管理方案。

    wxdux的实现

    使用前提:有redux基础

    wxdux 类似与redux,以action来描述触发的行为,reducer来描述state的变化。

    1. 小程序入口中注册

    注册store并添加到globalData中去

    import {createStore} from './wxdux/index';
    import reducer from './reducer';
    
    const store = createStore(reducer);
    
    App({
        globalData: {
            store,
        },
    });

    2. reducer实现

    写法与redux类似,功能也类似。

    const userReducer = (state = {}, action) => {
        // ...
    }
    
    const postReducer = (state = [], action) => {
        // ...
    };
    
    const reducers = {
        user: userReducer,
        posts: postReducer,
    };
    
    export default reducers;

    3. 页面中使用wxdux

    connect方法会将小程序页面实例与wxdux连接起来,必须提供$useState方法,该方法接收state,返回该页面所需要的state

    import {connect} from './wxdux/index';
    
    Page(connect({
        data: {
            sex: '男',
        },
        onLoad() {
            // ...
        },
        $useState(state) {
            return {
                name: state.name,
            },
        },
    }))

    4. wxml中使用name

    <view>{{name}}</view>

    5. 触发store更新

    使用dispatch方法,该方法接收一个对象作为参数,该对象必须包含type字段表示action的类型,wxdux会根据此action更新state并且刷新所有使用name的视图

    import {dispatch} from './wxdux/index';
    
    Page(connect({
        // 某点击事件触发,更新姓名为“张三”
        onClick() {
            const updateName = {
                type: 'update_name',
                name: '张三'
            };
            dispatch(updateName);
        }
    }))

    最后

    github链接

  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/xujiazheng/p/10966194.html
Copyright © 2011-2022 走看看