模拟Vue双向绑定

本文通过一个简单的示例,展示了如何使用JavaScript实现类似Vue.js框架的双向数据绑定机制。通过定义对象属性的getter和setter,结合事件监听,实现了input元素与div元素之间的数据同步更新。
 <!--模拟Vue-->
    <script>
        window.onload = function(){
            Binding("ins","boxs");
        }

        function Binding(ins,boxs){
            // 创建数据对象
            window.data = {};
            // 创建数据键值对
            let _name = "";
            let my_input = document.getElementById('ins');
            let desc = document.getElementById("boxs");

            Object.defineProperty(window.data, "name", {
                // 返回数据
                get: function(){
                    return _name;
                },
                // 设置数据
                set: function(value){
                    _name = value;
                    // 将新数据添加到input和div元素内
                    my_input.value = value;
                    desc.innerHTML = value;

                }
            });
            // 获取input按钮, 并为其绑定事件
            my_input.addEventListener('input', function (ev) {
                new_data = ev.target.value;
                console.log("当前输入框内的数据为:",new_data);
                // 将框内的数据赋值给, data
                window.data.name = new_data
            })
        }
    </script>

 

### Vue.js 双向绑定的实现与使用 #### 一、Vue.js 双向绑定的核心原理 Vue.js 的双向绑定主要依赖于 **数据劫持** 和 **发布-订阅者模式** 来完成。具体来说,Vue 使用 `Object.defineProperty` 或现代浏览器中的 `Proxy` 对象来拦截对象属性的变化[^2]。当某个属性被修改时,会通知对应的视图进行更新。 此外,在表单控件中,Vue 提供了 `v-model` 指令作为语法糖,用于简化开发者在输入框或其他交互组件上的操作逻辑[^4]。它本质上是一个语法糖,内部实现了对 `value` 属性和 `input` 事件的同时处理。 以下是其实现的关键点: 1. 数据劫持:通过 `Object.defineProperty` 动态追踪对象属性的变化。 2. 发布-订阅者模式:创建一个观察者实例,负责收集并分发变更通知给所有订阅者。 3. DOM 更新机制:一旦检测到数据变动,则重新渲染关联的模板节点。 #### 二、代码示例展示如何手动模拟简单的双向绑定过程 下面提供一段简易版的手动实现代码,帮助理解 Vue 内部的工作流程: ```javascript // 定义 Dep 类 (Dependency),用来存储 Watcher 实例集合 class Dep { constructor() { this.subs = []; } addSub(sub) { // 添加 watcher 到 deps 数组里 this.subs.push(sub); } notify() { // 当有改变发生时调用此函数去通知所有的 watchers 执行 update 方法 this.subs.forEach((sub) => sub.update()); } } // 创建 Observer 类来进行数据观测 function observe(value, cb) { const dep = new Dep(); Object.keys(value).forEach(key => { let internalValue = value[key]; Object.defineProperty(value, key, { get() { console.log(`Getting ${key}`); Dep.target && dep.addSub(Dep.target); // 如果存在 target 就加入当前dep return internalValue; }, set(newValue) { if(internalValue === newValue){ return; }else{ console.log(`${key} changed from ${internalValue} to ${newValue}`); internalValue=newValue; // 调用notify方法让所有watchers执行update() dep.notify(); } } }); }); return value; }; let data={message:"hello world"}; observe(data); new class Watcher{ // 这里的Watcher类可以看作是vue里面的computed或者methods部分的一个代理器 constructor(vm,key,callback){ this.vm=vm; this.key=key; this.callback=callback; Dep.target=this;//设置Dep.target指向自己 this.value=this.get();//获取初始值的时候就会触发getter从而把自己注册到了相应的dep里面去了 Dep.target=null;//清空target防止污染其他地方 } get(){ return this.vm[this.key]; } update(){//每当对应的数据发生变化都会调用这个方法刷新view层的内容 let oldValue=this.value, newValue=this.get(); if(oldValue!==newValue){ this.value=newValue; this.callback.call(this,newValue,oldValue); } } }(null,"message",(val)=>{ document.body.innerText=val; }); ``` 这段代码展示了基本的响应式系统构建方式,虽然远不及实际框架复杂度高,但它清晰地体现了核心思想——即通过对目标对象定义 getter/setter 并利用中间媒介(如这里的 Dep)连接起数据源同其消费者之间的桥梁关系。 #### 三、Vue.js 中 v-model 的典型应用场景 `v-model` 是 Vue 提供给用户的便捷工具,主要用于 HTML 表单项与 JavaScript 数据间的同步通信。例如在一个普通的 `<input>` 元素上应用该指令即可轻松达成两者间相互影响的效果: ```html <div id="app"> <p>{{ message }}</p> <input type="text" v-model="message"/> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) </script> ``` 在这个例子当中,无论是在页面显示区域还是文本框内更改文字内容均能即时反映至另一端位置上去,这就是所谓的“双向绑定”。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值