亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Vue2 中的數據劫持簡寫示例

瀏覽:82日期:2022-06-02 08:22:40
目錄
  • package.json 相關依賴
  • Webpack.config.js 配置文件
  • public/index.html 文件內容
  • 全部文件目錄結構
  • 實例一個模擬的 Vue 應用
    • vue/index.js 文件主要是負責初始化內容
    • initState方法
    • 核心文件vue/observer.js
    • vue/observer.js文件對數組進行處理

package.json 相關依賴

我們今天要編寫的項目通過需要使用 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>

全部文件目錄結構

好了,接下來我們就開始發車!

實例一個模擬的 Vue 應用

首先,我們需要編寫我們的入口文件 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;

initState方法

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.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(`
標簽: JavaScript
主站蜘蛛池模板: 国内精品九一在线播放 | 91在线公开视频 | 国产一区二区三区在线观看影院 | 午夜一级福利 | 欧美精品在线观看视频 | 欧洲欧美成人免费大片 | 妞干网在线视频观看 | 黄色一级片子 | 亚欧精品一区二区三区四区 | 国产福利视频一区二区微拍 | 国产成人夜色影视视频 | 久久久国产精品免费看 | 国产人成亚洲第一网站在线播放 | 精品国产欧美另类一区 | 日韩乱淫 | 国产日韩欧美在线一区二区三区 | 久久免费黄色 | 国产成人精品日本亚洲网址 | 日韩欧美国产偷亚洲清高 | 日韩 国产 欧美视频一区二区三区 | 欧美亚洲国产精品久久久久 | 在线播放 亚洲 | 日本一级毛片在线播放 | 日韩成人影院 | 99re66精品视频在线观看 | 日韩视频www | 欧美高清免费一级在线 | 亚洲国产一区在线 | 人妖另类xx00视频 | 免费 视频 1级 | 看黄视频免费 | 成a人片在线观看 | 日本色图视频 | 亚洲欧美日韩国产一区二区精品 | 亚洲色图150p | www日韩中文字幕在线看 | 国产精品黄在线观看免费软件 | 在线视频久 | 国产精品麻豆 | 中文字幕亚洲国产 | 免费人成黄页在线观看69 |