IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue响应式原理详细讲解 -> 正文阅读

[JavaScript知识库]Vue响应式原理详细讲解

面试官:请你简单的说说什么是Vue的响应式。

小明:mvvm就是视图模型模型视图,只有数据改变视图就会同时更新。

面试官:说的很好,回去等通知吧。

小明:....

Vue响应式原理

先看官方的说法

简单理解就是实例data,Vue通过遍历data中所有对象通过Observer劫持监听所以属性,然后数据一旦发生变化,就通知编译解析变化,更新视图。

首先创建一个data,需要将data变成响应式数据,创建Observer 函数传值data,如果data不是一个对象或者是空就不用处理直接return

 <script>
        function Observer(targer){
            if(typeof targer !== 'object' || targer ===null){
                return targer
            }
        }
        const data = {
            name:'海海',
            age:18,
            info:{
                address:'广州'
            },
            fava:[1,2,3,4,5]
        }
        Observer(data)
    </script>

其他的处理

这里只处理数组,其他

判断是否等于数组,如果等于,如果不等于就循环target,声明响应式函数 defineReactive

传值targer,循环的key和targer[key],然后在?defineReactive调用我们的?Object.defineProperty

 function Observer(targer){
            if(typeof targer !== 'object' || targer ===null){
                return targer
            }
            if(Array.isArray(targer)) {
                // 数组
            }else{
                for(let key in targer){
                    // 响应式数据的函数
                    defineReactive(targer,key,targer[key])
                }
            }
        }

Object.defineProperty

? ?(Object.defineProperty()?方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。)

传入我们的参数

拿到get set方法

get

初始值 直接return 我们的value

set

第一个参数是最新的值 newValue

判断如果我们传入的value和newValue不相等,那么就把newValue赋值给value

        function defineReactive(targer,key,value){
            Object.defineProperty(targer,key,{
                get(){
                    return value
                },
                set(newValue){
                    if(newValue !== value) {
                        value =newValue
                    }
                }
            })
        }

?那么问题又来了,如果是一个对象需要监听,我们刚刚的操作只监听到了第一层,如果监听的内容是上面的info就相当于监听了整个对象,答案也很简单,我们只需要在调用defineReactive的时候在调用一次Observer在进入一次循环,当不是object就自动结束了

        function defineReactive(targer,key,value){
            Observer(value)
            Object.defineProperty(targer,key,{
                get(){
                    return value
                },
                set(newValue){
                    if(newValue !== value) {
                        value =newValue
                    }
                }
            })
        }

视图更新

我们这里在模仿一下视图更新 定义函数 updataView

        function updataView(){
            console.log('视图更新了')
        }

调用

?显示视图更新。

数组

先定义一个值 oldArrayProperty 然后将Array.prototype赋值给oldArrayProperty,

然后针对原型对象创建?Object.create()

定义一个 arrProto 来接收。

然后声明数组? ['push','pop','unshift','shift','reverse','sort','splice']? 进行循环

   const oldArrayProperty =Array.prototype
   const arrProto = Object.create(oldArrayProperty)
   const fn = ['push','pop','unshift','shift','reverse','sort','splice']
        fn.forEach((method)=>{
            arrProto[method] = function(){
             
            } 
        })

然后调用更新视图 updataView? return?将oldArrayProperty对应的方法匹配上return出来

        const oldArrayProperty =Array.prototype
        const arrProto = Object.create(oldArrayProperty)
        const fn = ['push','pop','unshift','shift','reverse','sort','splice']
        fn.forEach((method)=>{
            arrProto[method] = function(){
                updataView()
                return oldArrayProperty[method].call(this,...arguments)
            } 
        })

然后回到Observer方法中,将arrProto赋值给?targer的__proto__原型链上,最后在将targer循环调用Observer,进行数据更新。

  if(Array.isArray(targer)) {
                // 数组
                targer.__proto__ =arrProto
                for(let i=0;i<targer.length;i++) {
                    Observer(targer[i])
                }
            }

测试

?到这里我们的监听数据变化并自动更新就完成了。

完整代码

    <script>
        function defineReactive(targer,key,value){
            Observer(value)
            Object.defineProperty(targer,key,{
                get(){
                    return value
                },
                set(newValue){
                    if(newValue !== value) {
                        value =newValue
                        updataView()
                    }
                }
            })
        }
        const oldArrayProperty =Array.prototype
        const arrProto = Object.create(oldArrayProperty)
        const fn = ['push','pop','unshift','shift','reverse','sort','splice']
        fn.forEach((method)=>{
            arrProto[method] = function(){
                updataView()
                return oldArrayProperty[method].call(this,...arguments)
            } 
        })
        function Observer(targer){
            if(typeof targer !== 'object' || targer ===null){
                return targer
            }
            if(Array.isArray(targer)) {
                // 数组
                targer.__proto__ =arrProto
                for(let i=0;i<targer.length;i++) {
                    Observer(targer[i])
                }
            }else{
                for(let key in targer){
                    // 响应式数据的函数
                    defineReactive(targer,key,targer[key])
                }
            }
        }
        function updataView(){
            console.log('视图更新了')
        }
        const data = {
            name:'海海',
            age:18,
            info:{
                address:'广州'
            },
            fava:[1,2,3,4,5]
        }
        Observer(data)
    </script>

如果你还有什么问题你可以选择↓↓↓

http://img.haihaina.cn/qr.jpg

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:03:56  更:2022-05-24 18:05:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:46:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码