• <ul id="cgeq2"></ul>
  • 歡迎您光臨深圳塔燈網絡科技有限公司!
    電話圖標 余先生:13699882642

    網站百科

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

    小程序技能進階回憶錄 - 自主實現數據偵聽器和計算器

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

    告訴元首我已盡力,告訴父親我仍然愛他!

    熟悉 Vue 的同學對 computedwatch 一定很熟悉,這些特性大大方便了我們對代碼中的數據進行處理:

    var vm = new Vue({
      el: '#example',
      data: {
        message: 'Hello'
      },
      computed: {
        // 計算屬性的 getter
        reversedMessage: function () {
          // `this` 指向 vm 實例
          return this.message.split('').reverse().join('')
        }
      }
    })
    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar',
        fullName: 'Foo Bar'
      },
      watch: {
        firstName: function (val) {
          this.fullName = val + ' ' + this.lastName
        },
        lastName: function (val) {
          this.fullName = this.firstName + ' ' + val
        }
      }
    })

    這是 Vue 官網中兩段代碼。

    官方實現

    如今小程序也有了自己的實現,詳見官方文檔 observer 。小程序官方 github
    中也開源了通過 Behaviors 實現的 Vue 風格的computedwatchhttps://github.com/wechat-miniprogram/computed

    那么在微信沒有提供這些方法之前,如何自主實現數據的偵聽器和計算屬性呢?

    ## 自主實現

    先看看定義的使用文檔:

    Page({
     data: {
       list: [],
       list2: [],
       size: 0
     },
     // 偵聽器函數名必須跟需要被偵聽的 data 對象中的屬性同名,
     // 其參數中的 newValue 為屬性改變后的新值,oldValue 為改變前的舊值
     watch: {
       // 如果 `list` 發生改變,這個函數就會運行
       list(newValue, oldValue) {
         console.log(oldValue + '=>' + newValue)
       }
     },
     // 傳入的參數list必須是 data 里面的屬性
     // 這里可以傳入多個 data 屬性
     computed({
       list,
       list2
     }) {
       return {
         size: list.length,
         size2: list2.length
       }
     }
    })

    Page 的傳參中多了兩個熟悉的屬性,用法不用解釋太多。需要繼續對小程序提供的 Page 方法進行改造,此外,因為所有數據變化都會用到 setData 方法去觸發,所以還需要改造這個方法。

    改造 Page 和 setData

    想要基于原有的 setData 進行封裝,那就得先得到這個函數緩存下來(像是緩存原有的 Page 一樣)。想到 onLoad 是小程序頁面的第一個生命周期函數,可以在這里進行操作:

    // 緩存原有的 `Page`
    let originPage = Page
    
    // 定義新的 Page
    function MyPage(config) {
      let that = this
      this.watch = config.watch
      this.computed = config.computed
      this.lifetimeBackup = {
        onLoad: config.onLoad
      }
      config.onLoad = function(options) {
        // 緩存下原有的 `setData`
        this._setData = this.setData.bind(this)
        this.setData = (data) => {
          // 偵聽器
          that.watching(data)
          // 計算器
          let newData = that.getComputedData(data)
          this._setData(extend(data, newData))
        }
        // 備份下頁面實例
        that.context = this
        // 執行真正的 `onLoad`
        this.lifetimeBackup.onLoad.call(this, options)
      }
      
      // ...
    
      originPage(config)
    }
    
    MyPage.prototype.watching = funtion(data) {
      // 執行偵聽器
      // ...
    }
    
    // 計算器
    MyPage.prototype.getComputedData = function(data) {
      // 開始生成新的數據
      // ...
    }
    
    function page (config) {
      return new MyPage(config)
    }

    大致代碼如上,重新定義了 this.setData,備份了原有的 setDatathis._setData。當然,這里只考慮了 setData 傳一個參數的情況,多個參數需要再對代碼優化下。

    注意:調用 watchingcreateNewData 的對象是 that,因為 this 指向小程序頁面實例,沒有自定的這個方法。

    做完上述改造,后續的 watchcomputed 就簡單多了。

    偵聽器 watch

    MyPage.prototype.watching = function(data) {
      var context = this.context
      var oldData = context.data
      // 開始生成新的數據
      var watch = this.watch
      if (watch) {
        Object.keys(watch).forEach(function (k) {
          // 如果新的 data 中屬性被偵聽,執行偵聽函數
          if (k in data) {
            var newValue = data[k]
            var oldValue = oldData[k]
            watch[k].apply(context, [
              newValue,
              oldValue
            ])
          }
        })
      }
    }

    簡易的偵聽器就寫好了,通過 setData 觸發自定的 watch 中的偵聽函數。

    計算器 computed

    MyPage.prototype.getComputedData = function(data) {
      var context = this.context
      var computed = this.computed
      var computedData
      if (computed) {
        computedData = computed.call(context, data)
      }
      return computedData
    }

    這樣就得到了計算后的新生成的數據:computedData

    總結

    不斷的通過備份、代理微信原有的方法,自主實現了簡單的偵聽器和計算器。當然這些代碼只是為了方便分享提取出來了提供思路,實際業務中遇到情況復雜的多,代碼量遠遠也不止這些。


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

    多一份參考,總有益處

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

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

    業務熱線:余經理:13699882642

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

    精品福利一区二区三区精品国产第一国产综合精品 | 亚洲高清专区日韩精品| 全球AV集中精品导航福利| 网友自拍区视频精品| 九九这里只有精品视频| 久久精品国产亚洲av麻豆小说 | 国产女精品视频在ktv| 中文字幕无码精品三级在线电影 | 国产成人精品福利网站人| 亚洲国产精品白丝在线观看| 亚洲国产成人精品91久久久| 成人精品视频一区二区| 国产成人精品免费久久久久| 国产农村妇女毛片精品久久| 久久精品国产亚洲AV蜜臀色欲 | 人妻少妇精品视频三区二区一区| 久久久久久极精品久久久| 精品欧洲av无码一区二区14| 国产精品久线在线观看| 正在播放酒店精品少妇约| 久久久国产精品va麻豆| 亚洲精品国产成人中文| 久久av老司机精品网站导航| 这里只有精品视频在线| 精品乱码久久久久久久| 99亚洲精品高清一二区| 精品国产一区二区三区2021| 精品无码一区二区三区水蜜桃 | 亚洲AV永久无码精品一区二区国产| 久久久久久精品久久久| 亚洲av无码成人精品区一本二本| 亚洲AV永久无码精品成人| 国产午夜精品无码| 亚洲国产成人精品无码久久久久久综合 | 99久久成人国产精品免费| 日本精品人妻无码免费大全| 色综合久久夜色精品国产| 2020精品自拍视频曝光| 亚洲第一精品在线视频| 中文字幕一区精品| 国产亚洲精品第一综合|