美文网首页移动前端
前端框架系列之(mvvm)

前端框架系列之(mvvm)

作者: vv_小虫虫 | 来源:发表于2020-06-22 21:36 被阅读0次

简介

前面我们介绍过了mvc 前端框架系列之(mvc),mvp 前端框架系列之(mvp),MVP中我们说过随着业务逻辑的增加,UI的改变多的情况下,会有非常多的跟UI相关的case,这样就会造成View的接口会很庞大。而MVVM就解决了这个问题,通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行。

  • Model(模型)表示应用程序核心(比如数据库记录列表)。
  • View(视图)显示数据(数据库记录)。
  • ViewModel (视图模型) 暴露公共属性和命令的视图的抽象。

我们再看一下mvc的设计图:

在这里插入图片描述

再看一下mvp的设计图:

在这里插入图片描述

最后看一下mvvm的设计图:

在这里插入图片描述

有没有发现,不管是mvc、mvp、mvvm其实都差不多呢?其实区别还是挺大的,在MVP中View和presenter要相互持有,方便调用对方,而在MVP中 View和ViewModel通过Binding进行关联,他们之前的关联处理通过绑定器(DataBinding)完成。

其实vue本身就是一个mvvm架构,通过es5的Object.defineProperty监听数据的变化,然后通过观察者模式通知各个vue实例,最后触发dom的更新,实现了数据驱动视图。感兴趣的可以去看一下我之前写的两篇关于vue的文章:

业务需求

  1. 接收用户输入的“用户名”和“密码”做登录操作
  2. 登录成功后返回“登录成功提示”

项目搭建

我们直接用上一节的demo

https://github.com/913453448/vue-property-decorator-demo

我们copy一个mvc目录为mvvm:

在这里插入图片描述

同样,我们修改一下main.ts的入口为mvvm/index.vue

main.ts:

import Vue from "vue";
import Demo from "./mvvm/index.vue";

new Vue({
  render(h) {
    return h(Demo);
  }
}).$mount("#app");

Model

model实现没变,还是跟mvc一样。

UserModelImp.ts

import User from "./User";

/**
 * user数据持久化接口层
 */
export default interface IUserModel {
  /**
   * 用户登录
   * @param {string} name
   * @param {string} pwd
   * @returns {Promise<User>}
   */
  login(name: string, pwd: string): Promise<User>
}

UserModelImp.ts

import User from "./User";
import IUserModel from "./IUserModel";

/**
 * user数据持久化实现层
 */
export default class UserModelImp implements IUserModel {
  /**
   * 用户登录
   * @param {string} name
   * @param {string} pwd
   * @returns {Promise<User>}
   */
  login(name: string, pwd: string): Promise<User> {
    return new Promise((resolve, reject) => {
      if ("123456" === pwd) {
        const user = new User();
        user.id = "1000";
        user.name = name;
        user.pwd = pwd;
        resolve(user);
      } else {
        reject(new Error("密码错误"));
      }
    });
  }
};

ViewModel

vue中已经为我们提供了一个叫vuex的工具,vuex完美的替代了我们的整个ViewModel,包括数据绑定器(databinding)。

首先我们安装vuex:

yarn add vuex || npm install -S vuex

我们在mvvm目录底下创建一个叫store的文件

store.ts

import Vue from 'vue';
import Vuex, {StoreOptions} from 'vuex';
import User from "../User";
import UserModelImp from "../UserModelImp";

Vue.use(Vuex);
//创建一个用户业务处理实例
const userModelImp = new UserModelImp();
const store = new Vuex.Store({
  state: {
    id: "",
    name: "",
    pwd: "",
  },
  mutations: {
    updateUser(state, user: User) {
      state.id = user.id;
    }
  },
  actions: {
    /**
     * 登录
     * @param context
     * @returns {Promise<Error | never | User>}
     */
    login(context) {
      return userModelImp.login(this.state.name, this.state.pwd)
        .then((user) => {
          context.commit("updateUser", user);
          return "欢迎你," + user.name;
        }).catch((error) => {
          return new Error("登录失败: " + error.message);
        });
    }
  }
} as StoreOptions<User>);
export default store;

我们直接创建了一个vuex中的store,vuex代表了我们的ViewModel,那么ViewModel是怎么跟view连接起来的呢?通过vuex的store跟页面进行数据绑定的,实现上面的代码想必大家问题都不大,不懂的童鞋可以去看vuex的官网,感兴趣的还可以看一下我之前写的几篇关于vuex的文章:

index.ts

把store当viewmodel暴露出去

import store from "./store";

export {
  store
};

View

IUserView.ts接口跟之前mvc、mvp一样

IUserView.ts

/**
 * user view接口
 */

export default interface IUserView {
  /**
   * 登录响应
   */
  onLogin(): void;

  /**
   * 展示消息
   * @param {string} msg
   */
  showMessage(msg: string): void;
}

index.vue我们直接通过vuex暴露在vue原型上的$store属性建立跟viewmodel的关联

index.vue

<template>
    <div>
        用户名:<input name="name" v-model="$store.state.name"><br>
        密码:<input name="pwd" v-model="$store.state.pwd"><br>
        <button @click="onLogin">登录</button>
    </div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "../view/component";
import IUserView from "./IUserView";
@Component
class UserViewImp extends Vue implements IUserView {
  /**
   * 去登录
   */
  onLogin() {
    this.$store.dispatch('login').then((msg:string)=>{
        this.showMessage(msg);
    }).catch((error:Error)=>{
      this.showMessage(error.message);
    });
  }
  /**
   * 展示消息
   * @param {string} msg
   */
  showMessage(msg = "") {
    alert(msg);
  }
}

export default UserViewImp;
</script>

可以看到,我们view中直接通过vuex的store建立了跟viewmodel的关系,然后通过vuex的store的dispatch方法触发viewmodel的action,viewmodel再通过usermodel获取数据,最后viewmodel直接修改state数据触发视图更新,其实小伙伴可以直接把vuex看成我们mvvm的viewmodel。

这里特别声明一下

小伙伴有没有看到我们代码中:

 <div>
        用户名:<input name="name" v-model="$store.state.name"><br>
        密码:<input name="pwd" v-model="$store.state.pwd"><br>
        <button @click="onLogin">登录</button>
    </div>

我们直接通过v-model绑定store的state对象的属性了,这样做其实是非常危险的,我们这里为了偷懒才这样写的,正常项目的话小伙伴需要通过computed关联state.name供当前组件使用,要修改state.name的话需要通过监听input的输入,然后触发vuex的action,最后通过mutation触发state.name的改变,也就是在vuex中只有mutation有权利修改state的值,为什么这样做呢? 主要就是为了更好的跟踪state的变化。

上面说的都是vuex官网中的规范,小伙伴可以自行去查看vuex的官网。

编译运行

npm run dev

运行结果

在这里插入图片描述
在这里插入图片描述

总结

  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变
  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑(这里说的是可以像mvp的presenter)
  • 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
  • 可测试。测试可以利用数据驱动视图了,可以针对viewmodel的开发
    代码

我们已经说了mvc、mvp、mvvm,那我们到底需要怎么去选择呢?

其实框架这种东西吧,没有绝对的框架,用起来大家都能接受、代码看起来很爽、维护起来方便、别再被人骂像💩一样就就可以了,管它啥啥啥呢!!!

源代码已经上传到github了

https://github.com/913453448/vue-property-decorator-demo.git

相关文章

  • 前端框架系列之(mvvm)

    简介 前面我们介绍过了mvc 前端框架系列之(mvc),mvp 前端框架系列之(mvp),MVP中我们说过随着业务...

  • webpack实战之(手把手教你从0开始搭建一个vue项目)

    前言 我们前面从前端架构: 前端框架系列之(装饰器Decorator) 前端框架系列之(vue-class-com...

  • Angular

    angular 概念 构建前端界面的mvvm框架 AngularjS 1系列 Angular 2-9 安装 安装脚...

  • MVVM在前端(web)使用

    前端框架vue,MVVM模式 今天咱们不谈iOS,说说web(MVVM模式)。MVVM模式在前端开发应该还是挺多的...

  • angular-1

    概念 构建前端界面的mvvm框架 angularJS 1系列 angular 2-9 安装 安装脚手架 npm i...

  • 使用Kotlin构建Android MVVM应用程序

    概述 说到MVVM,大家都会想起前端的MVVM框架,相较于前端MVVM的火热,它在移动开发领域就不那么热门了。Go...

  • VUE阶段性总结

    Vue是一个MVVM框架,这里的MVVM指的仅仅是前端,和后端无关。在MVVM框架中,视图和数据不能直接通信,而是...

  • Android MVVM文章整理

    DataBinding && MVVM 如何构建Android MVVM 应用框架 玩转Android之MVVM开...

  • MVVM及Vue渲染机制探索

    MVVM - Model View ViewModel 总所周知,Vue是目前比较流行的MVVM前端框架,其核心在...

  • 最新面试题目vue

    vue 1.mvvm 框架是什么? 前端页面中使用MVVM的思想,即MVVM/是整个视图层view的概念,属于视图...

网友评论

    本文标题:前端框架系列之(mvvm)

    本文链接:https://www.haomeiwen.com/subject/qjoffktx.html