让我们来写一个v-model吧

今天后端用到了一个插件,导致了整个页面没法滑动,通过控制台报错
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080
然后查看源码发现 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); 此行报错
这个错误在最后会说明 想要看错误的直接往下翻
这个只是简单介绍一下 最后会放文档地址 有兴趣的继续研究

addEventListener

根据mdn的说法 addEventListener 是将一个监听器注册到一个EventTarget对象上(这是啥?我也不太清楚 说的是泛指 包括元素 文档还有window对象等等,稍后进行研究)

语法

target.addEventListener(type, listener, options);

type:监听的事件类型
listener:监听事件触发时调用的方法
options:上面回调的有关方法调用时可选参数

用到的type类型

type : input 这个可以监听 input select textarea的更改

让我们开始吧

新建html 写入以下内容

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单的v-model</title>
</head>
<body>
    <input type="text" id="input">
    <button onclick="setdata()">点我赋值</button>
    <p id="value"></p>
    <script>
        let data = {value:""};
        let input = document.getElementById("input")
        let view = document.getElementById("value")
        //监听input值输入事件
        input.addEventListener("input",(el)=>{data.value = input.value})
        //监听data值变化
        Object.defineProperty(data,'value',{
            get(){
                return value
            },
            set(text){
                value = text
                input.value = text
                view.innerText = data.value
            }
        })
        // js测试修改值
        function setdata(){
            data.value = "这是点击赋值"
        }
    </script>
</body>
</html>

根据之前的介绍 大致已经能理解了
let input = document.getElementById("input") 获取input的dom对象
input.addEventListener 添加监听事件
监听类型为input
触发方法为给data.value赋值
接下来就是拦截对象的赋值操作
Object.defineProperty
第一个参数就是要定义的对象 我们是data
第二个参时要定义或修改的名字
第三个参数为定义的修改或者描述
get方法就是读取这个属性值时候触发的方法 如果没有 读取这个方法的时候就是undefined
set方法就是设置时候触发的方法 如果没有将无法设定值 传入的参数为修改的值
这个this指向不一定时定义的对象 这句看不懂 哪位大佬能解释下
详细可以参考mdn 在最后会放连接

然后基本代码已经介绍完毕了。有问题留言,感觉这个监听方法很好用的。

问题解决办法

最后的最后说一下解决办法,因为dom vevel-2的时候options只有一个传参 是 useCapture 当时解释是如果true的时候会向上冒泡而不会触发EventListener() 就是现在 options的passive
所以 最后解决将第三个参数更换为{passive:false}
悄悄说一句 第三个参数只是flase时在ios还是可以正常使用的

上述代码预览地址

codepan 预览地址

参考文章

mdn addEventListenerj介绍
mdn EventTarget介绍
mdn defineProperty介绍
csdn JS监听变量变化

猜你喜欢

转载自www.cnblogs.com/pplok/p/12812290.html