結合DvaJS來寫小程序

小程序結合Redux,對於複雜的小程序,是很好的狀態管理利器,git

而Redux寫起來相對複雜費力,
相比阿里爸爸的Dva.js把各類概念組合成model,
是很容易上手的,github

在寫小程序的時候,
很但願可以將兩者結合到一塊兒,
因此在深夜,
就動起手來了。小程序


主要任務分爲以下幾點,同時附上代碼,
應該不算複雜,很簡單而粗暴的實現,
性能方面尚未很深的考量過,
之後再慢慢優化,
歡迎各位大佬提意見app

  • 重寫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)
    },
}
  • 小程序初始化的時候要建立storethis

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的onStateChangespa

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與提意見code

DEMO:簡單計數器&鬥魚接口調用接口

相關文章
相關標籤/搜索