0
点赞
收藏
分享

微信扫一扫

vue利用object.defineproperty实现响应式数据绑定

跟着老师学习手写的

// 观察给定的对象,进行取值赋值监听
function guancha(obj){
    for(let key in obj){
        //定义内部变量
        let internalValue = obj[key];
        //存储方法的数组
        let funArr = [];
        Object.defineProperty(obj,key,{
            get:function(){
                //依赖搜集,将依赖此变量的方法都放进来
                //如何搜集依赖变量的函数呢?
                //在调用每个依赖此变量的"函数"时,不再直接调用此"函数",而是通过一个统一的函数来调用此"函数",这个时候就可以通过一个全局变量来存储"函数",当"函数"内触发get时,就知道是哪个"函数"在用变量了
                //这样就是将以来变量的函数都存起来,供set中调用了
                
                if(!funArr.includes(globalThis.__autoFn) && globalThis.__autoFn){
                    funArr.push(globalThis.__autoFn);
                }
                console.log(funArr);
                return internalValue;
            },
            set:function(val){
                internalValue = val;
                //派发更新,调用依赖此变量的所有方法
                for(let i=0; i < funArr.length; i++){
                    funArr[i]();
                }
            }
        });
    }
    return obj;
}

// 调用方法时,用这个
function autoRun(fn){
    globalThis.__autoFn = fn;
    fn();
    globalThis.__autoFn = null;
}


export {guancha, autoRun}

import {guancha, autoRun} from './vuetest.js'

var user = {
  name: "王小明",
  age: 28,
};

guancha(user);

function xing() {
  let xing = user.name.substring(0, 1);
  document.querySelector(".xing").textContent = "姓: " + xing;
}
function ming() {
  let ming = user.name.substring(1);
  document.querySelector(".ming").textContent = "名: " + ming;
}
function nianling() {
    document.querySelector(".nianling").textContent = "年龄: " + user.age;
}

autoRun(xing);
autoRun(ming);
autoRun(nianling);

// let lin_name = user.name;
// Object.defineProperty(user,'name',{
//     get:function(){
//         return lin_name;
//     },
//     set:function(val){
//         lin_name = val;
//         xing();
//         ming();
//     }
// })

user.name = "王重阳";

//拼音输入时,input事件会在打字期间触发,不是很舒服;可以利用另外两个事件 compositionstart compositionend  来做判断
//这两个事件 是合成开始和结束;输入英文是不会触发,当用了输入法打汉字时就会触发
let composition = true;
document.querySelector("#xingming").addEventListener("input",function(e){
    if(composition){
        user.name = this.value;
    }
})
document.querySelector('#xingming').addEventListener("compositionstart",function(){
    console.log("合成开始");
    composition = false;
})
//合成结束是最后运行的,所以需要在合成结束这里再次赋值才可以变化
document.querySelector('#xingming').addEventListener("compositionend",function(){
    console.log("合成结束");
    composition = true;
    user.name = this.value;
})

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VUE响应式的简单实现</title>
</head>
<body>
    <div class="box">
        <div class="xing"></div>
        <div class="ming"></div>
        <div class="nianling"></div>
        <input type="text" id="xingming" placeholder="输入姓名可以实时展示" />
    </div>

    <style>
        *{
            padding: 0;
            margin: 0;
        }
        body{
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100vw;
            height: 100vh;
        }
        .box{
            border: 1px solid goldenrod;
            padding: 30px;
            border-radius: 10px;
            font-size: 30px;
            background-color: bisque;
            width: 500px;
        }
        .box div{
            margin-bottom: 30px;
        }
        .box div:nth-last-child(1){
            margin-bottom: 0;
        }
    </style>
    <!-- <script src="vuetest.js"></script> -->
    <script src="index2.js" type="module"></script>
</body>
</html>


举报

相关推荐

0 条评论