vue数据的响应式原理

本文探讨Vue数据的响应式原理,通过Object.defineProperty实现数据劫持和依赖追踪。同时,解释了声明式渲染的思路,强调Dom状态与数据状态的映射关系,以及状态改变时自动更新视图的功能。另外,提到了v-html指令的安全隐患和input自动获取焦点的方法,以及如何在Vue中注册自定义指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:vue数据的响应式原理

把一个普通的javascript对象传给Vue实例的data选项,

Vue将遍历此对象所有的属性,并用Object.defineProperty把这些属性全部转换为getter/setter

Vue内部会对数据进行劫持操作,进而追踪依赖,在属性被访问和修改时通知变化

<body>
    <div id="app">
        <button id="btn">
            改变数据
        </button>
        <h2 id="title">这是标题</h2>
    </div>
    <script>
        var data = {
            title= "新闻"
            }

    //数据劫持,转换成setter  getter
    function observer(obj){
        //这个方法 拿到对象,循环遍历这个对象,拿到所有的 属性。做一个数据劫持
        //Object.keys()  这个能拿到对象上的所有key值,组成一个数组
        Object.keys(obj).forEach((item)=>{
            //obj对象  item是obj的每一个key值,obj[item] obj的key值对应的value值
            defineReactive(obj,item,obj[item])
        })
    }

    function defineReactive(obj,key,value){
    //Object.defineProperty对key做一个表述,有getter,setter方法
        Object.defineProperty(obj,key,{
            get(){
                return value
            }
            set(newValue){
                value = newValue;
                //此时数据变了 视图就会更新,不用再点击的时候再手动改写dom
                title.innerHTML = newValue

            }
        })
    }
    console.log(data)//此时的data具有getter和setter的属性

        var title = document.getElementById('title');
        var btn= document.getElementById('btn');

        title.innerHTML = data.title;


        btn.onclick = function(){
             data.title = "数据变了"
               // 传统的做法 需要操作dom手动的把值改写了
               // title.innerHTML = data.title
        }
    </script>
</body>

 

二:声明式渲染理解

1:Dom状态只是数据状态的一个映射,

2:所有的逻辑尽可能在状态的层面去进行

3:当状态改变了,view会被框架自动更新到合理的状态 

 

三:指令

v-html 如果插入不合理的 html结构,会受到wxs的攻击,会触发onerror事件 ,如果网页中有用户数据,这些数据有可能会被泄露出去 

三 input自动获取焦点事件

<style>
    [v-cloak]{
        display:none;
    }
    p{
         display:none;
    }
    .active input{
        display:none;
    }
    .active p{
        display:block;
    }
</style>
<body>
    <div id="app" v-cloak>
        <div :class="{active:show}">
            <p @dbclick="editHandle">双击我</p>
            <input ref="test" />
        </div>
    </div>
    <script>
        var message = "hello"
        var vm = new Vue({
            id:"#spp",
            data:{
                message,
                show:true
            },
            method:{
                editHandle(){
                    this.show = false;

                    
                  //  this.$refs.test.fouse();//直接这么写这个方法 只回使input一瞬间获得焦点
                    //在dom更新完执行,获取焦点
                    this.$nextTick(function(){
                         this.$refs.test.fouse();
                    })
                }
            }
        })
    </script>
</body>

  this.$refs.test找到要回去焦点的那个元素

四:自定义指令

Vue.directive全局注册

<input v-foucs />

Vue.directive( 'foucs',{//描述,钩子函数
    bind(){
        //绑定的时候出发
    },
    inserted(el,binding){
        //插入父节点那一刻时出发
        //    el所绑定的元素,binding 一个对象
        el.foucs()
    },
    update(){

        //更新时出发
    },
    componentUpdateed(){
        //组件更新时也会出发
    },
    unbind(){
        //解绑的时候触发
    }
})


局部注册

new Vue({
    el:"#app",
    data:{
        msg
    },
    method:{
        directive:{

            focus:{
                inserted(el,binding){
                    el.focus()
                }
            }
        }
    }
})

 

Vue数据响应式原理是通过结合数据劫持发布-订阅者模式来实现的。Vue使用Object.defineProperty来劫持data中各个属性的setter和getter方法,并在数据变动时发布消息给订阅者,从而触发相应的监听回调。 具体来说,Vue会创建一个observe对象来对数据进行劫持,将数据对象的每个属性都转换为getter和setter。当数据发生变动时,setter会被调用,然后发布消息给订阅者,通知它们数据已经发生改变了。订阅者会触发相应的监听回调进行相应的更新操作。 在Vue中,每个组件实例都会对应一个watcher实例。当组件渲染过程中使用了数据属性时,watcher会将这些属性收集为依赖。当依赖项的setter被触发时,watcher会被通知,从而使其关联的组件重新渲染。这样就实现了数据响应式更新。 总结起来,Vue数据响应式原理是通过数据劫持和发布-订阅者模式的结合来实现的,利用Object.defineProperty来劫持数据属性的setter和getter方法,然后通过发布-订阅者模式来实现数据变动时的通知和更新操作。这种机制使得Vue能够实现高效的数据更新和视图渲染。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue响应式原理](https://blog.youkuaiyun.com/dongqian911/article/details/116242827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue响应式原理](https://blog.youkuaiyun.com/weixin_48181168/article/details/120158346)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值