首页 > 其他分享 >一次学俩Vue&Blazor:1.4基础-响应式数据

一次学俩Vue&Blazor:1.4基础-响应式数据

时间:2023-02-15 22:45:29浏览次数:37  
标签:1.4 Vue name reactive age value 响应 学俩 ref

一、声明式编程和响应式数据


1、声明式编程

  • 逻辑层修改视图层元素属性值的方式有两种,一是命令式,先通过getElementById等方法获取元素对象,然后再修改对象的属性;二是声明式,先将视图层元素的属性值和逻辑层数据绑定,通过修改逻辑层数据,实现视图层元素属性值的自动更新。
  • 现代前端开发框架,都采用声明式。

2、响应式数据

  • 使用声明式编程的开发框架,需要通过特定的机制通知视图层更新。
  • Vue通过Proxy代理机制,劫持读取或修改数据的行为,进而通知使用到数据的UI节点进行更新,被Proxy代理的数据,就称之为响应式数据,在组合式API中,Vue提供了ref和reactive两个API来创建响应式数据。
  • 而Blazor中的字段或属性,不需要特殊处理,天然具有响应式特性,其内在机制,暂不清楚。.NET的另一个响应机制MVVM,则是通过事件机制,来通知UI层更新。


二、Vue定义响应式数据的方法


Vue提供reactive和ref两个API来创建响应式数据,只有响应式数据才具有通知更新功能。实际应用中,有几个点需要特别注意:

1、reactive只能用来创建对象类型(如对象、数组、Map、Set),不能创建原始类型(如string、number、boolean等)。而ref可以创建任何类型。

const a = reactive({name:'MC',age:18}) //正确
const b = reactive(18) //错误
const a = ref({name:'MC',age:18}) //正确
const b = ref(18) //正确

2、reactive创建的响应式对象,默认是深层次的,里面嵌套的数据都具有响应式。

const a = reactive({})
a.people = {name:'MC',age:18} //增加的people属性也是响应式

3、当使用ref时,值保存在ref对象的value属性上。如果是在逻辑层代码里读取或修改,需要通过访问value属性,如b.value+=2;如果在视图层模板中读取或修改,会自动解包,不需要.value

//视图层中,自动解包,不需要.value
//逻辑层中,需要通过.value来访问
<template>
  <h1>{{a.name}}</h1>
</template>

<script setup>
import {ref} from 'vue'
const a = ref({name:”MC”,age:18})
a.value.name 
</script>

4、当使用ref创建对象类型时,会调用reactive来创建value属性,类似于这种感觉ref(reactive(value))。当整体替换value值时,新值仍然是响应式的,而reactive如果整体替换新值,则会失去响应性。

  • 在实际应用中,创建对象数组类型时,推荐使用ref,因为ref创建的对象,使用数组的map、filter、reduce等返回新数组的方法时,新数组仍然可以保持响应性。
  • 使用模块化开发时,export出来的数据,也应该使用ref,这样在引用这个API时,解构出来的数据仍然具有响应性。
  • 官方文档有一句话“为了解决reactive带来的限制,Vue 也提供了一个ref方法来允许我们创建可以使用任何值类型的响应式ref”。创建响应式数据时,除了对象类型,其它类型都请尽量使用ref,虽然.value麻烦点。
 //整体替换,a失去响应性
const a = reactive({name:”MC”,age:18})
a = reactive{name:”Fun”,age:16}

//ref可以实现响应式替换,b仍具有响应性
const b = ref({name:”MC”,age:18})
b.value = {name:”Fun”,age:16} 
 
//ref实现响应式解构
const obj1 = {foo: ref(1),bar: ref(2)}
const {foo,bar} = obj1 //响应式解构

//使用ref,即使使用filter等方法,b仍然还是响应式的
const b = ref([
  {name:”MC1”,age:18},
  {name:”MC2”,age:19},
  {name:”MC3”,age:20}])
b.value = b.value.filter((e)=>{return e.age >18})

//上例换成reactive,b失去了响应性
const b = reactive([
  {name:”MC1”,age:18},
  {name:”MC2”,age:19},
  {name:”MC3”,age:20}])
b = b.filter((e)=>{return e.age >18})

5、Vue的响应式原理

无论是选项式API的date()方法,还是组合式API的ref和reactive,都会将数据包装为Proxy对象。如果熟悉C#的属性,代理机制其实很简单。

//需要被代理的数据
const obj = {
  name:"functionMC",
  age:18
}

//当读取或修改数据时,指定代理的行为
//当读取数据时,调用get方法; 当修改数据时,调用set方法
//参数说明:target-被代理的对象、prop-读取的属性、receiver-代理对象、value-新值
const handler = {
  get(target,prop,receiver){
    
    //通过代理读取属性时,在返回值之前,它会做一个跟踪的操作,标记哪些地方用到了这个数据
    //track(),追踪谁用了这个属性......

    return target[prop]
  },

  set(target,prop,value,receiver){
    target[prop] = value

    //通过代理修改值之后,做一些其它操作
    //trigger(),触发所有使用了该值的位置进行更新
  }
};

//为数据obj,创建一个代理对象proxy
//之后对数据obj的读取和修改,都通过代理proxy来完成
const proxy = new Proxy(obj,handler)


三、Blazor中的响应式数据


Blazor中,字段和属性天然具有响应性,对象也是深层次绑定。利用属性的getter和setter方法,可以对响应式数据进行更复杂的控制。

@page "/"

<p>@Num</p>
<MButton @onclick="AddNum">增加</MButton>

<p>@employee.Name</p>
<MButton @onclick="ChangeName">更改名称</MButton>

<p>@employee.Address.City</p>
<MButton @onclick="ChangeCity">更改城市</MButton>

@foreach (var sport in sports)
{
    <p>@sport</p>
}
<MButton @onclick="AddSport">增加运动</MButton>

@code{
    //值类型的属性绑定
    public int Num { get; set; }

    //对象类型的字段绑定(深层次响应)
    private Employee employee = new Employee { 
        Id = 1, 
        Name = "functionMC", 
        Address = new Address { Province = "广东", City = "广州" } };

    //集合类型对象的字段绑定
    private List<string> sports = new List<string> { "Running", "Swiming", "BasketBall" };

    private void AddNum()
    {
        Num++;
    }

    private void ChangeName()
    {
        employee.Name = "MC";
    }

    private void ChangeCity()
    {
        employee.Address.City = "深圳";
    }

    private void AddSport()
    {
        sports.Add("FootBall");
    }
}


标签:1.4,Vue,name,reactive,age,value,响应,学俩,ref
From: https://www.cnblogs.com/functionMC/p/17123268.html

相关文章

  • Vue 自定义指令
      案例1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍<!DOCTYPEhtml><head><metacharset="UTF-8"/><scripttype="text/javascript"sr......
  • Vue
    目录一.Vue介绍1.前端发展史2.Vue简介渐进式框架网站3.Vue特点易用灵活高效4.M-V-VM思想①MVVM介绍②MVVM的特性5.组件化开发、单页面开发组件化开发单页面开发(spa)6.版......
  • Vue v-once指令 和 v-pre指令
    v-once指令:1、v-once所在节点在初始化动态渲染后,就视为静态内容了2、以后数据的改变不会引起v-once所在结构的更新,可用于优化性能v-pre指令:1、跳过其所在节点的编译过......
  • vue基础:js的几种循环方式、key值的解释、数组,对象的检测与更新、input事件、v-model双
    目录一、js的几种循环方式1.1v-for可以循环的变量1.2js的循环方式二、key值的解释三、数组,对象的检测与更新四、input事件五、v-model双向数据绑定六、过滤案例七、事件......
  • vue-3
    js的几种循环方式v-for可以循环的变量可以循环的有数组,对象,字符串,数字<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</titl......
  • vue_day03
    今日内容1js的几种循环方式1.1v-for可以循环的变量<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scriptsrc......
  • VUE简单实用
    目录v-for的循环方式原生js的循环方式v-for中key值方法的解释vue中数组和对象的检测更新input事件v-model双向数据绑定过滤案例箭头函数事件修饰符按键修饰符Input表单控制......
  • vue框架3
    js的几种循环方式1.v-for可以循环的变量 <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scriptsrc="./js/vu......
  • vueday3
    昨日回顾#1mvvm演示#2插值语法{{}} -三目运算符条件?'':''#3文本指令 -v-xxvue的指令,放在标签上<pv-xx></p>-v-text='变......
  • vue3
    今日内容概要js的几种循环方式key值的解释数组对象的检测与更新input时间v-model双向数据绑定过滤案例事件修饰符按键修饰符表单控制今日内容详细js几种循环......