cometang前端技术博客 cometang前端技术博客
首页
  • html5
  • JavaScript
  • ES6
  • Vue
  • 微信小程序
  • react
  • react上手教程
  • 前端框架
  • 大神之路
  • 面试汇总
  • Node
  • PHP
  • Go语言
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

cometang

永远相信技术的力量
首页
  • html5
  • JavaScript
  • ES6
  • Vue
  • 微信小程序
  • react
  • react上手教程
  • 前端框架
  • 大神之路
  • 面试汇总
  • Node
  • PHP
  • Go语言
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • ES6

  • vue

    • vue基础详解
    • vue组件与路由
    • 组件通信与插槽
    • MVC与MVVM
      • 1.MVC 架构设计思想
      • 2.MVVM架构设计思想
      • 3. Object.defineProperty() 数据挟持
      • 4.尝试最简MVVM的实现
      • 5.通过 defineProperty 实现双向绑定
    • vuex状态管理
    • TypeScript基础
    • vue进阶
    • Vue2 装饰器与TS结合
    • Vue3.2 语法基础
    • Vue3.2项目架构
    • vue进阶-keepalive
    • vue2配置-环境变量-响应式-proxy-mock
    • vite打包工具
  • h5

  • JavaScript

  • 前端框架

  • react

  • 大神之路

  • 微信小程序

  • 面试题汇总

  • react轻松上手教程

  • 前端
  • vue
cometang
2022-05-31
目录

MVC与MVVM

# 1.MVC 架构设计思想

核心思想:代码层次分明,能够清晰明了分离 数据定义层Model ,渲染视图层View,业务逻辑控制层controller

特点:前端的MVC架构并不能简化代码,只是让代码看起来更具有规范性。

img

   <div id="app"></div>
1
  // 数据层Model  定义数据 
    const data = {
        name: '源码cometang'
    }
    //视图层 View   渲染视图
    function render() {
        let app = document.querySelector('#app');
        app.innerHTML = `
            <p>我的昵称是:${data.name}</p>
            <button onclick="editNickeName()">点我修改昵称 </button>
        `;
    }
    //进入页面自动渲染一次
    render()
    //控制层 controller  改变数据重新渲染视图
    function editNickeName() {
        //修改数据
        data.name = '源码小源'
        //重新渲染页面
        render()
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 2.MVVM架构设计思想

MVVM: Model(数据模型) View(视图) ViewModel(视图与数据的双向绑定)

特点: 视图更新 通知 defineProperty 更新数据;数据更新 defineProperty 重新渲染页面

img

  • vue 实现MVVM架构的方式

img

# 3. Object.defineProperty() 数据挟持

js在 Object类提供了一个数据挟持的静态方法 Object.defineProperty()

被挟持的数据 永远不能直接赋值,必须走set 方法

被挟持的数据 获取不到自己的值,获取的是get方法 return 的数据

Object.defineProperty(挟持的对象,'挟持对象中的属性',{
    //获取挟持数据的值时自动触发
    get(){ 
    },
    //设置 挟持数据的值时自动触发
    set(){
    }
})
1
2
3
4
5
6
7
8
    var data = {
        name:"cometang"
    }
    //数据挟持
    Object.defineProperty(data,'name',{
        get(){
            console.log('get....');
            return '啦啦啦';
        },
        set(newVal){
            console.log('set....',newVal); 
        }
    })
    data.name = '小源'    //直接赋值失效,把值传给了set方法的newVal 
    console.log(data.name);  //获取值 拿不到对象中的数据,拿到的是 get方法 return的数据 ====输出'啦啦啦'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 4.尝试最简MVVM的实现

写一个最简单的,没有 defineProperty 挟持的 实现 双向绑定的功能【失败】

问题:只实现了 页面变导致数据发生改变,数据变需要重新渲染,在vue代码中可不需要每次更改数据都调用重新渲染页面的函数。

    //Model 数据定义
    var data = {
        name: "cometang"
    }
    //View 视图渲染
    function render() {
        let app = document.querySelector('#app');
        app.innerHTML = `
           <p>
                请输入昵称:
                <input type="text" onchange="handleChange(this)" value="${data.name}"> 
           </p>
        `
    }
    render(); //初始化渲染
    //VM: ViewModel  双向绑定【失败】
    //获取页面的最新数据 重新给变量赋值===页面变导致数据变
    function handleChange(dom) {
        data.name = dom.value;
    }
    //数据变导致页面变===每次修改数据不能自动更新页面,必须要手动调用render函数
    data.name = '小源同学';
    //自动渲染失败,只能手动渲染,双向绑定实现失败
    render();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 5.通过 defineProperty 实现双向绑定

上述案例 ViewModel 层 没有起到应有的作用,增加defineProperty 挟持

set方法 更新挟持数据:页面变----set自动触发---获取最新数据---更新中间变量的值---重新渲染(自动触发get方法)

get方法 返回最新的中间变量的值------更新挟持的数据的值

    //Model 数据定义
    var data = {
        name: "cometang"
    }
    //View 视图渲染
    function render() {
        let app = document.querySelector('#app');
        app.innerHTML = `
           <p>
                请输入昵称:
                <input type="text" onchange="handleChange(this)" value="${data.name}"> 
           </p>
        `
    }
    render(); //初始化渲染
    //VM: ViewModel  双向绑定
    //必须要把 挟持的数据重新存储一份,防止陷入 更新数据的死循环中
    let val = data.name;
    Object.defineProperty(data, 'name', {
        get() {
            return val;
        },
        set(newVal) {
            //将最新数据写入到挟持的数据中
            val = newVal;
            //重新渲染页面
            render();
        }
    })
    //获取页面的最新数据 重新给变量赋值===页面变导致数据变
    function handleChange(dom) {
        data.name = dom.value;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

通过浏览器的控制台 验证

  • 直接输出 data.name 的值 看是否和页面的一致

  • 修改 data.name 之后 页面是否自动发生变化

  • 修改页面的input 框的数据 重新打印 data.name 看是否拿到最新数据

img

编辑 (opens new window)
上次更新: 2022/06/10, 01:34:10
组件通信与插槽
vuex状态管理

← 组件通信与插槽 vuex状态管理→

最近更新
01
go语言基础
07-13
02
《react上手教程》- 基础语法
07-13
03
redux-redux toolkit-状态管理
03-18
更多文章>
Theme by Vdoing | Copyright © 2019-2023

cometang | 唐世杰 渝ICP备18015657号-2

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式