首页 > 其他分享 >对vue MVVM的探究

对vue MVVM的探究

时间:2024-02-21 14:55:41浏览次数:21  
标签:异步 vue MVVM 探究 abort 事件 View

对vue MVVM的探究

这个问题是我在写blazor时想到的

MVVM

咱们都知道MVVM分了ModelViewModelView三层

  • Model层是数据
  • ViewModel层是给View层提供显示的数据和逻辑操作
  • View层是界面显示

在WPF里面是处理的很好,在XAML中DataContext是ViewModel,View可以直接绑定ViewModel的数据和事件,而View的界面样式和动画可以通过触发器TriggerDataTriggerEventTrigger操作,这样很容易就把三层给分开了

还有prism框架的依赖注入RegionModuleDialogNavigationEventAggregator等一系列东西

blazor MVVM

到了blazor里面再用MVVM很容易就发现问题了,因为是基于.net的,所以依赖注入这种基本的东西还是有的,要实现DataContext也不是难事,View层通过DataContext.的方式绑定数据和事件,但是这玩意儿的View毕竟是html,没有触发器和事件状态呀

没有触发器和事件状态意味着不能在标签语句中处理动画,不过这里可以通过View层代码操作动画和调用ViewModel事件,也算是符合MVVM

不过没有触发器还有个问题,那就是异步,如果要保证异步事件中数据不会被上一个异步事件操作,那就要把上一个异步事件中断掉,WPF里面也是要做这个处理的,但是因为WPF有触发器,所以不需要处理中断后的数据,比如动画状态之类的

vue MVVM

到这里问题就更多了,毕竟官方也没说完全遵守MVVM的规范

首先就是没有依赖注入,虽然官方说有依赖注入,但是说实话,我是不觉得vue那玩意儿算依赖注入,且不说js里面用key和value的方式注入,毕竟.net底层估计也差不多,用ts也可以通过类型注入,为什么我觉得不算依赖注入呢,因为js还有个对象拷贝的问题

根据vue的官方文档对依赖注入的描述

当提供/注入响应式的数据时,建议尽可能将任何对响应式状态的变更都保持在供给方组件中。这样可以确保所提供状态的声明和变更操作都内聚在同一个组件内,使其更容易维护。

但是这句话的意思应该就是说这玩意儿就是个大号的有读写权限的props,那么我们的ViewModel就需要手动创建,而且还需要reactive
小小的测试一波,官方文档说的是响应式状态,那我就测一个不用reactive和ref的例子

provide("a", { a: 1 });
let a1 = inject("a");
console.log(a1);
a1.a = a1.a + 1;
let a2 = inject("a");
console.log(a2);

还真是单例的

因为vue的View也是html,所以不可避免的,同样没有触发器和事件状态,那么View层也需要通过View层代码操作动画和调用ViewModel事件

至于异步事件,我觉得js的异步比.net的处理还是麻烦的多,Promise的中断没有Task方便,不过异步事件的处理还是差不多的

中断Task是比较简单,一个事件函数底下的async函数链传递同一个的CancellationToken

//在事件执行前中断上一个事件
if (null != cancellationTokenSource)
{
    cancellationTokenSource.Cancel();
}
cancellationTokenSource = new CancellationTokenSource();

//执行具体的事件函数
...

具体的异步耗时操作要手动判断是否中断,抛出OperationCanceledException异常

if (true == cancellationTokenSource.Token.IsCancellationRequested)
{
    cancellationTokenSource.Token.ThrowIfCancellationRequested();
}

其实也可以去掉这个判断直接调用ThrowIfCancellationRequested,因为这个函数就是这样

public void ThrowIfCancellationRequested()
{
    if (IsCancellationRequested)
        ThrowOperationCanceledException();
}

不过一般来说都不需要我们手动写这个,除非这个函数没有对应的CancellationToken重载

中断Promise就比较麻烦了,需要封装一个Promise,监听abort事件,中断之后再解除事件监听

FooAsync(foo: () => {}, abort: AbortController): Promise<void>
{
    if (true == abort?.signal.aborted)
    {
        return Promise.reject();
    }

    return new Promise((resolve, reject) =>
    {
        let abortHandler = () =>
        {
            abort?.signal?.removeEventListener("abort", abortHandler);
            reject();
        };

        abort?.signal?.addEventListener("abort", abortHandler);

        //函数执行
        foo();

        //函数完成
        resolve();
        abort?.signal?.removeEventListener("abort", abortHandler);
    });
}

大概是这样的,我没测试过,随手写的
js这里可以通过事件监听中断异步,.net则需要手动,不过.net的类库基本都封装好了,js则没有,.net要实现监听也有多种方式

还有就是官方说的MVVM,似乎指的是
Model

let data = reactive({

});

ViewModel

let methods = reactive({

});

View

<template>
</template>

而没有完全遵守MVVM的规范指的是

proxy.$refs

emmm,这算MVVM吗,我不好说

对vue MVVM的探究 结束

只能手动保持MVVM的规范,不过在vue里搞MVVM似乎没啥意义,我还没见过哪个vue项目有规范的MVVM呢,毕竟js就是一坨

标签:异步,vue,MVVM,探究,abort,事件,View
From: https://www.cnblogs.com/zzy-tongzhi-cnblog/p/18022632

相关文章

  • Vue 学习笔记2 -- 开发环境
    第一步:创建文件夹并在VScode中打开第二步:创建src目录+index.html第三步:https://v2.cn.vuejs.org/v2/guide/installation.html下载vue依赖文件,如下图所示: 第四步:引入vue.js,如下图所示: 第五步:运行+F12解决如下图问题 https://v2.cn.vuejs.org/v2/guide/instal......
  • vue3项目模板:新建一个vite+vue3项目,并做基础化建设
    原文地址:https://blog.csdn.net/weixin_43239880/article/details/130355138新建一个vite+vue3项目,并做基础化建设1.使用npmcreatvite@latest新建一个vue3项目2.生成git仓库3.将prettier的规则加入到eslint中(可选操作,建议有)4.添加commitLint(可选操作,建议有)5.加入UI组件库,以ele......
  • Vue3组合式API之getCurrentInstance详解
    Vue2中,可以通过this来获取当前组件实例; Vue3中,在setup中无法通过this获取组件实例,console.log(this)打印出来的值是undefined。在Vue3中,getCurrentInstance()可以用来获取当前组件实例  vue3官方文档解释let{proxy}=getCurrentInstance(); 在setup中分别打印下面......
  • Linux下使用docker部署vue项目
    通过nginx镜像部署关于前端vue项目部署:使用npm打包创建nginx容器dockerrun-d--nameadmin_portal-p9091:80nginx将dist目录下的所有文件拷贝到容器的/usr/share/nginx/html目录下,这个是html文件的默认读取路径dockercp./admin_portal:/usr/share/nginx/html/......
  • 记录--源码视角,Vue3为什么推荐使用ref而不是reactive
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助ref 和 reactive 是Vue3中实现响应式数据的核心API。ref 用于包装基本数据类型,而reactive用于处理对象和数组。尽管 reactive 似乎更适合处理对象,但 Vue3官方文档更推荐使用 ref。 我的想法,ref就......
  • Vue学习笔记 1-- 环境搭建
    第一步:安装vscode第二步:安装nodejs--node-v14.17.6-x64(需要注意版本--版本过高或过低均会导致程序打包运行问题)——一路默认,会安装对应的npm注:版本和程序中使用的依赖包不一致会导致各种打包异常......,因此需根据自身项目实际情况安装对应版本==>程序打包问题npmi/npmi......
  • vue2 echarts 渲染数据
     <template><divref="friendsTrend"class="mt-16friendsTrend"/></template><script>import*asechartsfrom'echarts'importmomentfrom'moment'import{getLineChartStatisticsData......
  • vue 高德图层---省市区行政图层显示
    官网文档:https://lbs.amap.com/api/javascript-api-v2/guide/layers/districtlayervarmap;vardistProvince;initMap(){//初始化地图AMapLoader.load({key:'申请的key',version:'2.0',//需要使用JSAPI2.0版本。若从1.x版本......
  • 关于vue3的h函数
    h(ElInput,{class:'w200ml8',placeholder:'关键字搜索',clearable:true,modelValue:formData.url_pattern,'onUpdate:modelValue':(val:string)=&......
  • Vite + Vue3 实现前端项目工程化
    原文地址:https://mp.weixin.qq.com/s/cgiLx6NsoCAnh-mcR5peQgVue3发布至今,周边的生态、技术方案已足够成熟,个人认为新项目是时候切换到Vite+Vue3了。今天就给大家操作一下这种技术方案实现前端工程化。1.初始化项目通过官方脚手架初始化项目第一种方式,这是使用vite命......