vue中v-model的实现原理

v-model就是vue的双向绑定的指令,能将页面上控件输入的值同步更新到相关绑定的data属性,也会在更新data绑定属性时候,更新页面上输入控件的值。

在view层,model层相互需要数据交互,即可使用v-model。

双向数据绑定,数据不仅能从 data 流向页面,还能从页面流向 data
v-mode:value="xxx" 或简写为 v-model="xxx"

1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值

 

v-model通过view层更新data的原理:可以理解为在input框里面通过v-bind动态绑定一个value,然后在input框里面通过@input方法去动态获取input输入的值,然后重新给变量赋值就可以。

代码:

<template>
<div>
<div>{{name}}</div>
<input type="text" :value="name" @input="_input">
</div>
</template>
<script>
export default {
    data() {
        return {
            name:'234'
        }
    },
    methods: {
        _input(e){
            this.name=e.target.value

        }
    },  
}
</script>
<style>
</style>

原生JS实现V-Model:

Object.defineProperty来劫持要双向绑定的属性,在set时将其更新到视图层
在视图层绑定事件监听来将视图层的数据更新到data
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button onclick="add()">点点点</button>
    <input type="text" id="name" onkeyup="eee()">
</body>
<script>
    var data = {
        name: '',
        _name: 222,//用来存储的变量,避免get set 死循环
    }
    function add() {
        data.name = 223
    }
    function eee() {
        data.name = document.getElementById('name').value//更新data
        console.log('输入了')
        alert(data.name)
    }
  
    //  Object.defineProperty来劫持要双向绑定的属性,在set时将其更新到视图层
    Object.defineProperty(data, 'name', {
        get() {
            alert('读取了')
            debugger
            return data["_name"]
        },
        set(val) {
            let oldval = data["_name"]
            if (oldval == val) {
                return
            } else {
                data["_name"] = val
                console.log('更新了')
                document.getElementById('name').value = val//更新视图层
            }
        }
    })
    document.getElementById('name').value = data.name//绑定data到视图层
</script>

</html>

 

posted @ 2022-06-08 14:34  SadicZhou  阅读(3956)  评论(0编辑  收藏  举报