返回顶部
首页 > 资讯 > 精选 >Vue2中的数据劫持怎么实现
  • 261
分享到

Vue2中的数据劫持怎么实现

2023-07-05 05:07:53 261人浏览 泡泡鱼
摘要

今天小编给大家分享一下Vue2中的数据劫持怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。我们今天要编写的项目通过需要

今天小编给大家分享一下Vue2中的数据劫持怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

我们今天要编写的项目通过需要使用 webpack 进行编译,package.JSON 相关依赖如下:

{  "scripts": {    "dev": "WEBpack-dev-server",    "build:": "webpack"  },  "devDependencies": {    "html-webpack-plugin": "^4.5.2",    "webpack": "^4.46.0",    "webpack-cli": "^3.3.12",    "webpack-dev-server": "^3.11.3"  }}

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")  },  devtool: "source-map",  resolve: {    // 表示解析模块引入的时候先从当前文件夹寻找模块,再去 node_modules 找模块    modules: [      path.resolve(__dirname, ""),       path.resolve(__dirname, "node_modules")    ]  },  plugins: [    new HtmlWebpackPlugin({      template: path.resolve(__dirname, "public/index.html")    })  ]};

public/index.html 文件内容如下:

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta Http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title></title>  </head>  <body>    <div id="app"></div>  </body></html>

全部文件目录结构如图:

Vue2中的数据劫持怎么实现

首先,我们需要编写我们的入口文件 index.js,该文件很普通主要就是实例一个模拟的 Vue 应用:

// index.js// 我们在 webpack.config.js 中进行了配置,所以这里优先在当前目录下寻找 vue 文件,也就是我们的 vue/index.js 文件import Vue from "vue"; let vm = new Vue({  el: "#app",  data() {    return {      title: "学生列表",      classNum: 1,      teacher: ["张三", "李四"],      info: {        a: {          b: 1        }      },      students: [        {          id: 1,          name: "小红"        },        {          id: 2,          name: "小明"        }      ]    };  }});console.log(vm);

vue/index.js 文件主要是负责初始化内容:

// src/sindex.jsimport { initState } from "./init";function Vue(options) {  this._init(options);}Vue.prototype._init = function (options) {  // this 指向当前实例对象  var vm = this;  // 我们把 new Vue() 时候传递的数据统称为 options  // 并且挂载到 Vue 的实例对象上  vm.$options = options;  // 调用 initState 初始化 data 数据  initState(vm);};export default Vue;

vue/init.js 文件暴露出一个initState方法,该方法主要是处理初始化的数据:

// vue/init.jsimport proxyData from "./proxy";import observer from "./observe"function initState(vm) {  var options = vm.$options;  // 如果 options 中存在 data 属性,我们才会继续处理  if (options.data) {    initData(vm);  }}function initData(vm) {  var data = vm.$options.data;  // 把 data 数据单独保存到 Vue 的实例化对象上,方便我们获取  // 如果 data 是一个函数,我们需要执行返回得到返回的对象  data = vm._data = typeof data === "function" ? data.call(vm) : data || {};  // 遍历 data 对象,通过 proxyData 对数据进行拦截  for (const key in data) {    // 传入的参数分别是:当前实例、key值(也就是 vm._data)、data 中的 key 值(例如 vm._data.title)    proxyData(vm, "_data", key);  }  // 调用观察者模式  observer(vm._data)}export {   initState};

以上代码,我们通过proxyDatadata中的数据进行拦截,详情如下:

// vue/proxy.jsfunction proxyData(vm, target, key) {  // 当访问 vm.title 的时候转换为 vm._data.title  //(请记住这句话!!!)  Object.defineProperty(vm, key, {    get: function () {      return vm[target][key];    },    set: function (newVal) {      vm[target][key] = newVal;    }  });}export default proxyData;

我们还调用了observer方法进行事件订阅,详细如下:

// vue/observe.jsimport Observer from "./observer"function observe(data) {  // 判断只处理对象,如果不是对象直接返回  if (typeof data !== "object" || data === null) {    return false;  }  // 观察数据  return new Observer(data)}export default observe;

接下来就是我们的核心文件vue/observer.js,该文件主要负责对数据类型进行判断,如果是数组就需要单独处理数组,这个我们后面再说:

// vue/observer.jsimport defineReactiveData from "./reactive";import { arrMethods } from "./array";import observeArr from "./observeArr";// 这个方法会在多个地方调用,请记住这个方法以它的作用function Observer(data) {  // 如果 data 是一个数组,那面需要单独处理  if (Array.isArray(data)) {    // 给数组新增一层原型    data._proto__ = arrMethods;    // 循环数组的每一项,然后让每一项都调用 Observer 方法进行订阅    observeArr(data)  } else {    // 处理对象    this.walk(data);  }}Observer.prototype.walk = function (data) {  // 获取到 data 全部的 key  // 也就是我们定义的 ['title', 'classNum', 'teacher', 'info', 'students']  let keys = Object.keys(data);  for (var i = 0; i < keys.length; i++) {    let key = keys[i];    let value = data[key];    // 拦截 data 数据    // 分别传入参数为:vm._data、data 中的 key、data 中 key 对应的 value    defineReactiveData(data, key, value);  }};export default Observer;

以上代码,我们分别对数组和对象执行不同的操作,我们先来看对象的操作:
Observer构造函数中我们新增了一个walk方法,该方法获取到了所有的key值,然后调用了defineReactiveData进行处理。

// vue/reactive.jsimport observe from "./observe";function defineReactiveData(data, key, value) {  // 例如 info.a 还是个对象,那么就递归观察  observe(value);  // 这里的 data 是 vm._data,所以这里拦截的也是 vm._data  Object.defineProperty(data, key, {    get() {      console.log(`⤴️ 响应式获取:data.${key},`, value);      return value;    },    set(newVal) {      console.log(`???? 响应式设置:data.${key},`, newVal);      if (newVal === value) {        return false;      }      // 如果新值还是对象,那么接着进行观察      observe(newVal);      value = newVal;    }  });}export default defineReactiveData;

以上代码,我们是对vm._data进行拦截的,这是因为我们前面说的proxyData拦截的是vm对象,当访问vm.title的时候,proxyData的拦截就会生效,而proxyData内部是通过vm._data来获取的,这样又会触发defineReactiveData的拦截!

回到vue/observer.js文件,我们还需要对数组进行处理:

import defineReactiveData from "./reactive";import { arrMethods } from "./array";import observeArr from "./observeArr";// 这个方法会在多个地方调用,请记住这个方法以它的作用function Observer(data) {  // 如果 data 是一个数组,那面需要单独处理  if (Array.isArray(data)) {    // 为数组更改原型    data._proto__ = arrMethods;    // 循环数组的每一项,然后让每一项都调用 Observer 方法进行订阅    observeArr(data)  } else {   // ...  }}Observer.prototype.walk = function (data) {  // ...};export default Observer;

以上代码我们对数组更改一个原型arrMethods,那看看它到底做了什么事情:

// vue/array.js// ARR_METHODS 是一些可以更改数组本身的方法,里面包括以下内容,我们就不展开看了// ["push", "pop", "shift", "unshift", "splic", "sort", "reverse"]import { ARR_METHODS } from "./config";import observeArr from "./observeArr";// 把数组本身的元素进行拷贝var originArrayMethods = Array.prototype;// 创建一个空对象,该空对象的原型就是数组的原型var arrMethods = Object.create(originArrayMethods);// 遍历这些数组的方法名称ARR_METHODS.forEach(function (m) {  // 在新对象上重写数组的方法  arrMethods[m] = function () {    // 把数组接到的参数转换为一个数组    var args = Array.prototype.slice.call(arguments);    // 执行数组原本的方法    var rt = originArrayMethods[m].apply(this, args);    var newArr;    switch (m) {      case "push":      case "unshift":        // 例如 arr.push({a: 1})        // args 就是 [{a: 1}]        newArr = args;        break;      case "splice":        // 例如 arr.splice(1, 0, {a: 1}, {b: 2})        // args 就是 [{a: 1}, {b: 2}]        newArr = args.slice(2);        break;      default:        break;    }    // 如果有值那面就调用 observeArr 方法    // observeArr 方法就是循环数组的每一项,然后让每一项都调用 Observer 方法进行订阅    newArr && observeArr(newArr);    return rt;  };});export { arrMethods };

以上代码我们重写了数组相关的方法,这是因为这些方法被并不能被Object.defineProperty拦截到。

详细请看:v-for 列表循环

所以我们通过重写方法的方式,让数组可以正常的执行方法,同时也能被我们的observeArr方法拦截到,所以数组现在就是这样多了一层我们写的原型,但最终它还是继承于Array构造函数的:

Vue2中的数据劫持怎么实现

而我们的observeArr只是遍历了数组的每一项,让每一项都进行了拦截:

// vue/observeArr.jsimport observe from "./observe";function observeArr(arr) {  for (let i = 0; i < arr.length; i++) {    // 又回到了起点,进行更新订阅    observe(arr[i]);  }}export default observeArr;

然后我们去index.js文件获取属性,看看结果:

import Vue from "vue";let vm = new Vue({  el: "#app",  data() {    return {      title: "学生列表",      classNum: 1,      teacher: ["张三", "李四"],      info: {        a: {          b: 1        }      },      students: [        {          id: 1,          name: "小红"        },        {          id: 2,          name: "小明"        }      ]    };  }});console.log(vm);console.log(vm.title);console.log(vm.teacher);console.log(vm.info.a);

Vue2中的数据劫持怎么实现

以上就是“Vue2中的数据劫持怎么实现”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: Vue2中的数据劫持怎么实现

本文链接: https://lsjlt.com/news/349865.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue2中的数据劫持怎么实现
    今天小编给大家分享一下Vue2中的数据劫持怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。我们今天要编写的项目通过需要...
    99+
    2023-07-05
  • Vue2 中的数据劫持简写示例
    目录package.json 相关依赖Webpack.config.js 配置文件public/index.html 文件内容全部文件目录结构实例一个模拟的 Vue 应用vue/in...
    99+
    2023-02-23
    Vue2 数据劫持 Vue 数据劫持
  • 微信小程序数据劫持代理的实现
    index.html   index.js // Vue数据劫持代理 //模拟Vue中data选项 let data = { username:'小...
    99+
    2024-04-02
  • JavaScript defineProperty怎么实现属性劫持
    本篇内容主要讲解“JavaScript defineProperty怎么实现属性劫持”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript defineProperty怎么实现属性劫...
    99+
    2023-06-20
  • Couchbase中怎么实现数据持久化
    在Couchbase中,数据持久化可以通过以下几种方式实现: 使用持久化存储引擎:Couchbase支持使用不同的持久化存储引擎...
    99+
    2024-03-08
    Couchbase
  • vue中数据劫持以及操作数组的坑有哪些
    这篇文章将为大家详细讲解有关vue中数据劫持以及操作数组的坑有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。TL;DR给data添加新属性的时候vm.$set(vm....
    99+
    2024-04-02
  • Vuex数据持久化怎么实现
    小编给大家分享一下Vuex数据持久化怎么实现,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是vuexvuex :是一个专为vue.js开发的状态管理器,采用集...
    99+
    2023-06-15
  • android数据持久化怎么实现
    在Android中,有多种方式可以实现数据持久化,下面列举了几种常见的方法:1. Shared Preferences(共享首选项)...
    99+
    2023-10-21
    android
  • mysql怎么实现数据持久化
    MySQL可以通过以下几种方式来实现数据持久化: 使用磁盘存储:MySQL将数据存储在硬盘上,包括数据文件、日志文件等。这样即使...
    99+
    2023-10-21
    mysql
  • mongodb数据持久化怎么实现
    在MongoDB中,数据持久化是通过将数据写入硬盘来实现的。MongoDB会在后台自动将数据写入到磁盘中,以确保数据的持久性。 Mo...
    99+
    2023-10-21
    mongodb
  • Redis怎么实现数据持久化
    Redis 有两种数据持久化的方式:RDB持久化和AOF持久化。 RDB持久化: RDB持久化是通过定期将内存中的数据快照写入磁...
    99+
    2024-05-07
    Redis
  • vue2怎么实现vue3的teleport
    本篇内容主要讲解“vue2怎么实现vue3的teleport”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue2怎么实现vue3的teleport”吧!vue2实现vue3的teleport不...
    99+
    2023-06-30
  • ZooKeeper数据持久化是怎么实现的
    本篇内容介绍了“ZooKeeper数据持久化是怎么实现的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、...
    99+
    2024-04-02
  • 美国主机出现域名劫持怎么办
    美国主机出现域名劫持的解决方法:1、检查美国主机是否有未知的DNS解析,如果有继续及时进行清除;2、需要修改美国主机管理员密码,防止被黑客恶意利用;3、需要检查美国主机的网站是否存在挂马或者中病毒情况,可以使用安全程序软件进行扫描查看并及时...
    99+
    2024-04-02
  • Spark中怎么实现数据缓存和持久化
    在Spark中,可以通过使用RDD的persist()方法来实现数据缓存。persist()方法有多种级别,包括MEMORY_ONL...
    99+
    2024-03-14
    Spark
  • Ajax如何实现网站劫持的检测方法
    这篇文章将为大家详细讲解有关Ajax如何实现网站劫持的检测方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。https可以彻底解决劫持的问题。但是一般虚拟主机都不支持 https,难道http只能任流氓们...
    99+
    2023-06-08
  • mysql表数据持久化怎么实现
    在MySQL中,数据持久化是通过将数据存储在磁盘上的表中来实现的。以下是一些实现数据持久化的方法: 创建表:首先需要创建一个表来...
    99+
    2023-10-26
    mysql
  • Vue2 与 Vue3 的数据绑定原理及实现
    目录介绍Object.definePropertyProxy介绍 数据绑定是一种把用户界面元素(控件)的属性绑定到特定对象上面并使其同步的机制,使开发人员免于编写同步视图模型和视图的...
    99+
    2024-04-02
  • 自动获取的dns被劫持怎么修复
    对自动获取的dns劫持进行修复的方法首先,在电脑桌面中使用组合键“win+R”运行“control”,打开控制板面;控制板面打开后,在控制板面中进入“网络和共享中心”;在网络和共享中心页面中,点击“本地连接”选项;进入到本地连接页面后,在页...
    99+
    2024-04-02
  • Vue2中怎么实现管理组件通信
    今天就跟大家聊聊有关Vue2中怎么实现管理组件通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体内容如下<!DOCTYPE ht...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作