js 实现watch监听数据变化


1.js

/**
 * @desc 属性改变监听,属性被set时出发watch的方法,类似vue的watch
 * @author Jason 
 * @study https://www.jianshu.com/p/00502d10ea95
 * @data 2018-04-27
 * @constructor 
 * @param {object} opts - 构造参数. @default {data:{},watch:{}};
 * @argument {object} data - 要绑定的属性
 * @argument {object} watch - 要监听的属性的回调 
 * watch @callback (newVal,oldVal) - 新值与旧值 
 */
 
class watcher{
    constructor(opts){
        this.$data = this.getBaseType(opts.data) === 'Object' ? opts.data : {};
        this.$watch = this.getBaseType(opts.watch) === 'Object' ? opts.watch : {};
        for(let key in opts.data){
            this.setData(key)
        }
    }

    getBaseType(target) {
        const typeStr = Object.prototype.toString.apply(target);
    
        return typeStr.slice(8, -1);
    }

    setData(_key){
        Object.defineProperty(this,_key,{
            get: function () {
                return this.$data[_key];
            },
            set : function (val) {
                const oldVal = this.$data[_key];
                if(oldVal === val)return val;
                this.$data[_key] = val;
                this.$watch[_key] && typeof this.$watch[_key] === 'function' && (
                    this.$watch[_key].call(this,val,oldVal)
                );
                return val;
            },
        });
    }
}

// export default watcher;

  2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>wathc</title>
</head>
<body>
    <script src="./watch.js"></script>
    <script>
        let wm = new watcher({
            data:{
                a: 0,
                b: 'hello'
            },
            watch:{
                a(newVal,oldVal){
                    console.log(newVal, oldVal); // 111 0
                }
            }
        })
        wm.a = 111
    </script>
</body>
</html>

  3. 给vm.a 从新赋值 就能看到 newVal 和oldVal的变化


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM