当前位置: 首页 > news >正文

从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.lryc.cn/news/598429.html

相关文章:

  • Vue3 面试题及详细答案120道(91-105 )
  • 个人笔记GUI
  • 【Python】Python多线程爬虫实战:从基础原理到分布式架构实现
  • Linux 基本命令整理
  • #来昇腾学AI 【十天成长计划】大模型LLM Prompt初级班
  • 详解力扣高频 SQL 50 题-1757.可回收且低脂的产品【入门】
  • 保障工业核心命脉:深度解读工业交换机QoS的“智能流量治理”之道
  • docker设置字体及时间,映射到宿主机上
  • rustfs/rustfs基于 Rust 的高性能分布式存储系统
  • 数字系统自动设计:从C++到门级网表
  • EXCEL——INDEX和MATCH傻傻分不清?
  • 基于QT(C++)实现(图形界面)选课管理系统
  • 网易大模型算法面经总结第一篇
  • 【News】同为科技亮相首届气象经济博览会
  • Qt 元对象系统(Meta-Object System)解析
  • 【C#补全计划:类和对象(六)】
  • 【Linux基础知识系列】第六十三篇 - 文件编辑器基础:vim
  • Windows11 本地安装docker Desktop 部署dify 拉取镜像报错
  • 告别下载中断:深入解析Tomcat JSP中的“远程主机强迫关闭连接”与“软件中止连接”
  • BI 系统数据看板全解析:让数据可视化驱动业务决策
  • k8s之ingress定义https访问方式
  • 使用Claude Code从零到一打造一个现代化的GitHub Star项目管理器
  • QT项目-仿QQ音乐的音乐播放器(第二节)
  • 【初识数据结构】CS61B 中的归并排序和选择排序
  • [网安工具] 自动化威胁检测工具 —— D 盾 · 使用手册
  • kubernetes集群中部署CoreDNS服务
  • OceanBase 4.3.5 解析:DDL性能诊断
  • 爆肝整理,性能测试详细汇总,从0到1打通(二)
  • 基于深度学习的胸部 X 光图像肺炎分类系统(三)
  • 在 OceanBase 中,使用 TO_CHAR 函数 直接转换日期格式,简洁高效的解决方案