1.7章《传递UI片断》,需要做几个案例,这部分暂停消化几天。我们先把基础部分相对简单的最后两章学习了。

计算属性和数据监听是Vue当中的概念,本质上都是监听数据的变化,然后做出响应。两者的区别,在于响应方式的不同。

1、计算属性,如【const result = computed(()={return a + b})】。知名见意,是一个计算表达式,表达式中使用到的响应式变量都是它监听的对象,只要其中有任何变量发生变化,结果都会重新计算。可以理解为EXCEL里的计算,比如某个单元格的公式为“=A2+A1”。A2或A1发生变化是,结果也随之改变。

2、数据监听,如【watch(a,(newValue,oldValue)=>{console.log(newValue,oldValue)})】,其中a为被监听对象(必须是响应式),当a发生变化时,执行后面的回调函数,newValue是被监听对象的新值,oldValue为旧值,这两个值在回调的方法体里面,可以使用。

3、computed和watch,都会因被监听对象的改变,自动做出响应。不同的是,computed是为了返回一个计算结果(这个结果是ref响应式的);而watch是为了执行一个回调函数,做一些事情。所以,理论上watch也可以返回一个计算结果,实现computed的功能。

Blazor中没有计算属性和数据监听的概念,但也能实现相应的功能,只是本人技术有限,会有些差异限制。我们直接通过案例来进行对比:

一、Vue的计算属性computed和Blazor的实现

//Vue=====================================
//Vue使用computed来实现一个表达式的计算,参数是一个回调,在方法体里return出计算表达式。computed的返回值是一个ComputedRefImpl类型对象,使用方式和ref响应式对象一样
//实际上computed的值是可写的,如下写法:computed({get(){},set(newValue){}}),在set里写修改逻辑。但非常不推荐这么做,一违反这个API的设计初衷,二真没必要。
<template>
<h1>a:{{a}}</h1>
<h1>b:{{b}}</h1>
<h1>result:{{result}}</h1>
<button @click="a++">a++</button>
<button @click="b++">b++</button>
<button @click="show">show</button>
</template> <script setup>
import {ref,computed} from 'vue'
const a = ref(1)
const b = ref(2)
const result = computed(()=>{
console.log('执行计算'); //监测计算的执行
return a.value+b.value
})
//result是ComputedRefImpl类型对象,逻辑层也需要像ref一样
//在视图层,result也和ref对象一样,会自动解包,可以直接使用
function show(){
console.log(result);
}
</script> //Blazor====================================
//计算属性,本质上就是表达式,我们知道code里,表达式结果天然就是响应式的。所以我们可以定义一个变量,并根据其它变量来计算,
<h1>a:{{a}}</h1>
<h1>b:{{b}}</h1>
<h1>result1:{{result1}}</h1>
<h1>Result2:{{Result2}}</h1>
<button @onclick="a++">a++</button>
<button @onclick="b++">b++</button> @code{
private int a = 1;
private int b = 2;
private int result1 = a + b; //字段方式
public int Result2 => a + b; //属性方式(只读属性的简写)
//完整只读属性
private int result3;
public int Result3{
get{
Console.WriteLine("执行计算"); //监测计算的执行
return a + b;
}
}} //Vue和Blazor的区别
//难道在Blazor里,我们就这么简单了实现了computed?too young,too native
//我们分别在Vue和Blazor的视图层里,多次读取计算值,看看区别 //Vue中执行以下代码时,【console.log('执行计算')】只输出一次,计算结果被缓存,如果a和b不变,无论读取多少次,计算都不会重复执行。如果计算很复杂,将大大提升性能
<h1>result:{{result}}</h1>
<h1>result:{{result}}</h1>
<h1>result:{{result}}</h1>
//Blazor中执行以下代码时,【Console.WriteLine("执行计算");】输出三次,每次读取,都要执行一次计算。如果存在多次渲染、且计算复杂的情况,就需要特别注意
<h1>Result2:{{Result2}}</h1>
<h1>Result2:{{Result2}}</h1>
<h1>Result2:{{Result2}}</h1>

二、Vue的数据监听watch和Blazor的实现

//先说结论:虽然Blazor能够实现部分数据监控的功能,但存在很多缺漏。这不像计算属性,虽然存在性能问题,但功能是完整的
//Blazor对watch的实现,应该算是失败了 //Vue=====================================
//先简单汇总一下Vue中watch的基本用法
<template>
<h1>a:{{a}}</h1>
<h1>b:{{b}}</h1>
<button @click="a++">a++</button>
<button @click="b++">b++</button>
<button @click="people.look.height++">people对象身高++</button>
</template> <script setup>
import {ref, reactive,watch,watchEffect} from 'vue'
const a = ref(1)
const b = ref(1)
const people = reactive({name:"functionMC",look:{height:170,weight:130}}) //监视一个属性
watch(a,(newValue,oldValue)=>{
console.log(`a值被修改了,新值为${newValue},旧值为${oldValue}`)
})
//监视一个回调表达式,其中newValue和oldValue是表达式的结果
watch(()=>a.value+b.value,(newValue,oldValue)=>{
console.log(`a+b值被修改了,新值为${newValue},旧值为${oldValue}`)
})
//监视多个属性,其中newValue和oldValue都是返回形如[a,b]的数组
watch([a,b],(newValue,oldValue)=>{
console.log(`a或b值被修改了,新值为${newValue},旧值为${oldValue}`)
})
//Vue3的watch默认开启深度监视,可以监视对象的深层次改变,newValue和oldValue相等,都是新值
watch(people,(newValue,oldValue)=>{
console.log(`people的身高修改了,新值为${newValue.look.height},旧值为${oldValue.look.height}`)
})
//watchEffect是另外一个监听API,会自动监听回调中使用到的所有响应式数据,而且【在组件初次加载时会先执行一次回调】,而watch是懒加载,组件初次加载时,并不会调用回调
watchEffect(()=>{
const result = a.value+b.value
const height = people.look.height
console.log(`a+b=${result},people的身高为${height}`)
}) //watch和watchEffect的监听回调时机,是在DOM更新之前,所以回调中拿到的DOM是旧状态,如果要拿到更新后的新状态,需要配置一下
//watch(source, callback, {flush: 'post'})
//watchEffect(callback, {flush: 'post'}) </script> //Blazor===================================
<h1>a:@a</h1>
<h1>b:@b</h1>
<h1>身高:@People.Look.Height</h1>
<button @onclick="@(()=>A++)">A++</button>
<button @onclick="@(()=>B++)">B++</button>
<button @onclick="@(()=>C++)">C++</button>
<button @onclick="@(()=>People.Look.Height++)">people对象身高++</button> @code { //监视单个属性时,直接在set里执行回调
private int a;
public int A
{
get { return a; }
set {
Console.WriteLine($"A值被修改了,新值为{value},旧值为{a}");
a = value; }
} //监视多个属性时,在多个属性的set里执行一个委托
//action委托定义回调
private Action action = () =>
{
Console.WriteLine("B值或C值被修改了,无法获得新旧值");
}; private int b;
public int B
{
get { return b; }
set { b = value; action.Invoke(); } //值被修改时,执行委托
} private int c;
public int C
{
get { return c; }
set { c = value; action.Invoke(); } //值被修改时,执行委托
} //引用类型,无法监视到值得改变
private People people = new People
{
Name = "functionMC",
Age = 18,
Look = new Look { Height = 170, Weight = 130 }
};
public People People
{
get { return people; }
set
{
people = value;
Console.WriteLine("无法监视值得改变");
}
} //使用生命周期函数执行回调
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
Console.WriteLine("有数值被改了,但不知道是哪一个");
} }

三、总结:

1、Blazor通过get,可以实现computed的功能,但不具备cumputed的缓存能力,在执行复杂计算且在模板中多次渲染时,需要特别注意。

2、Blazor通过set,可以实现watch的部分功能,但实现不完整,直接的说,无法实现watch。

3、Blazor有没有可能实现完整的computed和watch?是有可能的!比如祖传的MVVM实现了属性变化通知,不就是watch吗。【或许社区已经实现了,只是我还不知道!】

Blazor和Vue对比学习(基础1.8):Blazor中实现计算属性和数据监听的更多相关文章

  1. Vue学习笔记(二)动态绑定、计算属性和事件监听

    目录 一.为属性绑定变量 1. v-bind的基本使用 2. v-bind动态绑定class(对象语法) 3. v-bind动态绑定class(数组语法) 4. v-bind动态绑定style(对象语 ...

  2. Blazor和Vue对比学习(基础1.9):表单输入绑定和验证,VeeValidate和EditFrom

    这是基础部分的最后一章,内容比较简单,算是为基础部分来个HappyEnding.我们分三个部分来学习: 表单输入绑定 Vue的表单验证:VeeValidate Blazor的表单验证:EditForm ...

  3. Blazor和Vue对比学习(基础1.2):模板语法和Razor语法

    Vue使用模板语法,Blazor使用祖传的Razor语法,从逻辑和方向上看,两者极为相似,比如: 都基于HTML 都通过声明式地将组件实例的状态(数据/方法)绑定到呈现的DOM上 都通过指令实现更加丰 ...

  4. Blazor和Vue对比学习(基础1.4):事件和子传父

    Blazor和Vue的组件事件,都使用事件订阅者模式.相对于上一章的组件属性,需要多绕一个弯,无论Blazor还是Vue,都是入门的第一个难点.要突破这个难点,一是要熟悉事件订阅模式<其实不难& ...

  5. Blazor和Vue对比学习(基础1.5):双向绑定

    这章我们来学习,现代前端框架中最精彩的一部分,双向绑定.除了掌握原生HTML标签的双向绑定使用,我们还要在一个自定义的组件上,手撸实现双向绑定.双向绑定,是前两章知识点的一个综合运用(父传子.子传父) ...

  6. Blazor和Vue对比学习(基础1.1):组件结构

    难度:★ 简单说一说: 1.Vue和Blazor都遵循单文件结果,即HTML(视图模板).CSS(样式).JS/C#(代码逻辑)写在一个文件里,Vue的文件后缀为.vue,Blazor的文件后缀为.r ...

  7. Blazor和Vue对比学习(基础1.6):祖孙传值,联级和注入

    前面章节,我们实现了父子组件之间的数据传递.大多数时候,我们以组件形式来构建页面的区块,会涉及到组件嵌套的问题,一层套一层.这种情况,很大概率需要将祖先的数据,传递给子孙后代去使用.我们当然可以使用父 ...

  8. Blazor和Vue对比学习(基础1.7):传递UI片断,slot和RenderFragment

    组件开发模式,带来了复用.灵活.性能等优势,但也增加了组件之间数据传递的繁杂.不像传统的页面开发模式,一个ViewModel搞定整个页面数据. 组件之间的数据传递,是学习组件开发,必须要攻克的难关.这 ...

  9. Blazor和Vue对比学习:说在开始前

    1.Vue:现代前端三大框架之一(Vue/React/Angualr),基于HTML.CSS和JavaScript,2014年正式对外发布,目前已发展到3.X版本.值得说道的是,Vue的创始人作者是华 ...

随机推荐

  1. resin服务之一---安装及部署

    参考网站: http://caucho.com/ http://www.oschina.net/p/resin http://caucho.com/resin-4.0/admin/starting-r ...

  2. 学习zabbix(二)

    超大规模门户网站集群架构: 运维30%的时间都在监控,监控要多维度: 监控(单机监控(系统监控).网络监控.应用监控.分布式监控): 业务监控(业务指标-->流量分析-->舆论监控): 流 ...

  3. 学习openstack(二)

    OpenStack企业私有云实践 1.     实验架构 OpenStack我们把它当作是一个全新的"Linux"系统来学习,有的时候我们也把OpenStack称之为一个新的Lin ...

  4. 乱序数组中第k大的数(顺序统计量)

    该问题是顺序统计量中十分经典的问题. 使用快排中的分区法,将第k大的数排序.若双向扫描分区加上三点中值法或绝对中值法,可以保证在 O(n) 时间里找出第k大的数. 补充:可以直接使用C++STL中的n ...

  5. 在网页中预览excel表格文件

    项目需求在前端页面中实现预览excel表格的功能,上网了解之后大致总结为一下几种方法. 1.office文档转换为pdf,再转swf,然后通过网页加载flash进行预览 2.通过 xlsx.js,js ...

  6. Wepy-小程序踩坑记

    引言 用过原生开发的小程序也知道除了api 其他功能性的内容并不多对于需要做大型项目来说是比较难入手的,因此朋友推荐的wepy我就入坑鸟...这么一个跟vue的开发方式类似的框架,不过说起来跟vue类 ...

  7. ES6-11学习笔记--代理Proxy

    Proxy代理 常用拦截方法 ES5拦截: let obj = {} let newVal = '' Object.defineProperty(obj, 'name', { get() { cons ...

  8. C#编写程序,用 while 循环语句实现下列功能

    编写程序,用 while 循环语句实现下列功能:有一篮鸡蛋,不止一个,有人两个两个数,多余一个,三个三个数,多余一个,再四个四个地数,也多余一个,请问这篮鸡蛋至少有多少个. 代码: using Sys ...

  9. java中Error和Exception用法上有什么区别,Error是怎么回事?

    顺便提一句, 和Exception 相对应的,还有Error,Error(错误)表示系统级的错误和程序不必处理的异常,是JRE(java运行环境)的内部错误或者硬件问题,比如,另外 某一处地方的bug ...

  10. Idea导出jar包和使用自定义API

    自定义jar简单实现案例 学习内容 1. 自定义工具类 2. 导出jar 3. 加载Jar包 4. 调用自定义的API方法 总结 学习内容 1. 自定义工具类 新建一个java项目,然后创建包和工具类 ...