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

vue中defineProperty和Proxy的區(qū)別詳解

 更新時(shí)間:2020年11月30日 11:13:03   作者:南藍(lán)  
這篇文章主要介紹了vue中defineProperty和Proxy的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Proxy的出現(xiàn),給vue響應(yīng)式帶來了極大的便利,比如可以直接劫持?jǐn)?shù)組、對象的改變,可以直接添加對象屬性,但是兼容性可能會(huì)有些問題

Proxy可以劫持的數(shù)組的改變,defineProperty 需要變異

defineProperty 中劫持?jǐn)?shù)組變化的變異的方法

可以理解為在數(shù)組實(shí)例和原型之間,插入了一個(gè)新的原型的對象,這個(gè)原型方法實(shí)現(xiàn)了變異的方法,也就真正地?cái)r截了數(shù)組原型上的方法

我們來看下vue2.x的源碼

// vue 2.5.0
var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto); // Array {}
function def(obj, key, val, enumerable) {
  Object.defineProperty(obj, key, {
   value: val,
   enumerable: !!enumerable,
   writable: true,
   configurable: true
  });
}
var methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
  ];

  /**
  * Intercept mutating methods and emit events
  */
  methodsToPatch.forEach(function(method) {
  // cache original method
  var original = arrayProto[method]; 
    // 比如 method是push,則結(jié)果為
    // ƒ push() { [native code] }
  def(arrayMethods, method, function mutator() {
   var args = [],
   len = arguments.length;
   while (len--) args[len] = arguments[len];

   var result = original.apply(this, args);
   var ob = this.__ob__;
   var inserted;
   switch (method) {
   case 'push':
   case 'unshift':
    inserted = args;
    break
   case 'splice':
    inserted = args.slice(2);
    break
   }
   if (inserted) {
   ob.observeArray(inserted);
   }
   // notify change
   ob.dep.notify();
   return result
  });
  });
  
  /**
  * Observe a list of Array items.
  */
  Observer.prototype.observeArray = function observeArray(items) {
  for (var i = 0, l = items.length; i < l; i++) {
   observe(items[i]); // 后續(xù)的邏輯
  }
  };

Proxy可以直接劫持?jǐn)?shù)組的改變

  let proxy = new Proxy(fruit, {
    get: function (obj, prop) {
      return prop in obj ? obj[prop] : undefined

    },
    set: function (obj, prop, newVal) {
      obj[prop] = newVal
      console.log("newVal", newVal) // 輸出{ name: "lemon", num: 999 }
      return true;
    }
  })
  proxy.push({ name: "lemon", num: 999 })
  console.log(fruit)

Proxy代理可以劫持對象的改變,defineProperty需要遍歷

defineProperty

   let fruit = {
     "apple": 2,
     "pear": 22,
     "peach": 222
  }
  Object.keys(fruit).forEach(function (key) {
      Object.defineProperty(fruit[i], key, {
        enumerable: true,
        configurable: true,
        get: function () {
          return val;

        },
        set: function (newVal) {
          val = newVal; // 輸出 newVal 888
          console.log("newVal", newVal)
        }
      })
    })
   fruit.apple = 888

Proxy

   let fruit = {
     "apple": 2,
     "pear": 22,
     "peach": 222
  }
  let proxy = new Proxy(fruit, {
    get: function (obj, prop) {
      return prop in obj ? obj[prop] : undefined

    },
    set: function (obj, prop, newVal) {
      obj[prop] = newVal
      console.log("newVal", newVal) // 輸出 newVal 888
      return true;
    }
  })
  proxy.apple = 888

Proxy代理可以劫持對象屬性的添加,defineProperty用this.$set來實(shí)現(xiàn)
defineProperty,如果屬性不存在,則需要借助this.$set

<div id="app">
  <span v-for="(value,name) in fruit">{{name}}:{{value}}個(gè) </span> 
  <button @click="add()">添加檸檬</button>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
  new Vue({
    el: '#app',
    data() {
      return {
        fruit: {
          apple: 1, 
          banana: 4, 
          orange: 5 
        }
      }
    },

    methods: {
      add() {
          this.fruit.lemon = 5;  // 不會(huì)讓視圖發(fā)生變化
        // this.$set(this.fruit,"lemon",5)  // this.$set可以
      }
    }
  })
</script>

  Object.keys(fruit).forEach(function (key) {
    Object.defineProperty(fruit, key, {
      enumerable: true,
      configurable: true,
      get: function () {
        return val;

      },
      set: function (newVal) {
        val = newVal;
        console.log("newVal", newVal) // 根本沒有進(jìn)去這里
      }
    })
  })

Proxy 直接可以添加屬性

// vue 3
<div id="app">
  <span v-for="(value,name) in fruit">{{name}}:{{value}}個(gè) </span>
  <button @click="add()">添加檸檬</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  Vue.createApp({
    data() {
      return {
        fruit: {
          apple: 1,
          banana: 4,
          orange: 5
        }
      }
    },

    methods: {
      add() {
        this.fruit.lemon = 5; // 這樣子是可以的
      }
    }
  }).mount('#app') // vue 3 不再是使用el屬性,而是使用mount
</script>

  let proxy = new Proxy(fruit, {
    get: function (obj, prop) {
      return prop in obj ? obj[prop] : undefined

    },
    set: function (obj, prop, newVal) {
      obj[prop] = newVal
      console.log("newVal", newVal) // lemon, 888
      return true;
    }
  })
  proxy.lemon = 888

Proxy

其他屬性

應(yīng)用場景 promisify化

用Proxy寫一個(gè)場景,請求都是通過回調(diào),如果我們需要用promise包一層的話,則可以

// server.js
// 假設(shè)這里都是回調(diào)
export const searchResultList = function (data, callback, errorCallback) {
 axios.post(url, data, callback, errorCallback)
}
// promisify.js
import * as server from './server.js'
const promisify = (name,obj) => (option) => {
 return new Promise((resolve, reject) => {
  return obj[name](
   option,
   resolve,
   reject,
  )
 })
}
const serverPromisify = new Proxy(server, {
 get (target,prop) {
  return promisify(prop, server)
 }
})
export default serverPromisify

使用

// index.js
import serverPromisify from './serverPromisify'
serverPromisify.searchResultList(data).then(res=>{

})

如有不正確,望請指出

留下一個(gè)疑問,既然兼容性不是很好,那么尤大是怎么處理polyfill呢

 到此這篇關(guān)于vue中defineProperty和Proxy的區(qū)別詳解的文章就介紹到這了,更多相關(guān)vue defineProperty和Proxy內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Vue+Node.js實(shí)現(xiàn)埋點(diǎn)功能全流程

    基于Vue+Node.js實(shí)現(xiàn)埋點(diǎn)功能全流程

    埋點(diǎn)(Track)是指在應(yīng)用程序、網(wǎng)站或平臺(tái)中添加代碼,以記錄特定用戶行為和事件的做法,通過添加埋點(diǎn)代碼,可以觀察和分析用戶行為,以調(diào)整和改進(jìn)產(chǎn)品設(shè)計(jì)和使用體驗(yàn),本文給大家介紹了基于Vue+Node.js實(shí)現(xiàn)埋點(diǎn)功能的全流程,需要的朋友可以參考下
    2025-04-04
  • 父子組件生命周期及子組件獲取數(shù)據(jù)傳值問題剖析

    父子組件生命周期及子組件獲取數(shù)據(jù)傳值問題剖析

    這篇文章主要介紹了父子組件生命周期及子組件獲取數(shù)據(jù)問題剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • vue不操作dom實(shí)現(xiàn)圖片輪播的示例代碼

    vue不操作dom實(shí)現(xiàn)圖片輪播的示例代碼

    這篇文章主要介紹了vue不操作dom實(shí)現(xiàn)圖片輪播的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • vue proxyTable的跨域中pathRewrite配置方式

    vue proxyTable的跨域中pathRewrite配置方式

    這篇文章主要介紹了vue proxyTable的跨域中pathRewrite配置方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue組件間傳值的方法你知道幾種

    vue組件間傳值的方法你知道幾種

    這篇文章主要為大家詳細(xì)介紹了vue組件間傳值的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Vue2.0設(shè)置全局樣式(less/sass和css)

    Vue2.0設(shè)置全局樣式(less/sass和css)

    這篇文章主要為大家詳細(xì)介紹了Vue2.0設(shè)置全局樣式(less/sass和css),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • vue檢測對象和數(shù)組的變化分析

    vue檢測對象和數(shù)組的變化分析

    這篇文章給大家分享了vue檢測對象和數(shù)組的變化的相關(guān)知識(shí)點(diǎn)與實(shí)例代碼,有興趣的朋友參考下。
    2018-06-06
  • Vue2純前端實(shí)現(xiàn)文字流式輸出效果

    Vue2純前端實(shí)現(xiàn)文字流式輸出效果

    這篇文章主要為大家詳細(xì)介紹了Vue2純前端實(shí)現(xiàn)像chatGpt和Deepseek那樣的文字流式輸出效果的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),有需要的可以了解下
    2025-03-03
  • Vue.use()的用法和install的用法解析

    Vue.use()的用法和install的用法解析

    這篇文章主要介紹了Vue.use()的用法和install的用法解析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • vue keepAlive緩存清除問題案例詳解

    vue keepAlive緩存清除問題案例詳解

    這篇文章主要介紹了vue keepAlive緩存清除問題案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09

最新評論

博罗县| 肇东市| 澄迈县| 南部县| 台南市| 济南市| 石首市| 张家口市| 万州区| 碌曲县| 农安县| 都昌县| 辽源市| 若羌县| 永仁县| 长武县| 博爱县| 南城县| 长海县| 民丰县| 丁青县| 乐山市| 包头市| 东方市| 怀来县| 万年县| 沙雅县| 肇源县| 胶南市| 咸阳市| 海伦市| 松溪县| 岳普湖县| 离岛区| 双桥区| 泽库县| 闸北区| 通渭县| 新乡市| 玛纳斯县| 芦溪县|