<address id="r9vd9"><address id="r9vd9"><listing id="r9vd9"></listing></address></address>

      歡迎您光臨深圳塔燈網絡科技有限公司!
      電話圖標 余先生:13699882642

      網站百科

      為您解碼網站建設的點點滴滴

      關于原生小程序頁面間數據傳送的研究

      發表日期:2019-11 文章編輯:小燈 瀏覽次數:4723

      第一次在公司里負責做小程序,因為第一次做怕遇到大坑,所以用的原生開發。頁面數據共享比較常用,所以來研究研究。
      
      1. A頁面直接url傳參 B頁面onload里接收。這種簡單粗暴但B如果還想給A傳參感覺不太方便。而且傳一個很大的對象過去,必須要stringfy。但是地址長度有限所以會有bug
      2. 直接wx.setStorage 簡單粗暴,直接存微信本地。有時候我并不想存太久,只是臨時的數據也給我存本地了感覺怪怪的。
      3. getCurrentPages() 這個可以拿當前的頁面棧,通過他來那上一個頁面,上上個頁面的信息。有時候一個頁面說不定有很多種進入途徑,也不知道上個頁面是啥,用起來也有點怕怕的。
      4. app.globalData 里存一個臨時數據比如payload:null,當要A頁面要傳參時改變payload值,然后B頁面獲取到后置為null。我一般就這么搞感覺還行。
      5. 有米有什么更好的方法呢,我發現現在的小程序框架都是有狀態管理的,要不我也整個。我就研究了下,抄個乞丐版的redux放在小程序里用用。以下為代碼。

      一、上來建個文件夾把redux相關的代碼丟上去。

      //createStore.js
      
      export default function createStore(reducer, preloadedState, enhancer) {
        //放中間件用 其實就是在enhancer里調用createStore 并修改dispatch
        if (enhancer && typeof enhancer === 'function') {
          return enhancer(createStore)(reducer, preloadedState)
        }
        
        //初始state賦值
        let state = preloadedState;
        let listeners = [];
      
        const getState = () => state;
         //觸發動作
        const dispatch = (action) => {
          state = reducer(state, action);
          listeners.forEach(listener => listener());
        };
        //添加監聽器,無非加些有setData的方法進去
        const subscribe = (listener) => {
          listeners.push(listener);
          return () => {
            listeners = listeners.filter(l => l !== listener);
          }
        };
      
         //初始化
        dispatch({});
      
        return { getState, dispatch, subscribe };
      }

      具體代碼可以看代碼地址
      對于redux不太理解的同學可以看看其它文章。有很多高手寫,我這個菜鳥就不寫了:)

      二、把store 存到app.js里

      import store from './store/index.js'
      import bindActionCreator from '/store/hcyRedux/bindActionCreator.js'
      App({
        globalData: {
          store,
          bindActionCreator //方便dispatch
        }
      })

      三、建action

      // /action/page2
      import * as types from '../action-types'
      //創建 action的函數
      export default {
        change(obj) {
          return { type: 'page2/' + types.INPUT, payload: obj }
        },
        promiseChange(obj) {
          return {
            type: 'page2/' + types.INPUT,
            payload: new Promise(function (resolve, reject) {
              setTimeout(function () {
                resolve(obj)
              }, 1000)
            })
          }
        }
      }
      
      // /action/page1
      import * as types from '../action-types'
      //創建 action的函數
      export default {
        change(obj) {
          return { type: 'page1/' + types.INPUT, payload: obj}
        }
      }

      四、建reducer

      import * as types from '../action-types'
      const head = 'page2/'
      const defaultValue = {
        input1: 4,
        input2: 5,
        input3: 6
      }
      export default function (state = defaultValue, action) {
        switch (action.type) {
          case head + types.INPUT:
            return { ...state, ...action.payload };
          default:
            return state
        }
      }

      這是page2的page1也差不多

      這樣子不管什么頁面可以通過app.globalData.store.getState()想怎么取值都可以了。
      當然每個頁面的onload 和 onUnLoad 都必須添加和刪除監聽(就是setData)這樣dispatch 之后頁面才會渲染。

      這樣基本就完成了。但我不想每個頁面都添加刪除監聽??梢赃@么干。

      // 自己封裝了一個mini-redux.js
      const app = getApp();
      const store = app.globalData.store;
      
      //得到一個{page1:{。。。},page2{。。。}}這樣一個對象
      function getData (obj) {
        let res = {}
        obj.pages.forEach(x => {
          res[x] = store.getState()[x]
        })
        return res
      }
      
      export default function (obj) {
        let listener = null;
        let res = {};
        this.action = obj.action.map(x => app.globalData.bindActionCreator(x, store.dispatch));
        this.store = store
        return {
          ...obj,
          data: getData(obj),
          onLoad: function () {
            listener = store.subscribe(() => {
              this.setData(getData(obj))
            })
            store.dispatch({})
            obj.onLoad && obj.onLoad();
          },
          onUnload() {
            listener();
            obj.onUnload && obj.onUnload();
          }
        }
      }

      page2頁面

      <view class="page-section">
        <view class="weui-cells__title">{{page2.input1}}</view>
        <view class="weui-cells weui-cells_after-title">
          <view class="weui-cell weui-cell_input">
            <input class="weui-input" placeholder="test" value="{{page2.input1}}" bindinput="bindKeyInput" data-key="input1" />
          </view>
        </view>
      </view>
      <view class="page-section">
        <view class="weui-cells__title">{{page2.input2}}</view>
        <view class="weui-cells weui-cells_after-title">
          <view class="weui-cell weui-cell_input">
            <input class="weui-input" placeholder="test" value="{{page2.input2}}" bindinput="bindKeyInput" data-key="input2" />
          </view>
        </view>
      </view>
      <view class="page-section">
        <view class="weui-cells__title">{{page2.input3}}</view>
        <view class="weui-cells weui-cells_after-title">
          <view class="weui-cell weui-cell_input">
            <input class="weui-input" placeholder="test" value="{{page2.input3}}" bindinput="bindKeyInput" data-key="input3" />
          </view>
        </view>
      </view>
      <text>{{page1.input1}}</text>
      <navigator url="/pages/page2/page2">
        <button type="primary"> 2 </button>
      </navigator>

      page2.js

      import actions1 from '../../store/actions/page1.js'
      import actions2 from '../../store/actions/page2.js'
      import V from '../../utils/mini-redux.js'
      const page = {}
      
      Page(V.call(page,{
        action: [actions1, actions2], //定義好用那些action
        pages:['page1', 'page2'], //定義好需要用那些store 是在reducer/index.js 定義的
        bindKeyInput(e) {
          //action[0] 就是actions1
          page.action[0].change({
            [e.target.dataset.key]: e.detail.value
          });
          page.action[1].promiseChange({
            [e.target.dataset.key]: e.detail.value
          });
        },
        onShow() {
          console.log('show2')
        },
        onLoad () {
          console.log('load2')
        }
      }))

      具體代碼可以看代碼地址

      還是有些問題 每次dispatch 會觸發頁面棧的所有頁面的監聽,頁面可以直接setData store 等等。這些地方應該還可以優化。


      本頁內容由塔燈網絡科技有限公司通過網絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網頁中由涉嫌抄襲的內容,請及時與我們聯系,并提供相關證據,工作人員會在5工作日內聯系您,一經查實,本站立刻刪除侵權內容。本文鏈接:http://www.webpost.com.cn/25242.html
      相關小程序
       八年  行業經驗

      多一份參考,總有益處

      聯系深圳網站公司塔燈網絡,免費獲得網站建設方案及報價

      咨詢相關問題或預約面談,可以通過以下方式與我們聯系

      業務熱線:余經理:13699882642

      Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

      国产成人精品综合在线观看