返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详细聊聊Vue.js中的MVVM
  • 482
分享到

详细聊聊Vue.js中的MVVM

2024-04-02 19:04:59 482人浏览 安东尼
摘要

目录MVVM的理解MVVM的原理脏检查机制:数据劫持相同点实现MVVM总结MVVM的理解 MVVM拆开来即为Model-View-ViewModel,有View,ViewModel

MVVM的理解

MVVM拆开来即为Model-View-ViewModel,有View,ViewModel,Model三部分组成。View层代表的是视图、模版,负责将数据模型转化为UI展现出来。Model层代表的是模型、数据,可以在Model层中定义数据修改和操作的业务逻辑。ViewModel层连接Model和View。

在MVVM的架构下,View层和Model层并没有直接联系,而是通过ViewModel层进行交互。ViewModel层通过双向数据绑定将View层和Model层连接了起来,使得View层和Model层的同步工作完全是自动的。因此开发者只需关注业务逻辑,无需手动操作DOM,复杂的数据状态维护交给MVVM统一来管理。在vue.js中MVVM的体现:

MVVM的原理

在不同的框架当中,MVVM实现的原理是不同的:

脏检查机制:

angular.js就是采取的脏检查机制,当发生了某种事件(例如输入),Angular.js会检查新的数据结构和之前的数据结构是否发生来变动,来决定是否更新视图。

数据劫持

Vue.js的实现方式,对数据(Model)进行劫持,当数据变动时,数据会出发劫持时绑定的方法,对视图进行更新。

相同点

脏检查机制和数据劫持是有许多相同点的,例如,它们都有三个步骤:

  • 解析模版
  • 解析数据
  • 绑定模版与数据

实现MVVM

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Two-way data-binding</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="text">
        {{ text }}
    </div>
    <script>
        function observe (obj, vm) {
            Object.keys(obj).forEach(function (key) {
                defineReactive(vm, key, obj[key]);
            });
        }
        function defineReactive (obj, key, val) {
            var dep = new Dep();
            Object.defineProperty(obj, key, {
                get: function () {
                    if (Dep.target) dep.addSub(Dep.target);
                    return val
                },
                set: function (newVal) {
                    if (newVal === val) return
                    val = newVal;
                    dep.notify();
                }
            });
        }
        function nodeToFragment (node, vm) {
            var flag = document.createDocumentFragment();
            var child;
            while (child = node.firstChild) {
                compile(child, vm);
                flag.appendChild(child);
            }
            return flag;
        }
        function compile (node, vm) {
            var reg = /\{\{(.*)\}\}/;
            // 节点类型为元素
            if (node.nodeType === 1) {
                var attr = node.attributes;
                // 解析属性
                for (var i = 0; i < attr.length; i++) {
                    if (attr[i].nodeName == 'v-model') {
                        var name = attr[i].nodeValue; // 获取v-model绑定的属性名
                        node.addEventListener('input', function (e) {
                            // 给相应的data属性赋值,进而触发该属性的set方法
                            vm[name] = e.target.value;
                        });
                        node.value = vm[name]; // 将data的值赋给该node
                        node.removeAttribute('v-model');
                    }
                }
                new Watcher(vm, node, name, 'input');
            }
            // 节点类型为text
            if (node.nodeType === 3) {
                if (reg.test(node.nodeValue)) {
                    var name = RegExp.$1; // 获取匹配到的字符串
                    name = name.trim();
                    new Watcher(vm, node, name, 'text');
                }
            }
        }
    
        function Watcher (vm, node, name, nodeType) {
        //  this为watcher函数
            Dep.target = this;
        //  console.log(this);
            this.name = name;
            this.node = node;
            this.vm = vm;
            this.nodeType = nodeType;
            this.update();
            Dep.target = null;
        }
        Watcher.prototype = {
            update: function () {
                this.get();
                if (this.nodeType == 'text') {
                    this.node.nodeValue = this.value;
                }
                if (this.nodeType == 'input') {
                    this.node.value = this.value;
                }
            },
            // 获取daa中的属性值
            get: function () {
                this.value = this.vm[this.name]; // 触发相应属性的get
            }
        }
        function Dep () {
            this.subs = []
        }
        Dep.prototype = {
            addSub: function(sub) {
                this.subs.push(sub);
            },
            notify: function() {
                this.subs.forEach(function(sub) {
                    sub.update();
                });
            }
        };
        function Vue (options) {
            this.data = options.data;
            var data = this.data;
            observe(data, this);
            var id = options.el;
            var dom = nodeToFragment(document.getElementById(id), this);
            // 编译完成后,将dom返回到app中
            document.getElementById(id).appendChild(dom);
        }
        var vm = new Vue({
            el: 'app',
            data: {
                text: 'hello world'
            }
        });
    </script>
</body>
</html>

总结

到此这篇关于Vue.js中MVVM的文章就介绍到这了,更多相关Vue.js中MVVM内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详细聊聊Vue.js中的MVVM

本文链接: https://lsjlt.com/news/141217.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详细聊聊Vue.js中的MVVM
    目录MVVM的理解MVVM的原理脏检查机制:数据劫持相同点实现MVVM总结MVVM的理解 MVVM拆开来即为Model-View-ViewModel,有View,ViewModel...
    99+
    2024-04-02
  • 详细聊聊Vue中的MVVM模式原理
    目录1. MVVM模式2. Vue响应式3. Vue监听对象3.1 监听普通对象3.2 监听复杂对象(深度监听)4. Vue监听数组5. 使用 Object.defineProper...
    99+
    2023-03-03
    vue.js mvvm vue.js教程 vue mvvm模式
  • 详细聊聊前端Vue.js开发中的坑
    Vue.js是一个非常流行的JavaScript框架,能够帮助开发者快速构建高性能和可维护的Web应用程序。Vue.js框架在使用过程中,有时候会遇到一些“坑”,所谓“坑”,就是一些代码或设计上的难点或者问题。下面我将详细介绍一下前端Vue...
    99+
    2023-05-14
  • 详细聊聊Vue中的options选项
    目录Vue中的options选项options的五类属性入门属性使用vue文件添加组件computed(计算属性)用途缓存示例:watch(监听)用途何为变化deep: true是干...
    99+
    2024-04-02
  • 详细聊聊MySQL中的LIMIT语句
    目录问题 server层和存储引擎层 那LIMIT是什么鬼? 怎么办? 吐个槽 最近有多个小伙伴在答疑群里问了小孩子关于LIMIT的一个问题,下边我来大致描述一下这个问题。 问题 ...
    99+
    2024-04-02
  • 详细聊聊Mybatis中万能的Map
    目录万能的Mapdemomap 实现add usermap 实现通过id查询多个参数可以使用Map进行传参总结万能的Map 假设,我们的实体类,或者数据库中的表,字段或者参数过多,我...
    99+
    2024-04-02
  • 详细聊聊golang中函数的用法
    随着计算机技术的不断发展,编程语言也在不断更新换代,其中Golang是近年来非常热门的一种编程语言,它的高效、安全、易用受到了很多开发者的喜爱。在Golang中,函数是一种非常重要的编程元素,本文将详细介绍Golang函数的用法。一、函数的...
    99+
    2023-05-14
  • 聊聊MVVM模型在Vue中怎么应用
    Vue中的实现MVVM即模型-视图-视图模型。模型指的是后端传递的数据;视图指的是所看到的页面。视图模型是mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将模型转化成视图,即将后端传递的数据转化成所看到的页面。实现...
    99+
    2022-11-22
    javascript vue3 Vue vue.js
  • 一起详细聊聊C#中的Visitor模式
    目录写在前面模式演进举个例子使用了Tpye-Switch的版本尝试使用重载的版本单分派与双分派Visitor模式总结写在前面 Visitor模式在日常工作中出场比较少,如果统计大家不...
    99+
    2024-04-02
  • 详细聊一聊algorithm中的排序算法
    目录前言一、algorithm是什么?二、有哪些排序算法?sortrandom_shufflemergereverse总结前言 雨下不停,爱意难眠,说一下algorithm中的几个排...
    99+
    2024-04-02
  • 详细聊聊TypeScript中unknown与any的区别
    目录前言1. unknown vs any2. unknown 和 any 的心智模式3.总结总结前言 我们知道 any 类型的变量可以被赋给任何值。 let myVar: a...
    99+
    2024-04-02
  • 详细聊聊vue中组件的props属性
    目录问题一:那props具体是怎么使用呢?原理又是什么呢?往下看问题二:那如果我们想给年龄加1岁,怎么实现?问题三:对于年龄这一类型,我们最希望拿到的是什么数据类型?问题四:可以限制...
    99+
    2024-04-02
  • 聊聊Gitlab搭建的详细过程
    随着软件开发的蓬勃发展,版本控制工具的应用越来越广泛。Git作为一种分布式版本控制系统,已经成为了开发者们的首选工具。而Gitlab作为一个基于Web的Git代码仓库管理工具,也备受开发者们的青睐。本文将分享Gitlab搭建的详细过程和一些...
    99+
    2023-10-22
  • 详细聊聊Redis的过期策略
    保存过期时间 Redis可以为每个key设置过期时间,会将每个设置了过期时间的key放入一个独立的字典中。 typedef struct redisDb { int id; //i...
    99+
    2024-04-02
  • 详细聊聊MySQL中慢SQL优化的方向
    目录前言SQL语句优化记录慢查询SQL如何修改配置查看慢查询日志查看SQL执行计划如何使用SQL编写优化为何要对慢SQL进行治理总结前言 影响一个系统的运行速度的原因有很多,是多方面...
    99+
    2024-04-02
  • 详细聊一聊java中封装的那点事
    目录什么是封装封装拓展之包包的概念 什么是包访问权限什么是静态成员总结一下: 什么是封装 什么是封装呢?我们先来看一段代码 class Student { ...
    99+
    2024-04-02
  • 详细聊聊JS中不一样的深拷贝
    前言 对于深拷贝这个概念在面试中时常被提起,面试官可能让你实现深拷贝需要考虑那些因素,或者直接让你手写封装一个深拷贝,那么今天就和大家探讨一下一个让面试官感到牛的深拷贝, 1.思考 ...
    99+
    2022-11-13
    js深拷贝实现方式 js 对象深拷贝 js深拷贝的应用场景
  • 详细聊聊MySQL中auto_increment有什么作用
    目录问题来源解释注意事项总结问题来源 很多时候,mysql语句中会出现【auto_increment】这个词汇,大多数时候,表都是自动生成的,刚开始学习MySQL数据库时会学习到,后来,渐渐地可能会忘记,那么这个语句的作...
    99+
    2022-06-29
    mysql中auto_increment的作用 mysql auto increment
  • 详细聊聊sql中exists和not exists用法
    目录exists:exists 和in 的区别not exists详细介绍:附案例分析总结之所以要说这个问题,是因为项目中用到了not exists,但两者写的语句只有一点差别,结果...
    99+
    2024-04-02
  • 详细聊聊sql中exists和not exists用法
    在SQL中,EXISTS和NOT EXISTS是用于判断子查询中是否存在或不存在记录的条件运算符。1. EXISTS用法:EXIST...
    99+
    2023-08-08
    SQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作