首页前端开发JavaScript手写Vue2.0 数据劫持的示例

手写Vue2.0 数据劫持的示例

时间2024-02-01 01:02:02发布访客分类JavaScript浏览292
导读:收集整理的这篇文章主要介绍了手写Vue2.0 数据劫持的示例,觉得挺不错的,现在分享给大家,也给大家做个参考。 @H_777_0@目录一:搭建webpack二:数据劫持三:总结一:搭建w...
收集整理的这篇文章主要介绍了手写Vue2.0 数据劫持的示例,觉得挺不错的,现在分享给大家,也给大家做个参考。 @H_777_0@
目录
  • 一:搭建webpack
  • 二:数据劫持
  • 三:总结

一:搭建webpack

简单的搭建一下webpack的配置。新建一个文件夹,然后inIT一下。之后新建一个webpack.config.js文件,这是webpack的配置文件。安装一下简单的依赖。

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

在同级目录下新建一个public/index.htML和src/index.js,作为出口文件和入口文件。

j简单配置一下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就可以开始正题了。

二:数据劫持

在v2中,通过new Vue(el, options)的方式,完成vue的实例化。我们需要新建一下vue文件,把数据劫持的方法统一到vue中。

新建一个vue/index.js,作为数据劫持的入口文件。

import {
initstate}
     From './init.js';
function Vue (options) {
     this._init(options);
  // 数据初始化}
Vue.PRototyPE._init = function (options) {
     VAR vm = options;
     // 保存一下实例 vm.$options = options;
     // 实例挂载 initState(vm);
   // 实例初始化}
    

新建一个init.js文件初始化实例:

初始化的时候注意几个问题: 

1.  需要分别对computed,watch, data进行处理。

2. 不要在用户定义的data上直接修改。

3. 官方指定data为函数,是为了保证组件内部有自己的作用域不会有污染,直接访问data函数是不行的,需要自动执行。data也可以是对象(需要考虑到这个情况)

4. 这种方式获取data是通过vm._data.xxx 但是在vue中不需要data来获取,所以这里需要拦截重写。

5. 内部的引用类型需要递归

function initState (vm) {
     var options = vm.$options;
 // 获取options if (options.data) {
      initData(vm);
 // 因为computed,watch都需要在这里初始化,所以针对data初始化}
    ;
function initData (vm) {
     var data = vm.$options.data;
 // 对data重新赋值,不要改变用户定义的data data = vm._data = typeof data === 'function' ? data.call(vm) : data || {
}
    ;
 for (var key in data) {
      ProxyData(vm, '_data', key);
   // 对data的取值重新赋值 }
    ;
     observe(vm._data);
 // 对data内部进行观察}
    

新建一个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;
    

处理好了访问问题,现在需要递归一下data内部元素。obseve(vm._data);

新建一个observe.js:

function observe (data) {
     if (typeof data !== 'object' || data = null) return;
     return new Observer(data);
 // 如果是应用类型,直接添加一个观察者}
     

新建一个观察者:observer.js

function Observer(data) {
 if (Array.isArray(data)) {
      // 处理数组   data._proto_ = arrMethods;
  }
 else {
      // 处理对象  this.walks(data);
 }
}
Observer.prototype.walks = function (data) {
     let keys = Object.keys(data);
     // 拿到data下面所有的key,并且还是一个数组 for (var i = 0 ;
     i  keys.length ;
 i++) {
        var key = keys[i];
        var value = data[key];
        defineReactiveData(data, key, value);
 // 每个重新生成响应式数据  }
}
    

新建一个reactive.js 处理对象等响应式

function defineReactiveData (data, key, value) {
      observe(value);
  // 对子元素接着递归。  Object.defineProperty(data, key, {
    get() {
          return value;
    }
,    set (newValue) {
          if (newValue === value) return;
          value = newValue;
  // 触发更改    }
  }
 )}
    ;
    

ok,这里处理好了对象的数据劫持,剩余的需要处理数组了

在V2中采用重写原型上的7种方法,做到数据劫持。

劫持数组:

新建一个Array.js文件:

import {
ARR_METHODS}
     from './config.js';
       // 7个数组方法的合集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);
     // 类数组转为数组    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): 数组也可能有嵌套,所以需要对数据进行观察。

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

三:总结

 基本流程就是这样的,不仅仅是object.defineProperty对数据进行get和set这么简单。总结一下主要流程:

(1): 在初始化的时候:保存一下实例,挂载实例。通过initState方法来初始化数据,这里主要是data数据,也有computed和watch需要处理。

(2): 调用initData(); 重新赋值data,然后执行data,修改用户获取data属性的写法统一为this.xxx同时observe(data)

(3):在observe(data)的时候需要对data进行判断,如果是引用类型需要加上一个观察者observer,同时在观察者终判断data是为数组还是对象,对象直接重新触发object.defineProperty,同时对内部重新observe。如果是数组直接重新7种数组方法,然后对数组内部接着observe。

以上就是手写Vue2.0 数据劫持的示例的详细内容,更多关于手写vue 数据劫持的资料请关注其它相关文章!

您可能感兴趣的文章:@H_182_126@
  • vue2.0实战之基础入门(1)
  • Vue2.0 实现页面缓存和不缓存的方式
  • vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
  • vue2.0+SVG实现音乐播放圆形进度条组件
  • Vue2.0实现简单分页及跳转效果
  • Vue 2.0 基础详细
  • 声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

    vue数据劫持"

    若转载请注明出处: 手写Vue2.0 数据劫持的示例
    本文地址: https://pptw.com/jishu/594714.html
    vue3.0封装轮播图组件的步骤 C语言中快速排序法怎么排

    游客 回复需填写必要信息