看代码

<input type="text">
    <script>
        let ipt = document.querySelector("input")
        let str = "请输入"
        ipt.value = str
        ipt.addEventListener("change", (e) => {
            str = e.target.value
        })
    </script>

以上代码写前端的都认识,input里面的value值会被赋值给str变量,但是当str变量本身发生变化的时候,input的value却不会产生变化,因为我们的addEventListener是单纯对input标签进行的监听,而没有函数对str这个值进行监听,当然我们可以使用以下的方法实现str和input的同步

<input type="text">
    <button>改变str的值</button>
    <script>
        let ipt = document.querySelector("input")
        let str = "请输入"
        ipt.value = str
        ipt.addEventListener("change", (e) => {
            str = e.target.value
        })
        //改变str的方法
        let but = document.querySelector("button")
        but.addEventListener("click", () => {
            str = "改变str"
            ipt.value = str
        })
    </script>

但是我们可以注意到这种写法中我们还要点击一个button,我们想让这个str变量直接动态改变,input不用其他操作自动改变其value,由此我们就引入了双向绑定的概念,而其中的重点在于增样去监听变量的set方法,如str=“hahha”

以下是两种简单的双向绑定事件

第一种是利用defineProperty

<body>
    <input type="text" class="ipt">
    <script>
        let ipt = document.querySelector(".ipt")
        let obj1 = {} //代理者
        let obj2 = { iptVal: '其输入' } //被代理者
        Reflect.defineProperty(obj1, "iptVal", {
            get () {
                // 试图获取obj1.iptVal的值时,会返回obj2.iptVal
                return obj2.iptVal
            },
            set (newVal) {
                // 当给obj1.iptVal设置新值的时候,obj2.iptVal的值也会更新,同时input的value也会更新
                obj2.iptVal = newVal
                ipt.value = obj1.iptVal
            }
        })
        ipt.value = obj1.iptVal
        ipt.addEventListener("change", (e) => {
            obj1.iptVal = e.target.value
            console.log(obj1);
        })
    </script>
</body>

我们可以通过浏览器的控制台去设置新值去看我们的input中的value会不会直接改变

 第二种是Proxy的写法

<body>
    <input type="text" class="ipt">
    <script>
        let ipt = document.querySelector(".ipt")
        let obj1 = { iptVal: "请输入" }

        let obj2 = new Proxy(obj1, {
            get (target, index) {
                return target[index]
            },
            set (target, index, value) {
                target[index] = value
                ipt.value = value
            }
        })
        ipt.value = obj2.iptVal
        ipt.addEventListener("change", (e) => {
            obj2.iptVal = e.target.value

        })

    </script>
</body>

两种写法其实有两个值,一个是和input绑定的监听者,另外一个是提供数据的被监听者,两者能够实现双向绑定的原因还是在于set方法,这个方法能在监听变量的赋值行为,并让我们做出dom操作,这才是最主要的。

今天想写文章,实在不知道写什么才写的这个。

Logo

前往低代码交流专区

更多推荐