Vue MVVM与数据代理

2024-03-18 1,064 1

1.vue中的MVVM

在Vue框架中,MVVM是指Model-View-ViewModel(模型-视图-视图模型),是一种用于构建用户界面的架构模式。MVVM将用户界面分为三个主要部分:

1)模型(Model):表示应用程序中的数据和业务逻辑,对应vue中data中的数据

2)视图(View):表示用户界面,对应vue中的模板

3)视图模型(ViewModel):连接模型和视图,充当桥梁,对应Vue实例对象

MVVM,最核心的就是 ViewModel 。ViewModel 包含 DOM Listeners 和 Data Bindings

Data Bindings 用于将数据绑定到 View 上显示DOM Listeners 用于监听操作

  • 从 Model 到 View 的映射,也就是 Data Bindings 。这样可以大量省略我们手动 update View 的代码和时间。
  • 从 View 到 Model 的事件监听,也就是 DOM Listeners 。这样我们的 Model 就会随着 View 触发事件而改变。数据的请求和视图的请求完全解耦(相互影响)。

vue虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例。

<!--视图 - vue模板容器-->
<div id='root'>
    <h1>{{ name }}</h1>
    <h1>{{ msg }}</h1>
</div>
<script>
    //视图模型 - Vue实例对象
    const vm = new Vue({
        el: '#root',
        data: { // 模型 - data中的数据
            name: 'Vue',
            msg: 'hello vue'
        }
    });
    console.log(vm)
</script>

注:

1)data中的所有属性,最后都出现在vm身上。
2)vm身上所有的属性和vue原型上所有的属性,在vue模板中都可以直接使用。

数据的双向绑定

  • 一是将模型转换成视图,即将后端传递的数据转换成看到的页面。 实现方式是:数据绑定
  • 二是将视图转换成模型,即将看到的页面转换成后端的数据。实现的方式是:DOM 事件监听

2. Object.defineProperty

1)Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

2)语法:Object.defineProperty(obj, prop, descriptor)

  • obj:要定义属性的对象
  • prop:要定义或修改的属性的名称。
  • descriptor:要定义或修改的属性配置项。

3)descriptor 里面的可配置项

默认不可枚举,不可修改,不可删除。

let person = {
    name: '张三',
    sex: '男',
    // age: 18
}

//定义的属性默认不可枚举,不可修改,不可删除
Object.defineProperty(person, 'age', {
    value: 18
});

高级配置 get( )set( ) :

let number = 18;
let person = {
    name: '张三',
    sex: '男',
    // age: 18
}

//定义的属性默认不可枚举,不可修改,不可删除
Object.defineProperty(person, 'age', {
    //value: 18,
    //enumerable: true, //控制属性是否可枚举(遍历),默认false
    //writable: true, //控制属性是否可写(修改),默认false
    //configurable: true, //控制属性是否可配置(删除),默认false

    //当读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
    get() {
        console.log('读取了age属性')
        return number;
    },
    //当修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值value
    set(value) {
        console.log('修改了age属性,值为',value)
        number = value;
    }
});
console.log(person.age)
person.age = 30;
console.log(person.age)

注意:

  1. value 和 get 是同一个作用,只能同时用一个。
  2. writable 和 set是同一个作用,用一个。

3. 数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)。

比如:obj 中有一个 x 属性,如果想在 obj2 中也能访问和修改这个属性就可以使用数据代理:

//数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
let obj = { x: 100 };
let obj2 = { y: 200 };

Object.defineProperty(obj2, 'x', {
    get() {
        return obj.x;
    },
    set(value) {
        obj.x = value;
    }
});

4.vue中的数据代理

1)vue中的数据代理

通过vm实例对象来代理data对象中属性的操作(读/写)。在Vue中,数据代理是一种使得在组件中直接通过Vue实例对象来操作data对象中的属性变得可行的机制。Vue实例会对data对象中所有属性进行封装,从而在内部实现对这些属性的访问、修改等操作。

2)基本原理

通过Object.defineProperty()把data对象中所有属性添加到vm上,并给每一个添加到vm上的属性都指定一个getter/setter,在getter/setter内部去操作(读/写)data中对应的属性。

在Vue中,每个Vue实例都有一个与之对应的响应式数据对象。Vue会遍历这个对象所有的属性,并使用Object.defineProperty把这些属性转为响应式属性,这个过程称为数据代理。

实现数据代理的目的是为了让我们可以在Vue实例(或组件实例)上直接访问data对象中的属性。例如,如果你有一个data属性,你可以直接用this.attr来代替this.data.attr

例如如下vue模板:

<div id="root">
    <h1>姓名:{{ name }}</h1>
    <h1>年龄:{{ age }}</h1>
</div>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            name: '张三',
            age: 18
        }
    });
    console.log(vm)
</script>

在浏览器控制台打印查看vm实例属性,可以看到:

我们并没有手动的去给name和age属性添加get和set函数,都是vue使用Object.defineProperty()给实例对象vm的data中定义的每个属性都添加了getter和setter。当用户修改data中的属性时,就会自动调用setter改变视图中对应的属性值了,这就是数据代理的实现原理。

在实例化 Vue 对象时,Vue 会将传入的 data 对象的属性都添加到实例的 _data 对象中,并实现数据代理,使得这些属性能够被实例直接访问。如果没有_data对象,那么我们在模版中使用Vue实例中的data属性时,必须要在属性名前面加上_data

相关文章

Vue 过滤器
Vue 自定义指令
Vue key的作用与原理
Vue 计算属性和监听属性
Vue el与data的两种写法
vue-codemirror编辑器使用(vue3)

评论(1)

发布评论