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

手寫(xiě)Vue2.0 數(shù)據(jù)劫持的示例

 更新時(shí)間:2021年03月04日 11:04:27   作者:梳碧湖的砍柴人  
這篇文章主要介紹了手寫(xiě)Vue2.0 數(shù)據(jù)劫持的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下

一:搭建webpack

簡(jiǎn)單的搭建一下webpack的配置。新建一個(gè)文件夾,然后init一下。之后新建一個(gè)webpack.config.js文件,這是webpack的配置文件。安裝一下簡(jiǎn)單的依賴(lài)。

npm install webpack webpack-cli webpack-dev-server -D

在同級(jí)目錄下新建一個(gè)public/index.html和src/index.js,作為出口文件和入口文件。

j簡(jiǎn)單配置一下webpack, 在webpack.config.js文件中:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
 entry: './src/index.js',
 output: {
  filename: 'bundle.js',
  path: path.resolve(__dirname, 'dist')
 },
 resolve: { 
  modules: [
  path.resolve(__dirname, ''), path.resolve(__dirname, 'node_modules')  
  ] 
 },
 plugins: [  
  new HtmlWebpackPlugin({   
   template: path.resolve(__dirname, 'public/index.html')  
  }) 
 ]
}

ok,基本配置好webpack就可以開(kāi)始正題了。

二:數(shù)據(jù)劫持

在v2中,通過(guò)new Vue(el, options)的方式,完成vue的實(shí)例化。我們需要新建一下vue文件,把數(shù)據(jù)劫持的方法統(tǒng)一到vue中。

新建一個(gè)vue/index.js,作為數(shù)據(jù)劫持的入口文件。

import {initState} from './init.js';

function Vue (options) {
 this._init(options);  // 數(shù)據(jù)初始化
}
Vue.prototype._init = function (options) {
 var vm = options; // 保存一下實(shí)例
 vm.$options = options; // 實(shí)例掛載
 initState(vm);   // 實(shí)例初始化
}

新建一個(gè)init.js文件初始化實(shí)例:

初始化的時(shí)候注意幾個(gè)問(wèn)題: 

1.  需要分別對(duì)computed,watch, data進(jìn)行處理。

2. 不要在用戶(hù)定義的data上直接修改。

3. 官方指定data為函數(shù),是為了保證組件內(nèi)部有自己的作用域不會(huì)有污染,直接訪問(wèn)data函數(shù)是不行的,需要自動(dòng)執(zhí)行。data也可以是對(duì)象(需要考慮到這個(gè)情況)

4. 這種方式獲取data是通過(guò)vm._data.xxx 但是在vue中不需要data來(lái)獲取,所以這里需要攔截重寫(xiě)。

5. 內(nèi)部的引用類(lèi)型需要遞歸

function initState (vm) {
 var options = vm.$options; // 獲取options
 if (options.data) {
  initData(vm); // 因?yàn)閏omputed,watch都需要在這里初始化,所以針對(duì)data初始化
};

function initData (vm) {
 var data = vm.$options.data; // 對(duì)data重新賦值,不要改變用戶(hù)定義的data
 data = vm._data = typeof data === 'function' ? data.call(vm) : data || {};
 for (var key in data) {
  proxyData(vm, '_data', key);   // 對(duì)data的取值重新賦值
 };
 observe(vm._data); // 對(duì)data內(nèi)部進(jìn)行觀察
}

新建一個(gè)proxy.js作為代理層:

function proxyData(vm, target, key) { 
 Object.defineProperty(vm, key, {  
   get () {   
   // 這里做了攔截: vm.xxx => vm._data.xxx   
   return vm[target][key];  
  },  
  set(newValue) {   
   // vm.xxx = yyy ===> vm._data.title = yyy   
   vm[target][key] = newValue;  
  } 
 }) 
}
export default proxyData;

處理好了訪問(wèn)問(wèn)題,現(xiàn)在需要遞歸一下data內(nèi)部元素。obseve(vm._data);

新建一個(gè)observe.js:

function observe (data) {
 if (typeof data !== 'object' || data = null) return;
 return new Observer(data); // 如果是應(yīng)用類(lèi)型,直接添加一個(gè)觀察者
} 

新建一個(gè)觀察者:observer.js

function Observer(data) {
 if (Array.isArray(data)) {
  // 處理數(shù)組
   data._proto_ = arrMethods; 
 }
 else {
  // 處理對(duì)象
  this.walks(data);
 }
}
Observer.prototype.walks = function (data) {
 let keys = Object.keys(data); // 拿到data下面所有的key,并且還是一個(gè)數(shù)組
 for (var i = 0 ; i < keys.length ; i++) {  
  var key = keys[i];  
  var value = data[key];  
  defineReactiveData(data, key, value); // 每個(gè)重新生成響應(yīng)式數(shù)據(jù) 
 }}

新建一個(gè)reactive.js 處理對(duì)象等響應(yīng)式

function defineReactiveData (data, key, value) { 
 observe(value);  // 對(duì)子元素接著遞歸。 
 Object.defineProperty(data, key, {  
  get() {   
   return value;  
  },  
  set (newValue) {   
   if (newValue === value) return;   
   value = newValue;  // 觸發(fā)更改  
  } 
 }
 )
};

ok,這里處理好了對(duì)象的數(shù)據(jù)劫持,剩余的需要處理數(shù)組了

在V2中采用重寫(xiě)原型上的7種方法,做到數(shù)據(jù)劫持。

劫持?jǐn)?shù)組:

新建一個(gè)Array.js文件:

import {ARR_METHODS} from './config.js';  
 // 7個(gè)數(shù)組方法的合集
import observeArr from './observeArr.js';
var originArrMethods = Array.prototype, 
arrMethods = Object.create(originArrMethods); 
ARR_METHODS.map(function (m) { 
 arrMethods[m] = function () {  
  var args = Array.prototype.slice.call(arguments); // 類(lèi)數(shù)組轉(zhuǎn)為數(shù)組  
  var rt = originArrMethods[m].apply(this, args);  
  var newArr;  
  switch (m) {   
   case 'push':   
   case 'ushift':     
    newArr = args;   
   case 'splice':    
    newArr = args.slice(2);    
    break;   
   default:     
    break;  };  
  newArr && observeArr(newArr);  
  return rt; 
  } 
}); 
 export { arrMethods }

observeArr(newArr): 數(shù)組也可能有嵌套,所以需要對(duì)數(shù)據(jù)進(jìn)行觀察。

import observe from "./observe";
function observeArr (arr) { 
 for (var i = 0 ; i < arr.length ; i++) {  
  observe(arr[i]); // 重新走到了observe上。 
 }
}
export default observeArr;

三:總結(jié)

 基本流程就是這樣的,不僅僅是object.defineProperty對(duì)數(shù)據(jù)進(jìn)行g(shù)et和set這么簡(jiǎn)單??偨Y(jié)一下主要流程:

(1): 在初始化的時(shí)候:保存一下實(shí)例,掛載實(shí)例。通過(guò)initState方法來(lái)初始化數(shù)據(jù),這里主要是data數(shù)據(jù),也有computed和watch需要處理。

(2): 調(diào)用initData(); 重新賦值data,然后執(zhí)行data,修改用戶(hù)獲取data屬性的寫(xiě)法統(tǒng)一為this.xxx同時(shí)observe(data)

(3):在observe(data)的時(shí)候需要對(duì)data進(jìn)行判斷,如果是引用類(lèi)型需要加上一個(gè)觀察者observer,同時(shí)在觀察者終判斷data是為數(shù)組還是對(duì)象,對(duì)象直接重新觸發(fā)object.defineProperty,同時(shí)對(duì)內(nèi)部重新observe。如果是數(shù)組直接重新7種數(shù)組方法,然后對(duì)數(shù)組內(nèi)部接著observe。

以上就是手寫(xiě)Vue2.0 數(shù)據(jù)劫持的示例的詳細(xì)內(nèi)容,更多關(guān)于手寫(xiě)vue 數(shù)據(jù)劫持的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Element Dropdown下拉菜單的使用方法

    Element Dropdown下拉菜單的使用方法

    這篇文章主要介紹了Element Dropdown下拉菜單的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 前端報(bào)錯(cuò)npm ERR! cb() never called!問(wèn)題解決辦法

    前端報(bào)錯(cuò)npm ERR! cb() never called!問(wèn)題解決辦法

    最近接手了一個(gè)前臺(tái)項(xiàng)目,執(zhí)行npm install的時(shí)候一直報(bào)錯(cuò),所以這里就給大家總結(jié)下,這篇文章主要給給大家介紹了關(guān)于前端報(bào)錯(cuò)npm?ERR! cb() never called!問(wèn)題的解決辦法,需要的朋友可以參考下
    2024-05-05
  • Vue中使用create-keyframe-animation與動(dòng)畫(huà)鉤子完成復(fù)雜動(dòng)畫(huà)

    Vue中使用create-keyframe-animation與動(dòng)畫(huà)鉤子完成復(fù)雜動(dòng)畫(huà)

    這篇文章主要介紹了Vue中使用create-keyframe-animation與動(dòng)畫(huà)鉤子完成復(fù)雜動(dòng)畫(huà),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • vue清空數(shù)組的幾個(gè)方式(小結(jié))

    vue清空數(shù)組的幾個(gè)方式(小結(jié))

    本文主要介紹了vue清空數(shù)組的幾個(gè)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 關(guān)于在Vue中import和require的用法分析

    關(guān)于在Vue中import和require的用法分析

    在Vue項(xiàng)目中,我們經(jīng)常需要引入外部的模塊或文件,這時(shí)候就會(huì)用到import和require這兩個(gè)關(guān)鍵字,本文將詳細(xì)分析它們的用法,并提供具體的代碼實(shí)例和解釋,需要的朋友可以參考下
    2023-06-06
  • vue實(shí)現(xiàn)圖片滾動(dòng)的示例代碼(類(lèi)似走馬燈效果)

    vue實(shí)現(xiàn)圖片滾動(dòng)的示例代碼(類(lèi)似走馬燈效果)

    下面小編就為大家分享一篇vue實(shí)現(xiàn)圖片滾動(dòng)的示例代碼(類(lèi)似走馬燈效果),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • vue3?vite異步組件及路由懶加載實(shí)戰(zhàn)示例

    vue3?vite異步組件及路由懶加載實(shí)戰(zhàn)示例

    這篇文章主要為大家介紹了vue3?vite異步組件及路由懶加載實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Vue 使用超圖SuperMap的實(shí)踐

    Vue 使用超圖SuperMap的實(shí)踐

    作為一名剛?cè)腴T(mén)計(jì)算機(jī)語(yǔ)言的人來(lái)說(shuō),要想快速完成測(cè)試開(kāi)發(fā)地圖項(xiàng)目,肯定要接用到SuperMap,本文主要介紹了Vue 使用超圖SuperMap的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Vuex中的Mutation使用詳解

    Vuex中的Mutation使用詳解

    這篇文章主要介紹了Vuex中的Mutation使用詳解,當(dāng)我們想修改狀態(tài)值,想傳入的值進(jìn)而進(jìn)行修改時(shí),你可以向 store.commit 傳入額外的參數(shù),即 mutation 的 載荷,需要的朋友可以參考下
    2023-11-11
  • vue3 高德地圖關(guān)鍵詞搜索獲取經(jīng)緯度的示例代碼

    vue3 高德地圖關(guān)鍵詞搜索獲取經(jīng)緯度的示例代碼

    這篇文章主要介紹了vue3 高德地圖關(guān)鍵詞搜索獲取經(jīng)緯度的示例代碼,需要的朋友可以參考下
    2024-08-08

最新評(píng)論

广汉市| 黄浦区| 辉南县| 扶沟县| 秦安县| 买车| 子长县| 疏附县| 凤翔县| 岑溪市| 福州市| 崇文区| 万源市| 塔河县| 岳池县| 四川省| 金平| 高密市| 称多县| 平度市| 长治县| 舟山市| 永平县| 汉沽区| 厦门市| 肇源县| 绥宁县| 阜康市| 昭通市| 乐都县| 禄劝| 宝清县| 鱼台县| 鹤峰县| 南丹县| 华亭县| 封丘县| 衡山县| 会昌县| 邹城市| 琼结县|