最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

原生微信小程序開發(fā)中 redux 的使用詳解

 更新時間:2021年02月18日 10:24:11   作者:王唯佳  
這篇文章主要介紹了原生微信小程序開發(fā)中 redux 的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前提

復(fù)雜場景中有不少數(shù)據(jù)需要在多個不同頁面間來回使用和修改。但是小程序頁面直接的數(shù)據(jù)通信方式十分的簡單。通常情況需要自己維護一個全局的對象來存放共有數(shù)據(jù)。但是,簡單的維護一個共有數(shù)據(jù)實體,會隨著業(yè)務(wù)邏輯的不斷復(fù)雜化而變的過分龐大,并且數(shù)據(jù)的修改往往無法很好的溯源。加之公共數(shù)據(jù)實體中數(shù)據(jù)的修改和頁面的UI之間沒有太好的同步手段,往往需要在頁面和對應(yīng)的數(shù)據(jù)實體中同時都維護一份相同的數(shù)據(jù),操作十分的不方便。

之前使用過Taro以react+redux的結(jié)構(gòu)來開發(fā)微信小程序,依托redux整體上可以解決上述的問題。但是Taro本身也有著一些讓人無法接受的潛在問題。本著能用原生就絕不使用第三方二次封裝的庫的原則。一直想嘗試一下在原生微信小程序開發(fā)中接入redux。

需要解決的問題

1、redux庫的接入
2、頁面UI與redux數(shù)據(jù)的綁定

redux庫的引入

1、redux的安裝,使用 npm與yarn 都可以。
具體到redux中文官網(wǎng)如下:https://www.reduxjs.cn/introduction/getting-started/
2、微信小程序引入外部npm包。
使用微信小程序IDEA,tools 中的 Build npm,生成miniprogram_npm。

3、redux庫ReferenceError: process is not defined報錯的解決。

因為微信小程序Build npm工具,構(gòu)建時不會引入nodeprocess環(huán)境變量,但是redux對不同env做了對應(yīng)的優(yōu)化。所以導(dǎo)致構(gòu)建出來的包缺失process變量。最便捷的解決方法是在構(gòu)建完成的包中自己注入需要的process。

這樣基本可以解決所有第三方庫遇到的process參數(shù)缺失的問題。如果每次運行Build npm工具后都需要手動修改。如果有多個第三方庫需要手動修改,那就很麻煩。所以很有必要通過腳本,使用ast樹等工具完整動態(tài)修改,節(jié)省人力成本(這個后續(xù)介紹)

綜上,redux的引入就完成了。

在項目中添加redux

1、store的創(chuàng)建

使用combineReducers合并不同的實體,使用createStore創(chuàng)建store實體,并導(dǎo)出。為了數(shù)據(jù)的統(tǒng)一性,redux的原則是一個項目只初始化一個store,所以后續(xù)任何的操作都是在當前生成的store中進行。

合并數(shù)據(jù)實體:

const { combineReducers } = require('redux');
const testItem = require('./testItem/index');
const testItem2 = require('./testItem2/index');
const user = require('./user/index');

const reducer = combineReducers({
 testItem: testItem.testItem,
 testItem2,
 user
});

module.exports = {
 reducer
}

導(dǎo)出store:

const { createStore, applyMiddleware } = require('redux');
const { reducer } = require('./reducers');
const { logger } = require('redux-logger');

const store = createStore(
 reducer,
 applyMiddleware(logger)
)

module.exports = {
 store
}

2、全局維護store

這里和react中的使用方法不同。微信小程序沒有對應(yīng)的控件來全局維護store,所以我的做法是直接在,app.js的globalData中維護,這樣每個頁面都可以直接獲取到store
app.js:

const { store } = require('./redux/index');

//app.js
App({
 globalData: {
  $store: store,
  getState: ()=> store.getState(),
 }
})

模擬connect方法

在react中,connect方法是通過高階組件的方式實現(xiàn)的,但是這個方法并不適用微信小程序。好在redux有提供subscribe方法來監(jiān)聽store中數(shù)據(jù)的變化。所以初步設(shè)計:
1、每當頁面計入或顯示的時候,添加監(jiān)聽,頁面隱藏或銷毀時銷毀監(jiān)聽
2、添加完監(jiān)聽后,模擬 mapState 方法,把對應(yīng) redux 中的數(shù)據(jù)注入到頁面的data中
3、當監(jiān)聽到redux中數(shù)據(jù)變化時,更新頁面data,從而實現(xiàn)頁面UI刷新
4、模擬mapDispatch方法,為頁面提供修改store數(shù)據(jù)的方法

pageW.js:

const { store } = require('../redux/index');

const initPage = (params = {}, connect = []) => {
 const { 
  onLoad = ()=>{},
  onShow = ()=>{},
  onHide = ()=>{},
  onUnload = ()=>{},
  data = {}
  } = params;

 const newPage = {
  ...params,
  // ----------------
  OnLoad(...p) {
   onLoad.bind(this)(...p);
  },
  OnShow(...p) {
   onShow.bind(this)(...p);
  },
  OnHide(...p) {
   onHide.bind(this)(...p);
  },
  OnUnload(...p) {
   onUnload.bind(this)(...p);
  },
  // ----------------
  // 清空監(jiān)聽
  clearStoreSubscribe() {
   if (this.storeSubscribe) {
    this.storeSubscribe();
    this.storeSubscribe = undefined;
   }
  },
  // 獲取redux 中 data
  getNewData() {
   const newItems = {};

   const state = this.$store.getState();

   if (connect) {
    if ( Array.isArray(connect) ) {
     connect.forEach((key) => {
      const value = state[key];
      if (value && this.data[key] !== value) {
       newItems[key] = value
      }
     })
    } else if (typeof connect === 'function') {
     const list = connect(state) || {};
     Object.keys(list).forEach((key) => {
      const value = list[key];
      if (value && this.data[key] !== value) {
       newItems[key] = value
      }
     })
    }
   }

   return newItems;
  },
  // 監(jiān)聽 redux 變化
  handleReduxChange() {
   this.setData({
    ...this.getNewData(),
   });
  },
  // ----------------
  data: {
   ...data
  },
  onLoad(...p) {
   const app = getApp()
   this.$store = app.globalData.$store;
   this.setData({
    ...this.getNewData(),
   });

   this.OnLoad(...p);

   this._isOnLoad = true;
  },
  onShow (...p) {
   if (!this.storeSubscribe) {
    this.storeSubscribe = this.$store.subscribe(()=>this.handleReduxChange());
   }

   if (!this._isOnLoad) {
    this.setData({
     ...this.getNewData(),
    });
   }


   this.OnShow(...p);

   this._isOnLoad = false;
  },
  onHide(...p) {
   this.OnHide(...p);

   this.clearStoreSubscribe();
  },
  onUnload(...p) {
   this.OnUnload(...p);

   this.clearStoreSubscribe();
  },
  // ----------------
  dispatch(...p) {
   if (this.$store) {
    return this.$store.dispatch(...p);
   }
  }
 }

 return newPage;
}

const PageW = (params = {}, mapState = [], mapDispatch = ()=>{}) => {
 const page = initPage({...params}, mapState);
 const dispatchList = mapDispatch(store) || {};

 page.mapDispatch = {
  ...dispatchList
 };

 return Page(page);
}

module.exports = PageW;

PageW 中主要考慮和不足 如下問題:
1、為了保持微信小程序原有生命周名稱不變,所以事先劫持了傳入頁面的生命周期,然后用bind重新在對應(yīng)生命周期完成后觸發(fā)。
2、因為redux更新數(shù)據(jù),都會生成一個新的數(shù)據(jù)對象,所以每當監(jiān)聽到數(shù)據(jù)變化,新數(shù)據(jù)和老數(shù)據(jù)會進行對比,每次setData,只放入確實發(fā)生變化的數(shù)據(jù)
3、頁面中的data,既維護了默認頁面創(chuàng)建的data數(shù)據(jù),又加入了redux connect 后的數(shù)據(jù),但是目前沒有對這個兩個數(shù)據(jù)的命名進行安全的區(qū)分,所以頁面原生data中的數(shù)據(jù)名稱必須與 connect 注入的數(shù)據(jù)不同。

測試頁面:

導(dǎo)入了testItem, testItem2兩個數(shù)據(jù),導(dǎo)入了add2一個方法

const PageW = require('../../pageW/index');
const { ActionsFun } = require('../../redux/testItem/actions');

const page = {
 data: {
  wwj: 4
 },
 onLoad() {
  console.log('sub onLoad');
 },
 onShow() {

 },
 toTest() {
  console.log('toTest');
  wx.navigateTo({
   url: '/pages/test/index'
  })
 },
 button1() {
  console.log('button1');
  this.mapDispatch.add2();
 },
 button2() {
  const { wwj } = this.data;
  this.setData({
   wwj: wwj + 2
  });
 },
}

const mapState = [ 'testItem', 'testItem2' ];

const mapDispatch = ({dispatch}) => {
 return {
  add2: (params) => dispatch(ActionsFun.add(params))
 }
}

PageW(page, mapState, mapDispatch);

到此這篇關(guān)于原生微信小程序開發(fā)中 redux 的使用詳解的文章就介紹到這了,更多相關(guān)小程序 redux使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • JavaScript中的scrollTop詳解(滾動到頂部)

    JavaScript中的scrollTop詳解(滾動到頂部)

    scrollTop是JavaScript中一個非常有用且重要的方法,它用于獲取或設(shè)置元素的垂直滾動條位置,這篇文章主要給大家介紹了關(guān)于JavaScript中scrollTop詳解(滾動到頂部)的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • uni-app基本的數(shù)據(jù)綁定v-bind,v-for,v-on:click詳解

    uni-app基本的數(shù)據(jù)綁定v-bind,v-for,v-on:click詳解

    這篇文章主要介紹了uni-app基本的數(shù)據(jù)綁定v-bind,v-for,v-on:click,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2024-08-08
  • json屬性名為什么要雙引號(個人猜測)

    json屬性名為什么要雙引號(個人猜測)

    json屬性名為什么要雙引號?更加規(guī)范,利于解析、避免class等關(guān)鍵字引起的不兼容問題,需要的朋友可以參考下
    2014-07-07
  • js為什么不能正確處理小數(shù)運算?

    js為什么不能正確處理小數(shù)運算?

    這篇文章主要介紹了js不能正確處理小數(shù)運算的原因,為大家解除js為什么不能正確處理小數(shù)運算的疑慮,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 原生js實現(xiàn)fadein 和 fadeout淡入淡出效果

    原生js實現(xiàn)fadein 和 fadeout淡入淡出效果

    這篇文章主要介紹了通過原生js實現(xiàn)fadein 和 fadeout淡入淡出效果,需要的朋友可以參考下
    2014-06-06
  • JS判定是否原生方法

    JS判定是否原生方法

    這篇文章介紹了js判定是否原生方法,有需要的朋友可以參考一下
    2013-07-07
  • JS操作XML實例總結(jié)(加載與解析XML文件、字符串)

    JS操作XML實例總結(jié)(加載與解析XML文件、字符串)

    這篇文章主要介紹了JS操作XML的方法,結(jié)合實例形式總結(jié)分析了JavaScript加載與解析XML文件及字符串的相關(guān)技巧,需要的朋友可以參考下
    2015-12-12
  • JS中Attr的用法詳解

    JS中Attr的用法詳解

    本文通過實例代碼給大家介紹了js中的attr的用法,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-10-10
  • 詳細解密jsonp跨域請求

    詳細解密jsonp跨域請求

    當進行一些比較深入的前端編程的時候,不可避免地需要進行跨域操作,JSONP跨域GET請求是一個常用的解決方案,下面我們來看一下JSONP跨域是如何實現(xiàn)的,并且探討下JSONP跨域的原理。
    2015-04-04
  • 微信小程序調(diào)用天氣接口并且渲染在頁面過程詳解

    微信小程序調(diào)用天氣接口并且渲染在頁面過程詳解

    這篇文章主要介紹了微信小程序調(diào)用天氣接口并且渲染在頁面過程詳解,今天寫一個具體的例子,調(diào)用一個免費的天氣接口的api,并且把所獲取的內(nèi)容展示在前端的界面,前端界面與 iView Weapp結(jié)合,需要的朋友可以參考下
    2019-06-06

最新評論

广安市| 西畴县| 常山县| 凤翔县| 周宁县| 莒南县| 乌兰县| 临澧县| 南澳县| 防城港市| 沙河市| 南乐县| 莱西市| 雷波县| 昭平县| 盈江县| 昌宁县| 南华县| 屏山县| 衡阳县| 高州市| 山东省| 文化| 康保县| 措美县| 青田县| 永定县| 托克逊县| 云林县| 荔波县| 莲花县| 精河县| 玉溪市| 盐城市| 白河县| 方城县| 安龙县| 罗源县| 武功县| 景宁| 太康县|