从java到vue3:第二天

文章目录

  • 前言
  • 一、setup
    • 1.定义
    • 2.作用
    • 3.响应式数据
      • 1.ref
      • 2.reactive
      • 3.ref与reactive的区别
      • 4.toRefs
      • 5.computed
    • 二、Watch
    • 1.监视ref:基本数据
    • 2.监视ref:对象数据
    • 3.监视reactive:对象数据。
    • 4.监视ref或reactive中某个属性
    • 5.监视多个属性
  • 总结


前言

  • setup、响应式数据的几个函数、watch监听。

一、setup

1.定义

  • 它是一个新的组件选项,与以前的data、methods标签相同的地位。

2.作用

  • 可以在setup里面定义变量、方法,同时返回值可以使用类似于lambda表达式的简便写法。

关键问题1:在setup中能否读到以前data选项或methods选项里面的数据?
不能,浅显的理解一下就是。因为setup没有维护this对象,无法调用。
关键问题2:在data选项或methods选项中可以读到setup中的数据?
可以,需要使用this进行调用。

setup示例:

export default {name:'Person', // 组件名// 1.setup能和methods data共存 // 2.data里面能不能读到setup里面的数据?// >>可以,使用this.变量进行读取// 3.但是setup不可以读到data里面的数据// 4.setup是一个全新的配置项 它的优先级比vue2中的beforeCreate的优先级更高// 5.它不存在this,没有维护this对象setup(){// 1.数据 ---> data选项let name = '张三'let age = 18let tel = '1388888888'// 2.方法function changeName () {// 注意:此时的数据不是响应式的// 虽然改了但是页面不会有变化 name = 'zhang-san'}function changeAge () {age += 1}function showTel () {alert(tel)}// 2.通过返回值进行返回数据 可交可不交return {name,age,changeName,changeAge,showTel}// return ()=>'哈哈' 直接返回 setup的返回值也可以是个渲染函数}
}

语法糖:

  • 可以直接写在script标签里,自动返回变量以上的写法等价于下面的写法

关键问题3:如果说需要自定义命名组件名需要单独设置,但是默认是与文件名一致。
关键问题4:如果说要想基本数据类型是响应式的,需要导入ref,将响应式数据用ref()框起来,需要在改变的时候使用.value进行修改。因为在标签里的变量返回值是一个RefImpl实例对象,也就是返回的数据用对象封装起来了,里面的数据就需要.value来进行调用。

<!-- 需要单独设置组件名的话可以在这里设置 就不使用插件了 -->
<script lang="ts">
export default {name:'Person123', // 组件名
}
</script><script lang="ts" setup>
import {ref} from 'vue'let name = ref('张三')let age = ref(18)let tel = '1388888888'function changeName () {name.value = 'zhang-san'}function changeAge () {age.value += 1}function showTel () {alert(tel)}
</script>

3.响应式数据

1.ref

  • ref是一个响应式的API,用于创建一个响应式的引用,通常用于响应式基本数据类型,也可以用于对象类型的响应
  • 使用的时候将需要响应式的数据导入ref,然后用ref()包裹起来,然后在需要进行修改的时候调用数据.value进行修改。以上示例已经展示了ref的基本数据类型响应。
  • 返回的是一个Proxy代理对象。
    ref对象类型响应:
<template><div class="car"><h2>品牌:{{ car.brand }}</h2><h2>价格:{{ car.price }}</h2><ul><li v-for="c in cars" :key="c.name">车名:{{ c.name }},价格:{{ c.price }}</li></ul><button @click="changePrice">修改价格</button></div>
</template><script lang="ts">
export default {name:'Car', 
}
</script><script lang="ts" setup>// 1.导入refimport {ref} from 'vue'// 2.用ref包裹起来let car = ref({brand:'保时捷',price:100,})// 对象数组let cars = ref([{name:'奔驰',price:100},{name:'法拉利',price:1000},])// 3.直接修改function changePrice() {car.value.price += 10 }console.log(car)
</script><style scoped>.car {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>
  • 它的外层使用ref包裹起来的,内部是reactive处理的。需要先用value读到对象后再进行操作才可以,包括ref里面包含了数组对象,需要用value去读到数组对象后在进行索引等其他操作。
<template><div class="car"><h2>品牌:{{ car.brand }}</h2><h2>价格:{{ car.price }}</h2><ul><li v-for="c in cars" :key="c.name">车名:{{ c.name }},价格:{{ c.price }}</li></ul><button @click="changePrice">修改价格</button></div>
</template><script lang="ts">
export default {name:'Car', 
}
</script><script lang="ts" setup>// 1.导入reactiveimport {ref} from 'vue'// 2.用ref包裹起来let car = ref({brand:'保时捷',price:100,})// 对象数组let cars = ref([{name:'奔驰',price:100},{name:'法拉利',price:1000},])// 3.直接修改function changePrice() {car.value.price += 10 }console.log(car)
</script><style scoped>.car {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>

2.reactive

  • reactive也是响应式API,只能用于创建一个响应式对象。
  • 使用的时候需要导入reactive,然后用reactive包裹起来,然后直接修改即可。
    返回的也是一个Proxy代理对象。
    注意不用.value。
    reactive响应对象类型:
<template><div class="car"><h2>品牌:{{ car.brand }}</h2><h2>价格:{{ car.price }}</h2><button @click="changePrice">修改价格</button></div>
</template><script lang="ts">
export default {name:'Car', 
}
</script><script lang="ts" setup>// 1.导入reactiveimport {reactive} from 'vue'// 2.用reactive包裹起来let car = reactive({brand:'保时捷',price:100,})// 3.直接修改function changePrice() {// 4.不用加.value了car.price += 10}
</script><style scoped>.car {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>

数组代理对象:

  • v-for类似于我们写的mybatis的xml方式的sql语句里面的forEach,这里表示遍历cars,:keys表示能确定每一个数据的主键元素,同样需要用reactive来括起来,访问元素就要用c来访问。
<template><div class="car"><ul><li v-for="c in cars" :key="c.name">车名:{{ c.name }},价格:{{ c.price }}</li></ul></div>
</template><script lang="ts">
export default {name:'Car', 
}
</script><script lang="ts" setup>// 1.导入reactiveimport {reactive} from 'vue'// 2.用reactive包裹起来// 对象数组let cars = reactive([{name:'奔驰',price:100},{name:'法拉利',price:1000},])
</script><style scoped>.car {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>

3.ref与reactive的区别

区别1:ref用来生成响应式数据的时候,需要用.value来访问。
区别2:ref能够修饰基本类型、对象类型的响应式数据。
总结:基本类型用ref,层级不深的对象使用ref。
总结:层级深的使用reactive。

4.toRefs

作用:能够将reactive包裹的对象响应式数据解构,能够将它的每一个字段变成ref对象。
实质:将某个对象的字段结构,将该字段与对象里的字段变成一摸一样的数据,意思是调用toRefs后我们可以修改对象的字段了。

<template><div class="person"><h2>{{ name }}</h2><h2>{{ age }}</h2><button @click="changeAge">修改年龄</button><button @click="changeName">修改名字</button></div>
</template><script lang="ts">
export default {name:'ToRefs',
}
</script><script lang=ts setup>import {ref,reactive,toRefs} from 'vue'let person = reactive({name:"kkk",age:999,})let {name, age} = toRefs(person)function changeName() {name.value = name.value + "k"}function changeAge() {age.value += 1}
</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>

5.computed

定义:计算属性,基于响应式数据计算响应值。
使用:需要get和set方法。像jv里的getter和setter。
v-model:数据双向绑定。
const:明确声明不可变数据。
const [str1,str2] = val.split(‘’-‘’) :数组也能解构定义。

<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br><!-- v-model 是 Vue 提供的双向数据绑定指令,主要用于 <input><select><textarea> 等表单元素,实现数据与视图的自动同步。 -->全名:<span>{{ fullname }}</span> <br>修改:<button @click="changeFullName"></button></div>
</template><script lang="ts">
export default {name:"Compute",
}
</script><script setup lang="ts">import {ref,reactive, computed} from 'vue'let firstName = ref("jo")let lastName = ref("ny")// 变成一个可读可写的计算属性let fullname = computed({get(){return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + "-" + lastName.value},set(val){// 数组也能解构赋值const [str1,str2] = val.split("-")firstName.value = str1lastName.value = str2}})function changeFullName() {fullname.value = "gy-ro"}
</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}.button {margin: 0 5px;}
</style>

二、Watch

  • 它能够监视数据.。

注意1:需要监视的值不需要加.value,因为自动解包。
注意2:调用watch返回值是一个监视停止器,再次调用就会停止监视。
注意3:它只监视4种数据。函数返回值,ref、reactive和它们的数组。

1.监视ref:基本数据

<template><div class="person"><h1>监视数据</h1><h1>当前数据求和为:{{ sum }}</h1><button @click="changeSum"></button></div>
</template><script lang="ts">
export default { // 实际上这里要缩进这个大括号一下才不会报错name:"Watch",
}
</script>
<script lang="ts" setup>
import {ref, watch} from 'vue'
// 需要用ref或reactive包裹起来let sum = ref(0)function changeSum(){sum.value += 1}// 监视const stopWatch = watch(sum, (nv,ov)=>{console.log("sum变化了", nv, ov)if(nv >= 10) {stopWatch() // 如果newValue大于等于10就停止监视 stopWatch()表示停止监视}})
</script>

2.监视ref:对象数据

  • 监视用ref包裹的对象数据需要手动开启深度监视。
  • 监视的是地址,整个对象,只有整个对象改变的时候才会触发监视器。
  • 如果想要深度监视,需要手动添加深度监视。
  • {immediate:true}:添加在深度监视后面。表示不管你改没改,先执行一次箭头函数。它提醒的是旧的引用,如果没改变,那就还是新的那个对象,已经改了。
  • 实际上开发不管旧值。

参数1:被监视的数据。
参数2:监视的回调函数。
参数3:配置对象。
实质:改的是它的引用。

<template><div class="person"><h1>情况二:监视【ref】定义的【对象类型】数据</h1><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button></div></template><script lang="ts">
export default {name:"Watch2",
}</script><script lang="ts" setup>import {ref,watch} from 'vue'// 数据let person = ref({name:'张三',age:18,})// 方法function changeName(){person.value.name += '~'}function changeAge(){person.value.age += 1}function changePerson(){person.value = {name:'李四', age:90}}/* 监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视watch的第一个参数是:被监视的数据watch的第二个参数是:监视的回调watch的第三个参数是:配置对象(deep、immediate等等.....) */watch(person,(nv,ov)=>{console.log('person变化了',nv,ov)}, {deep:true})</script>

3.监视reactive:对象数据。

  • 默认开启深度监视。且关不掉哦。

修改对象: Object.assign(person,{name:‘李四’,age:80})。
第一个参数是要改的对象,第二个参数是要改的内容。
实质:没改变原引用,只覆盖了值。

<template><div class="person"><h1>情况三:监视【reactive】定义的【对象类型】数据</h1><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button><hr><h2>测试:{{obj.a.b.c}}</h2><button @click="test">修改obj.a.b.c</button></div></template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18})let obj = reactive({a:{b:{c:666}}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changePerson(){Object.assign(person,{name:'李四',age:80})}function test(){obj.a.b.c = 888}// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的watch(person,(nv,ov)=>{console.log('person变化了',nv,ov)})watch(obj,(nv,ov)=>{console.log('Obj变化了',nv,ov)})</script>

4.监视ref或reactive中某个属性

  • 当我们直接修改的时候直接把原对象的地址改了,在watch传入的第一个参数传递的时候就要看地址到底是谁的,可能是原对象的可能是已经改了的。
  • 总之一句话,如果我们只想监听对象的其中某个属性,将他写成箭头函数形式,并开启深度监听,记住就行。
<template><div class="person"><h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改第一台车</button><button @click="changeC2">修改第二台车</button><button @click="changeCar">修改整个车</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18,car:{c1:'奔驰',c2:'宝马'}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changeC1(){person.car.c1 = '奥迪'}function changeC2(){person.car.c2 = '大众'}function changeCar(){person.car = {c1:'雅迪',c2:'爱玛'}}// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式/* watch(()=> person.name,(newValue,oldValue)=>{console.log('person.name变化了',newValue,oldValue)}) */// 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数watch(()=>person.car,(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})
</script>

5.监视多个属性

  • 多个属性放数组里,说白了如果是单纯的监听某一个属性,写成箭头函数形式,如果监听某一个对象,那就直接写就行了。
<template><div class="person"><h1>情况五:监视上述的多个数据</h1><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改第一台车</button><button @click="changeC2">修改第二台车</button><button @click="changeCar">修改整个车</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18,car:{c1:'奔驰',c2:'宝马'}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changeC1(){person.car.c1 = '奥迪'}function changeC2(){person.car.c2 = '大众'}function changeCar(){person.car = {c1:'雅迪',c2:'爱玛'}}// 监视,情况五:监视上述的多个数据watch([()=>person.name,person.car],(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})</script>

总结

  • 今天学了ref、reactive、toRefs、watch监听的五大情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90364.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 JmsClient 的高效消息通信架构设计与实现

1. 引言 1.1 消息通信在分布式系统中的作用 随着企业级应用的复杂性不断提升,传统的同步调用方式已难以满足高并发、低延迟、高可用等需求。消息通信机制通过异步解耦的方式,提升了系统的可扩展性和容错能力。Java Message Service(JMS)作为一种标准的消息中间件接口,广…

2025.7.24

这题写了好一会, 因为遇到一些问题分糖分的是原来的糖果还是拿到了别人给的糖果加起来一起的?如果是分原来的糖果之后那就要再另外那一个数组存, 数组初始为0, 那么分完之后自己的那一份应该存进另一个数组, 是加法如果是分拿到了别人给的糖果加起来一起的, 那么分完之后不是直…

学习设计模式《十九》——享元模式

一、基础概念 享元模式的本质是【分离与共享】。 思考享元模式序号说明1 【分离】的是对象状态中变与不变的部分&#xff0c;【共享】的是对象中不变的部分&#xff1b; 享元模式的关键就在于【分离变与不变】把不变的部分作为享元对象的内部状态&#xff0c;而变化部分则作为外…

AI助力 三步实现电子发票发票号码的提取

小伙伴们&#xff0c;大家好今天我们来利用ollama本地大模型&#xff0c;三步实现电子发票发票号码的提取。 步骤1&#xff1a;安装Ollama访问官网https://ollama.com/ 下载相应的版本进行安装&#xff0c;下载属于自己平台的ollama&#xff0c;根据安装向导完成安装。…

告别下载中断:深入解析Tomcat JSP中的“远程主机强迫关闭连接”与“软件中止连接”

在Web开发中,提供文件下载功能是一项常见需求。然而,当用户在Tomcat JSP项目中尝试下载文件时,有时会遭遇令人头疼的错误提示:“远程主机强迫关闭了一个现有链接”(Remote host closed connection unexpectedly)或“您的主机中的软件中止了一个已建立的连接”(Software …

实战演练—基于Transformers的NLP解决方案总结

实战演练—基于Transformers的NLP解决方案总结 截至目前讲解的基础组件 以文本分类为例 Transformers显存优化 截至目前讲解的基础组件 Pipeline 流水线,用于模型推理,封装了完整的推理逻辑,包括数据预处理、模型预测及后处理 Tokenizer 分词器,用于数据预处理,将原始文本…

Java 解析前端上传 ZIP 压缩包内 Excel 文件的完整实现方案

使用zip压缩包上传excel文件的优点1、体积更小&#xff0c;节约带宽2、比excel直接读取更方便携带参数及修改3、可以一次性批量导入Java代码 ControllerPostMapping("/importData")ApiOperationSupport(order 3)ApiOperation(value "上传")public R impo…

【shell脚本编程】day1 备份指定文件类型

文章目录1、脚本要求2、脚本编写3、脚本解释4、脚本改进1、脚本要求 编写一个脚本&#xff0c;遍历/data/目录下的.txt文件将这些txt文件做一个备份备份的文件名增加一个年月日的后缀&#xff0c;比如将aming.txt备份为aming.txt_20231001 2、脚本编写 [rootlocalhost shell…

Gata 携手 Walrus 构建 AI 的开放执行基础设施

致力于开发去中心化大模型推理、训练和数据技术的 Gata&#xff0c;现已整合 Walrus&#xff0c;作为其 AI 开放执行基础设施的核心组件。Walrus 将为 Gata 的首款产品 DataAgent 提供关键的数据层&#xff0c;助力其全套应用&#xff0c;将去中心化 AI 的优势直接带给用户&…

DNS及DNS域名解析流程

文章目录什么是DNS域名解析DNS服务器DNS域名解析流程什么是DNS域名解析 我们首先要了解域名和IP地址的区别。IP地址是互联网上计算机唯一的逻辑地址&#xff0c;通过IP地址实现不同计算机之间的相互通信&#xff0c;每台联网计算机都需要通过IP地址来互相联系和分别。 但由于I…

用 STM32 的 SYSTICK 定时器与端口复用重映射玩转嵌入式开发

目录 1. SYSTICK 定时器的基本功:时间管理大师 1.1 SYSTICK 的核心寄存器与工作原理 1.2 配置 SYSTICK 的正确姿势 1.3 实战:用 SYSTICK 实现精准延时 1.4 小技巧:SYSTICK 的低功耗优化 2. SYSTICK 中断:让你的程序“活”起来 2.1 配置 SYSTICK 中断 2.2 实战:用 S…

Sa-Token:轻量级Java权限认证框架使用指南

一、Sa-Token简介 Sa-Token 是一个专注于权限认证的轻量级 Java 框架&#xff0c;旨在简化登录认证、权限控制等功能的实现。其核心功能包括&#xff1a; 登录认证&#xff1a;通过 Token 机制管理用户会话&#xff0c;支持单点登录&#xff08;SSO&#xff09;。权限认证&am…

动态 vs 静态住宅代理,哪种更适合广告投手?

在广告投放行业&#xff0c;无论你是跑Facebook、Google Ads&#xff0c;还是做TikTok、原生广告&#xff0c;代理IP几乎是绕不开的话题。而选择动态住宅代理还是静态住宅代理&#xff0c;对广告账户的稳定性、投放质量甚至生命周期都有直接影响。本篇文章将结合IPFoxy代理&…

命题是一种清晰、确定的表达。通过学习命题,来帮助你更清晰地表达自己的思想。

文章目录 引言 I 命题的特点 可以判断真伪 同一性 II 有效沟通的小技巧 多用陈述句,少用感叹句和疑问句。 在表述意思时,多用名词,少用代词;多用具体的名词,少用抽象的名词,避免造成不必要的歧义。 正确找托词 引言 要进行有效的逻辑推理,第一步是把我们的想法,我们要…

IPV6地址与IPV4有什么区别?

作为互联网协议的迭代版本&#xff0c;IPV6&#xff08;Internet Protocol Version 6&#xff09;与IPV4&#xff08;Internet Protocol Version 4&#xff09;在设计理念和功能特性上存在显著差异。本文将简要解析两者的核心区别&#xff0c;帮助读者理解IPV6的优势与必要性。…

python 什么时候应该用函数式编程,什么时候应该用面向对象?

在 Python 这个多范式语言中&#xff0c;选择使用函数式编程&#xff08;Functional Programming, FP&#xff09;还是面向对象编程&#xff08;OOP&#xff09;并非一个非黑即白的选择&#xff0c;而更像是在一个工具箱中为特定的任务挑选最合适的工具。 我们可以用一个比喻来…

【设计模式】迭代器模式 (游标(Cursor)模式)

迭代器模式&#xff08;Iterator Pattern&#xff09;详解一、迭代器模式简介 迭代器模式&#xff08;Iterator Pattern&#xff09; 是一种 行为型设计模式&#xff08;对象行为型模式&#xff09;&#xff0c;它提供了一种方法来顺序访问一个聚合对象中的各个元素&#xff0c…

docker安装 Elasticsearch、Kibana、IK 分词器

Elasticsearch 1.拉去镜像 docker pull elasticsearch:8.12.2 docker pull kibana&#xff1a;8.12.22.创建挂载目录 mkdir /root/elasticsearch3.不挂载启动 docker run -d \ --restartalways \ --name fusion_elasticsearch \ --network fusion_network \ -p 9200:9200 \ -p …

Java面试宝典:Spring专题二

一、介绍下Spring中的事务 1.Spring事务的本质与价值 Spring事务本质是基于AOP的声明式事务封装,通过代理机制在目标方法前后注入事务管理逻辑(开启、提交/回滚)。其核心价值在于: 业务解耦:将事务控制从业务代码剥离,通过配置或注解管理(如@Transactional)。 统一抽…

DGMR压缩技术:让大规模视觉Transformer模型体积减半而性能不减

Transformer架构展现出卓越的扩展特性&#xff0c;其性能随模型容量增长而持续提升。大规模模型在获得优异性能的同时&#xff0c;也带来了显著的计算和存储开销。深入分析主流Transformer架构发现&#xff0c;多层感知器&#xff08;MLP&#xff09;模块占据了模型参数的主要部…