java学习路程之篇三、进阶知识、面向对象高级、接口新特性、代码块、内部类、Lambda表达式、窗体、组件、事件

这篇具有很好参考价值的文章主要介绍了java学习路程之篇三、进阶知识、面向对象高级、接口新特性、代码块、内部类、Lambda表达式、窗体、组件、事件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


ref

概述

生成值类型响应式数据
通过.value值修改
生成对象和数组类型的响应式对象选用reactive方式比较好


html

<template>
	<div>
		<div>countRef: {{ countRef }}</div>
		<div>objCountRef: {{ objCountRef.count }}</div>
		<div>爱好: {{ hobbyRef.join('---') }}</div>
	</div>
</template>

JavaScript

import { ref } from 'vue';

export default {
	name: 'refDemo',
	setup () {
		// 值类型
		const countRef = ref(1);
		console.log(countRef);
		
		// 对象
		const objCountRef = ref({ count: 1 });
		
		// 数组
		const hobbyRef = ref(['爬山', '游泳']);
		
		setTimeout(() => {
			// 通过value改变值
			countRef.value = 2;
			objCountRef.value.count = 3;
			hobbyRef.value.push('吃饭');
		}, 3000);
		
		return {
			countRef,
			objCountRef,
			hobbyRef
		};
	}
}

reactive

概述

reactive方法根据传入的对象,创建返回一个深度响应式对象。响应式对象看起来和传入的对象一样。但是,响应式对象属性值改动,不管层级有多深,都会触发响应式,新增和删除属性也会触发响应式。
1、改变name属性
2、深度改变address属性
3、新增school属性
4、删除age属性


html

<template>
	<div class="demo">
		<div>姓名: {{ state.name }}</div>
		<div v-if="state.age > 0">年龄: {{ state.age }}</div>
		<div>地址: {{ state.address.provoince }} - {{ state.address.city }} - {{ state.address.street }}</div>
	</div>
	
	<div class="demo">
		<div>学校: {{ state.school || '自学成才' }}</div>
	</div>
</template>

JavaScript

import { reactive } from 'vue';

export default {
	name: 'reactiveDemo',
	setup () {
		// 响应式对象
		const state = reactive({
			name: '太凉',
			age: 18,
			hobby: ['游泳', '爬山'],
			address: {
				provoince: '北京',
				city: '北京',
				street: '东城区长安街'
			}
		});
		
		// 过3秒后改变
		setTimeout(() => {
			// update1: 改变name属性
			state.name = '冰箱太凉';
			state.age = 25;
			// update2: 深度改变
			state.address.provoince = '山东省';
			// address属性
			state.address.city = '临沂市';
			// update3: 新增school属性
			state.school = '清华北大';
			// update4: 删除年龄属性
			delete state.age;
			// update5: 数组添加一项
			state.hobby.push('打豆豆');
		}, 3000);
		
		return {
			// 注意这里不能通过...state方式结构,
			// 这样会丢失响应式
			state  
		};
	}
}

style

.demo {
	text-align: left;
	width: 600px;
	margin: 20px auto;
}

toRef

概述

1、针对一个响应式对象(reactive封装)的prop(属性)创建一个ref,且保持响应式
2、两者保持引用关系


html

<template>
	<div class="demo">
		<div>姓名--state.name: {{ state.name }}</div>
		<div>姓名2--nameRef: {{ nameRef }}</div>
		<div>年龄: {{ state.age }}</div>
	</div>
</template>

JavaScript

import { reactive, toRef } from 'vue';

export default {
	name: 'toRefDemo',
	setup () {
		// 响应式对象
		const state = reactive({
			name: '太凉',
			age: 18
		});
		
		// 通过toRef创建一个Ref响应式
		const nameRef = toRef(state, 'name');
		
		// 过3秒后改变 两者 保持引用关系 
		setTimeout(() => {
			// update1: 改变name属性
			state.name = '冰箱太凉';
		}, 3000);
			
		// 过6秒后改变两者保持引用关系 
		setTimeout(() => {
			// update1: 改变name属性
			nameRef.value = '我就是冰箱太凉';
		}, 6000);
		
		return {
			nameRef,
			state
		};
	}
}

toRefs

概述

toRefs是一种用于破坏响应式对象并将其所有属性转换为ref的实用方法
1、将响应式对象(reactive封装)转成普通对象
2、对象的每个属性(prop)都是对应的ref
3、两者保持引用关系


html

<template>
	<div class="demo">
		<h3>state方式不推荐的方式绑定</h3>
		<div>姓名--state.name: {{ state.name }}</div>
		<div>年龄--state.age: {{ state.age }}</div>
	</div>
	
	<div class="demo">
		<h3>toRefs之后的方式推荐这种方式,return需要{ ...toRefs(state) }</h3>
		<div>姓名--name: {{ name }}</div>
		<div>年龄--age: {{ age }}</div>
	</div>
</template>

JavaScript

import { reactive, toRefs } from 'vue';

export default {
	name: 'toRefsDemo',
	setup () {
		// 响应式对象
		const state = reactive({
			name: '太凉',
			age: 18
		});
		
		// 通过toRefs创建一个响应式对象属性的Ref
		const toRefsValue = toRefs(state);
		
		// 过3秒后改变  两者保持引用关系
		setTimeout(() => {
			state.name = '冰箱太凉';
			state.age = '30';
		}, 3000);
		
		// 过6秒后改变 两者保持引用关系
		setTimeout(() => {
			toRefsValue.name.value = '我就是宇宙小超人';
			toRefsValue.age.value = '101';
		}, 6000);
		
		return {
			// 不建议使用这种方式,可以用下面的方式直接替换
			state,
			// 最佳方式:这里是结构将name的ref,
			// age的ref结构到对象根下面
			...toRefsValue
		};
	}
}

使用toRefs(state)方式返回

<template>
	<div>
		<div>姓名:{{ name }}</div>
		<div>年龄:{{ age }}</div>
	</div>
</template>
import { reactive, toRefs } from 'vue';

export default {
	setup () {
		const state = reactive({
			age: 20,
			name: '太凉'
		});
		
		const stateAsRefs = toRefs(state);
		
		return {
			...stateAsRefs
		};
	}
}

ref和reactive使用上区别

reactive定义引用数据类型,ref定义基本类型
reactive定义的变量直接使用,ref定义的变量使用时需要.value
模板中均可直接使用,vue帮我们判断了是reactive还是ref定义的(通过__v_isRef属性),从而自动添加了.value


ref和reactive的本质区别

代码片段壹

源码细节较多,本部分只分析关于refreactive的核心代码
首先找到ref函数,调用了createRef函数,而createRef返回了RefImpl

export function ref(value?: unknown) {
	// 创建ref
	return createRef(value, false);
}

function createRef(rawValue: unknown, shallow: boolean) {
	if (isRef(rawValue)) return rawValue;
	
	// 返回一个RefImpl对象
	return new RefImpl(rawValue, shallow);
}

代码片段贰

RefImpl类是不是似曾相识的感觉,没错就是Object.defineProperty,这里做的事情就是收集依赖,触发依赖,只是换了个写法而已。

class RefImpl<T> {
	// 用来保存加工后实现响应化的值
	private _value: T
	// 用来保存当前未经加工过的值
	private _rawValue: T
	// 用来收集依赖,这是一个Set类型
	public dep?: Dep = undefined;
	// 用来标识该值是否经过ref加工
	public readonly __v_isRef = true;
	
	constructor(value: T, public readonly __v_isShallow: boolean) {
		// __v_isShallow默认没有传,
		// 故默认为undefined,这里分别调用toRaw和toReactive
		this._rawValue = __v_isShallow ? value : toRaw(value);
		this._value = __v_isShallow ? value : toReactive(value);
	}
	
	get value() {
		trackRefValue(this);
		
		return this._value;
	}
	
	set value(newVal) {
		const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
		newVal = useDirectValue ? newVal : toRaw(newVal);
		if (hasChanged(newVal, this._rawValue)) {
			this._rawValue = newVal;
			this._value = useDirectValue ? newVal : toReactive(newVal);
			triggerRefValue(this, newVal);
		}
	}
}

代码片段叁

toReactive函数如果传入的参数是一个对象的话,返回值将会调用reactive方法来进行包裹,reactive最终会通过Proxy来实现响应式。

export const toReactive = <T extends unknown>(value: T): T => isObject(value) ? reactive(value) : value;

总结

1、基础类型值(StringNumberBooleanSymbol)或单值对象(类似{ count: 1 }这样只有一个属性值的对象)使用ref
2、引用类型值(ObjectArray)使用reactive


reactive将引用类型值变为响应式,使用Proxy实现
ref可将基本类型和引用类型都变成响应式,通过监听类的value属性的getset实现,但是当传入的值为引用类型时实际上内部还是使用reactive方法进行的处理
ref经修改实现方式后性能更高,推荐使用ref一把梭


1、ref创建基本数据类型时,是通过vue2中类似与Object.defineProperty的做法实现响应
2、ref创建对象时,内部调用的是reactive方法
3、vue3ref实际是对reactive的二次封装增强,reactive能做的ref一定能做,所以开发中多多使用ref


一阵见血的见解

1、ref把数据封装成一个整体,重新给数据指向新的内存地址,并且让其拥有响应式功能。
2、reactive把引用数据的每一个数据打散成单个独立的响应式数据,以便对数据的增删改查操作,也就是深度监听的意思。
3、开发中如果想重置一个数组那么建议使用ref,因为ref重置了内存地址;如果是一个固定数据对象,只是想修改数据中的某个属性值,那么使用reactive比较合适。


在对refreactive不是很了解的时候误用reactive定义一个空数组用来存放后端返回的数据,结果请求回来的数据一直无法正常的在页面上显示。
在使用vue3+typeScript+elementPlus+select实现下拉框选择时,下拉框的数据一直是’无数据’状态,后来使用ref解决了此问题。
文章来源地址https://www.toymoban.com/news/detail-604284.html

到了这里,关于java学习路程之篇三、进阶知识、面向对象高级、接口新特性、代码块、内部类、Lambda表达式、窗体、组件、事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Java面向对象进阶第四天(常用API)

    API全称是应用程序编程接口,是Java写好的程序,程序员可以直接调用。 Object是祖宗类,它里面的方法,一切子类对象都可以使用。 public String toString() 默认是返回当前对象的地址信息。 Student s = new Student(\\\"张三\\\",\\\'女\\\', 23); System.out.println(s.toString()); 返回对象地址 System.out.printl

    2024年01月20日
    浏览(13)
  • java基础入门-05-【面向对象进阶(static&继承)】

    java基础入门-05-【面向对象进阶(static&继承)】

    类的定义格式如下: 例如: 例如: 1.3.1 封装的步骤 1.使用 private 来修饰成员变量。 2.使用 public 修饰getter和setter方法。 1.3.2 封装的步骤实现 private修饰成员变量 public修饰getter和setter方法 1.4.1 构造方法的作用 在创建对象的时候,给成员变量进行初始化。 初始化即赋值的意

    2024年02月03日
    浏览(12)
  • C++进阶语法——OOP(面向对象)【学习笔记(四)】

    C++进阶语法——OOP(面向对象)【学习笔记(四)】

    1、C++ OOP面向对象开发 1.1 类(classes)和对象(objects) 简单介绍一下类: C++ 类(classes) 创建对象⽤的蓝图(blueprint) ⽤户⾃定义的数据类型 有成员属性(data)和成员⽅法(methods) 可以隐藏属性和⽅法(private) 可以提供公共接⼝(public) 示例: Account, Student, std::vecto

    2024年02月07日
    浏览(20)
  • 🔥🔥Java开发者的Python快速进修指南:面向对象进阶

    在上一期中,我们对Python中的对象声明进行了初步介绍。这一期,我们将深入探讨对象继承、组合以及多态这三个核心概念。不过,这里不打算赘述太多理论,因为我们都知道,Python与Java在这些方面的主要区别主要体现在语法上。例如,Python支持多重继承,这意味着一个类可

    2024年02月05日
    浏览(16)
  • Java面向对象程序开发——网络编程入门知识

    Java面向对象程序开发——网络编程入门知识

    ​ C/S结构 :client/sever是指客户端和服务器结构。常见程序有QQ、迅雷等软件。 B/S结构 :browser/sever是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。 Web应用系统开发的两种流行架构 两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一

    2024年02月12日
    浏览(46)
  • [ XJTUSE ]JAVA语言基础知识——第一章 面向对象程序设计思想

    类描述了一组有相同 特性 (属性)和相同 行为 (方法)的对象,类和对象是面向对象思想的两个核心概念 · 人类是一种类,每一个具体的人则是这个类的对象 用面向对象程序来模拟真实世界 发现并创建类 发现类的特征 发现类的行为 在面向对象程序中,对象的特征由各种

    2023年04月13日
    浏览(112)
  • Java学习笔记(三):面向对象

    类(class)和对象(object, 也被称为实例 instance)是 java面向对象的核心,可以把类理解成某种概念,对象理解为一个具体存在的实体。也就是说,日常说的人,其实都是人的实例,而不是人类。 定义类的简单语法: 修饰符可以是 public、final、abstract,或者完全省略。 对一个类而

    2024年02月11日
    浏览(13)
  • Java面向对象学习笔记-4

    当编写Java程序时,了解如何处理异常是至关重要的。异常处理可以帮助我们在程序执行过程中处理各种错误情况,以确保程序能够正常运行或者 graceful 地退出。本文将介绍一些关于Java异常处理的基本概念和最佳实践,包括自定义异常类、用户输入的处理、异常捕获与处理、

    2024年02月09日
    浏览(10)
  • Java面向对象学习笔记-3

    本文将介绍Java编程中的一些基本概念和用法,包括类、接口、抽象类、继承、多态和组合等。通过代码示例,我们将深入探讨这些概念,帮助读者更好地理解如何使用Java进行面向对象编程。 Java面向对象学习笔记-1 Java面向对象学习笔记-2 我们首先来看纸张和墨盒类,它们是

    2024年02月09日
    浏览(10)
  • Java学习路线(8)——面向对象基础(2)

    Java学习路线(8)——面向对象基础(2)

    一、static 概念: static是静态的意思,可以修饰成员变量和成员方法。当修饰成员变量时,在内存中 只存储一份 ,可以被 共享访问、修改 。当修饰成员方法时,可以被 共享访问 ,也被称为 公共方法 。 静态成员变量 访问格式: 【类名.静态成员变量】或【对象名.静

    2024年02月05日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包