结合DvaJS来写小程序

小程序结合Redux,对于复杂的小程序,是很好的状态管理利器,

而Redux写起来相对复杂费力,
相比阿里爸爸的Dva.js把各种概念组合成model,
是很容易上手的,

在写小程序的时候,
很希望能够将二者结合到一起,
所以在深夜,
就动起手来了。


主要任务分为如下几点,同时附上代码,
应该不算复杂,很简单而粗暴的实现,
性能方面还没有很深的考量过,
以后再慢慢优化,
欢迎各位大佬提意见

  • 重写connect,把Page和store链接起来

const connect = (mapStateToProps) => {
    const app = getApp()
    const state = app._store.getState();
    const watchMap = mapStateToProps(state);

    return (opts) => {
        const onLoad = opts.onLoad;
        const onShow = opts.onShow;


        opts.onLoad = function (options) {
            const page = this;
            page._watchMap = Object.keys(watchMap);
            page._query = options;
           
            page._updateData = function (newData) {

                page.setData(newData);
            };

            onLoad(options, app._store.dispatch)
        }

        opts.onShow = function () {
            global._routing_ = false;
            const app = getApp()._dva_app_;
            app._history._handler();
            onShow()
        }

        return {
            ...opts,
            data: {
                ...watchMap
            },
            dispatch: app._store.dispatch
        }
    }
}
  • 构造适用于小程序的history

const history = {
    _listenHooks: [],
    _oldPages: [],
    _handler: () => {
        const pages = getCurrentPages();
        const oldPages = history._oldPages;

        if (pages.length > 0) {
            const isBack = pages.length + 1 == oldPages.length; //页面返回    页面不断出栈,直到目标返回页,新页面入栈
            // console.log(isBack)
            history._oldPages = pages;
            const currentPage = {route : pages[pages.length - 1].route , _query : pages[pages.length - 1]._query}            

            if(currentPage.route.indexOf('/') != 0){
                currentPage.route = '/' + currentPage.route
            }

            const app = getApp();
            app._store.dispatch({
                type: '@@route/save',
                payload:{
                    pathname: currentPage.route,
                    query: currentPage._query,
                    isBack
                }
            })

            history._listenHooks.forEach((listen) => {
                
                listen({
                    pathname: currentPage.route,
                    query: currentPage._query,
                    isBack
                })
    
    
            })
        }
        
    },

    listen: (callback) => {
        history._listenHooks.push(callback)
    },
}
  • 小程序初始化的时候要创建store

const creatApp = (opts) => {
    const app = dva.create({
        onStateChange: (state) => {
            // 同步数据到每一个页面
            //console.log(state)
            const pages = getCurrentPages();
            pages.forEach((page) => {
                if (page._watchMap && page._updateData) {
                    page._watchMap.forEach((key) => {
                        if (state[key]) {
                            const upData = {};
                            upData[key] = state[key];
                            page._updateData(upData)
                        }

                    })
                }
            })
        }
    });

    app._history = history;

    if (opts.models) {
        opts.models.forEach((model) => {
            app.model(model)
        })
    }

    // 初始化记录路由数据的模块
    app.model({
        namespace: '@@route',
        state: {
            pathname: null,
            query: {},
            isBack: false
        },
        reducers: {
            save(state, { payload }) {
                return { ...state, ...payload };
            },
        },

        effects: {}
    })
    app.start()

    opts._store = app._store;
    opts._dva_app_ = app;

    return opts;
}
  • 如何做到,监听state变化同步到page,主要运用dva的onStateChange

onStateChange: (state) => {
    // 同步数据到每一个页面
    //console.log(state)
    const pages = getCurrentPages();
    pages.forEach((page) => {
        if (page._watchMap && page._updateData) {
            page._watchMap.forEach((key) => {
                if (state[key]) {
                    const upData = {};
                    upData[key] = state[key];
                    page._updateData(upData)
                }

            })
        }
    })
}

源码:GITHUB,欢迎Start与提意见

DEMO:简单计数器&斗鱼接口调用

猜你喜欢

转载自www.cnblogs.com/jlfw/p/12726472.html