内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

如何實(shí)現(xiàn)vue2.x數(shù)組劫持

小編這次要給大家分享的是如何實(shí)現(xiàn)vue2.x數(shù)組劫持,文章內(nèi)容豐富,感興趣的小伙伴可以來(lái)了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的興縣網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

接上篇Vue2.x 對(duì)象劫持,繼續(xù)來(lái)寫(xiě)數(shù)組劫持

實(shí)現(xiàn)原理:
1 重新定義原生數(shù)組方法push unshift shift pop splice sort reverse 因?yàn)檫@些方法可以修改原數(shù)組。
2 拿到原生數(shù)組方法 Object.create(Array.prototype)
3 AOP攔截,再執(zhí)行重寫(xiě)數(shù)組方法前,先執(zhí)行原生數(shù)組方法

核心監(jiān)聽(tīng)Observer代碼

// 把data中的數(shù)據(jù) 都使用Object.defineProperty重新定義 es5
// Object.defineProperty 不能兼容ie8 及以下 vue2 無(wú)法兼容ie8版本
import {arrayMethods} from './array.js'
import {
  isObject,def
} from '../util/index'
// 后續(xù)我可以知道它是不是一個(gè)已經(jīng)觀察了的數(shù)據(jù) __ob__
class Observer{
  constructor(value){ // 僅僅是初始化的操作
    // vue如果數(shù)據(jù)的層次過(guò)多 需要遞歸的去解析對(duì)象中的屬性,依次增加set和get方法
    // value.__ob__ = this; // 我給每一個(gè)監(jiān)控過(guò)的對(duì)象都增加一個(gè)__ob__屬性
    def(value,'__ob__',this);
    if(Array.isArray(value)){
      // 如果是數(shù)組的話并不會(huì)對(duì)索引進(jìn)行觀測(cè) 因?yàn)闀?huì)導(dǎo)致性能問(wèn)題
      // 前端開(kāi)發(fā)中很少很少 去操作索引 push shift unshift 
      value.__proto__ = arrayMethods;
      // 如果數(shù)組里放的是對(duì)象我再監(jiān)控
      this.observerArray(value);
    }else{
       // 對(duì)數(shù)組監(jiān)控
      this.walk(value); // 對(duì)對(duì)象進(jìn)行觀測(cè)
    }
  }
  observerArray(value){ // [{}]
    for(let i = 0; i < value.length;i++){
      observe(value[i]);
    }
  }
  walk(data){
    let keys = Object.keys(data); // [name,age,address]
    // 如果這個(gè)data 不可配置 直接reurn
    keys.forEach((key)=>{
      defineReactive(data,key,data[key]);
    });
  }
}
function defineReactive(data,key,value){

  observe(value); // 遞歸實(shí)現(xiàn)深度檢測(cè)
  Object.defineProperty(data,key,{
    configurable:true,
    enumerable:false,
    get(){ // 獲取值的時(shí)候做一些操作
      return value;
    },
    set(newValue){ // 也可以做一些操作
      console.log('更新數(shù)據(jù)')
      if(newValue === value) return;
      observe(newValue); // 繼續(xù)劫持用戶設(shè)置的值,因?yàn)橛锌赡苡脩粼O(shè)置的值是一個(gè)對(duì)象
      value = newValue;
    }
  });
}

export function observe(data) {
  let isObj = isObject(data);
  if (!isObj) {
    return
  }
  return new Observer(data); // 用來(lái)觀測(cè)數(shù)據(jù)
}

重寫(xiě)原生數(shù)組方法

// 我要重寫(xiě)數(shù)組的那些方法 7個(gè) push shift unshift pop reverse sort splice 會(huì)導(dǎo)致數(shù)組本身發(fā)生變化
// slice()


let oldArrayMethods = Array.prototype;
// value.__proto__ = arrayMethods 原型鏈查找的問(wèn)題, 會(huì)向上查找,先查找我重寫(xiě)的,重寫(xiě)的沒(méi)有會(huì)繼續(xù)向上查找
// arrayMethods.__proto__ = oldArrayMethods
export const arrayMethods = Object.create(oldArrayMethods); 

const methods = [
  'push',
  'shift',
  'unshift',
  'pop',
  'sort',
  'splice',
  'reverse'
]
methods.forEach(method=>{
  arrayMethods[method] = function (...args) { 
    const result = oldArrayMethods[method].apply(this,args); // 調(diào)用原生的數(shù)組方法
    // push unshift 添加的元素可能還是一個(gè)對(duì)象
    let inserted; // 當(dāng)前用戶插入的元素
    let ob = this.__ob__;
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args;
        break;
      case 'splice': // 3個(gè) 新增的屬性 splice 有刪除 新增的的功能 arr.splice(0,1,{name:1})
        inserted = args.slice(2)
      default:
        break;
    }
    if(inserted) ob.observerArray(inserted); // 將新增屬性繼續(xù)觀測(cè)


    return result;
  }
})

工具方法定義如下:

/**
 * 
 * @param {*} data 當(dāng)前數(shù)據(jù)是不是對(duì)象
 */
export function isObject(data) {
  return typeof data === 'object' && data !== null;
}
export function def(data,key,value){
  Object.defineProperty(data,key,{
    enumerable:false,
    configurable:false,
    value
  })
}

看完這篇關(guān)于如何實(shí)現(xiàn)vue2.x數(shù)組劫持的文章,如果覺(jué)得文章內(nèi)容寫(xiě)得不錯(cuò)的話,可以把它分享出去給更多人看到。

當(dāng)前題目:如何實(shí)現(xiàn)vue2.x數(shù)組劫持
URL鏈接:http://m.rwnh.cn/article34/gspgse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、小程序開(kāi)發(fā)、定制網(wǎng)站、網(wǎng)站營(yíng)銷、網(wǎng)站維護(hù)網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司
灵璧县| 朔州市| 广饶县| 崇义县| 靖州| 宾阳县| 霍城县| 堆龙德庆县| 尼木县| 敦化市| 余姚市| 上高县| 车致| 额敏县| 吉安市| 广安市| 油尖旺区| 万州区| 清流县| 石楼县| 岳池县| 肇东市| 扬中市| 陆丰市| 高州市| 施秉县| 墨玉县| 金华市| 高青县| 唐山市| 青川县| 沂南县| 清远市| 什邡市| 临泉县| 广水市| 英吉沙县| 建德市| 无棣县| 大同县| 霸州市|