Vue 代理模式(手写Vue源码)
2022/8/12 1:22:48
本文主要是介绍Vue 代理模式(手写Vue源码),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文章出自全栈Ace
VIP课程 b战搜索全栈Ace
仅用作学习记录
准备工作,新建一个文件,index.html
1.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"> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <title>Document</title> </head> <body> <div id="app"> {{userName}} </div> <script> var vm = new Vue({ el: "#app", data: { userName: "Ace" } }) vm.$data.userName = "Taro" </script> </body> </html>
2.新建一个文件myVue.js
myVue.js
/** * Vue类的创建 * @param {*} options vue实例中的众多对象 (data,method,el) */ function Vue(options) { this._init(options) } /** * 创建一个方法用于获取vue对象中的众多属性,并把这个方法赋值给Vue的原型对象_init * @param {*} options vue实例中的众多对象 (data,method,el) */ Vue.prototype._init = function (options) { //此时this指向Vue类 let vm = this console.log(`this 为:${this}`) //创建Vue的对象 $options,来接收传入的options对象 vm.$options = options //初始化vue initState(vm) } /** * 初始化vue * @param {*} vm vue对象 */ function initState(vm) { let opt = vm.$options // 初始化data对象 if (opt.data) { initData(vm) } // 初始化watch // if (opt.watch) { // initWatch() // } // } /** * 初始化Data * @param {*} vm vue对象 */ function initData(vm) { //获取data let data = vm.$options.data //vue 对象中创建$data 方法 //data || {} 表示如果data为null则直接返回{}空对象 vm.$data = data || {} if (typeof data != 'object' || data == null) { return } else { new Observe(data, vm) } } /** * 监听类 用于监听data的变化 * @param {*} data 数据对象 * @param {*} vm vue对象 */ function Observe(data, vm) { /** * 重构data 并对其进行get/set 属性代理 * @param {*} data * @param {*} vm */ function restructure(data, vm) { let keys = Object.keys(data) console.log(keys) // 循环遍历每一个key 并进行代理化改造 // ★核心内容 for (let index = 0; index < keys.length; index++) { let key = keys[index] let value = data[key] //先定义vm中的对象,就不会出现后面重复定义的错误 vm[key] = value // 验证value是否依旧是对象(递归) if (typeof value != 'object' || value == null) { //啥都不做 // vm[key] = value // console.log('到了') // console.log(vm) } else { new Observe(value, vm) } // 给data中的变量配置get/set属性用于监听 //或者可以理解成把指定key挂载到data中 Object.defineProperty(data, key, { get: function () { return value }, set: function (newValue) { if (newValue != value) { //验证newValue是否是对象 if (typeof newValue != 'object' || newValue == null) { //啥都不做 } else { new Observe(newValue, vm) } value = newValue //这里只是做一个日志输出,如果是一个正常的vue,则应该是更新视图方法 console.log(`我现在是[${value}] 啦`) } }, }) //直接将data中的变量挂载到vm中 //注意: 如果之前vm中未曾定义过这些属性,若是有两个相同的key则会出现重复定义属性的错误 //解决方案:在之前每一次for循环后先通过vm[key] = value //定义一次,那么在这里就不会再次定义了 //这和js中xxx.xxx的意思一样,如果xxx.xx的xx在xxx中不存在则会定义,存在则只是调用 Object.defineProperty(vm, key, { get: function () { return value }, set: function (newValue) { if (newValue != value) { //验证newValue是否是对象 if (typeof newValue != 'object' || newValue == null) { //啥都不做 } else { new Observe(newValue, vm) } // value = newValue console.log(`我现在是[${value}] 啦`) } }, }) } } restructure(data, vm) }
上述代码分为如下步骤:
- 创建vue类
- 写vue全局扩展类(.NET 是这么叫)
- 初始化vue
- 初始化data
- 监听类 用于监听data的变化(重构data)
3. 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"> <!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> --> <script src="./myVue.js"></script> <title>Document</title> </head> <body> <div id="app"> {{userName}} </div> <script> var vm = new Vue({ data: { userName: "Ace", user: { userName: "Taro", age: 18 } } }) vm.user.userName = "GaoSi" </script> </body> </html>
这篇关于Vue 代理模式(手写Vue源码)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-04React 19 来了!新的编译器简直太棒了!
- 2025-01-032025年Node.js与PHP大比拼:挑选最适合的后端技术进行现代web开发
- 2025-01-03?? 用 Gemini API、Next.js 和 TailwindCSS 快速搭建 AI 推文生成项目 ??
- 2024-12-31Vue CLI多环境配置学习入门
- 2024-12-31Vue CLI学习入门:一步一步搭建你的第一个Vue项目
- 2024-12-31Vue3公共组件学习入门:从零开始搭建实用组件库
- 2024-12-31Vue3公共组件学习入门教程
- 2024-12-31Vue3学习入门:新手必读教程
- 2024-12-31Vue3学习入门:初学者必备指南
- 2024-12-30Vue CLI多环境配置教程:轻松入门指南