vue3入门知识(二)

computed

计算属性是有缓存的,方法没有缓存

计算属性得到的数据是一个ref定义的响应式数据

<template><div class="person">姓:<input type="text" v-model="firstName"><br>名:<input type="text" v-model="lastName"><br>全名:<span>{{ fullName }}</span><br><button @click="changeFullName">修改名字</button></div>
</template><script setup lang="ts" name="Person"> 
import { ref, computed } from 'vue';let firstName = ref('张');
let lastName = ref('三');// 这样定义的计算属性是只读的
// let fullName = computed(() => {
//     return firstName.value + '-' + lastName.value;
// });// 这样定义的计算属性是可读可写的
let fullName = computed({get() {return firstName.value + '-' + lastName.value;},set(newValue) {const names = newValue.split('-');firstName.value = names[0];lastName.value = names[1];}
});function changeFullName() {fullName.value = '李-四';
};
</script>

watch

监视数据的变化,vue3中watch只能监视以下四种数据:

1. ref定义的数据

2. reactive定义的数据

3. 函数返回一个值(getter函数)

4. 一个包含上述内容的数组

1. 监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变

<template><div class="person"><h2>当前求和为:{{ sum }}</h2><button @click="changeSum">点我sum+1</button></div>
</template><script setup lang="ts" name="Person"> 
import { ref, watch } from 'vue';let sum = ref(0);// const stopWatch = watch(sum, (newVal, oldVal) => {
//     console.log('sum.value changed: ', newVal, oldVal);
//     if (newVal > 10) {
//         // 当 sum 大于10时,取消监听
//         stopWatch();
//     }
// });watch(sum, (newVal, oldVal) => {console.log('sum.value changed: ', newVal, oldVal);
});function changeSum() {sum.value++;
};
</script>

2. 监视ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视

<template><div class="person"><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改</button></div>
</template><script setup lang="ts" name="Person"> 
import { ref, watch } from 'vue';let person = ref({name: '张三',age: 18,
});// watch的第一个参数是:被监视的数据
// watch的第二个参数是:监视的回调函数
// watch的第三个参数是:配置对象(deep、immediate等)// 监视的是对象的地址值
// watch(person, (newVal, oldVal) => {
//     console.log('person changed', newVal, oldVal);
// });// 监视对象内部属性的变化 手动开启深度监听 立即执行 immediate: true
watch(person, (newVal, oldVal) => {// 当对象整体被替换时 newVal 和 oldVal 不同// 当对象中某个属性被修改 newVal 和 oldVal 相同console.log('person changed', newVal, oldVal);
}, { deep: true });function changeName() {person.value.name += '~';
};
function changeAge() {person.value.age++;
};
function changePerson() {person.value = {name: '李四',age: 80,};
}
</script><style scoped lang="less">
.person {button {margin: 0 10px;}
}
</style>

3. 监视reactive定义的【对象类型】数据,且默认开启了深度监视

<template><div class="person"><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person.age }}</h2><button @click="changeName">修改姓名</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改</button></div>
</template><script setup lang="ts" name="Person"> 
import { reactive, watch } from 'vue';let person = reactive({name: '张三',age: 18,
});// 监视【reactive】定义的【对象类型】数据 默认是开启深度监听的 且无法关闭
watch(person, (newVal, oldVal) => {// newVal 和 oldVal 相同 因为修改时操作的是同一个对象console.log('person changed', newVal, oldVal);
});function changeName() {person.name += '~';
};
function changeAge() {person.age++;
};
function changePerson() {Object.assign(person, {name: '李四',age: 80,});
}
</script><style scoped lang="less">
.person {button {margin: 0 10px;}
}
</style>

4. 监视ref或reactive定义的【对象类型】数据中的某个属性

(1)若该属性不是【对象类型】,需要写成函数形式

(2)若该属性依然是【对象类型】,可直接写,也可写成函数,建议写成函数

<template><div class="person"><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 setup lang="ts" name="Person"> 
import { reactive, watch } from 'vue';let person = reactive({name: '张三',age: 18,car: {c1: '奔驰',c2: '宝马',},
});// 监视响应式对象中的某个属性 且该属性是基本类型的 要写成函数式
watch(() => { return person.name }, (newVal, oldVal) => {// newVal 和 oldVal 不同console.log('person.name changed', newVal, oldVal);
});// 监视响应式对象中的某个属性 且该属性是对象类型的 建议写成函数式否则整体修改时监听不到 需要加深度监听
watch(() => { return person.car }, (newVal, oldVal) => {// newVal 和 oldVal 不同console.log('person.car changed', newVal, oldVal);
}, { deep: true });function changeName() {person.name += '~';
};
function changeAge() {person.age++;
};
function changeC1() {person.car.c1 = '奥迪';
};
function changeC2() {person.car.c2 = '保时捷';
};
function changeCar() {person.car = {c1: '11',c2: '22',};
};
</script><style scoped lang="less">
.person {button {margin: 0 10px;}
}
</style>

5. 监视响应式对象中的某几个属性

<template><div class="person"><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 setup lang="ts" name="Person"> 
import { reactive, watch } from 'vue';let person = reactive({name: '张三',age: 18,car: {c1: '奔驰',c2: '宝马',},
});// 监视响应式对象中的某几个属性
watch([() => { return person.name }, () => { return person.car.c1 }], (newVal, oldVal) => {console.log('person.car changed', newVal, oldVal);
}, { deep: true });function changeName() {person.name += '~';
};
function changeAge() {person.age++;
};
function changeC1() {person.car.c1 = '奥迪';
};
function changeC2() {person.car.c2 = '保时捷';
};
function changeCar() {person.car = {c1: '11',c2: '22',};
};
</script><style scoped lang="less">
.person {button {margin: 0 10px;}
}
</style>

watchEffect

立即执行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数

watch 和 watchEffect 对比:

1. 都能监听响应式数据的变化,监听数据变化的方式不同

2. watch:要明确指出监视的数据

3. watchEffect:不用明确指出监视的数据(其中用到哪些数据就监视哪些属性)

<template><div class="person"><h2>当前水温:{{ temp }}度</h2><h2>当前水位:{{ height }}cm</h2><button @click="changeTemp">水温+10</button><button @click="changeHeight">水位+10</button></div>
</template><script setup lang="ts" name="Person"> 
import { ref, watch, watchEffect } from 'vue';const temp = ref(10);
const height = ref(0);// watch([temp, height], (newVal) => {
//     const [t, h] = newVal;
//     if(t >= 60 || h >= 80) {
//         console.log('发送请求');
//     }
// });watchEffect(() => {// 会立即执行一次console.log('执行了');if(temp.value >= 60 || height.value >= 80) {console.log('发送请求');}
});function changeTemp() {temp.value += 10;
};
function changeHeight() {height.value += 10;
};
</script><style scoped lang="less">
.person {button {margin: 0 10px;}
}
</style>

标签的ref

1. 用在普通DOM标签上,获取的是DOM节点

2. 用在组件标签上,获取的是组件实例对象

// 父组件
<template><h2>中国</h2><h2 ref="title2">北京</h2><h2>朝阳</h2><button @click="showLog">输出</button><Person ref="ren"></Person>
</template><script lang="ts" setup name="App">
import Person from './components/Person.vue';
import { ref } from 'vue';const title2 = ref();
const ren = ref();function showLog() {// console.log(title2.value); // 输出html标签console.log(ren.value); // 输出组件实例
}
</script>
// 子组件
<template><div class="person"></div>
</template><script setup lang="ts" name="Person"> 
import { ref, defineExpose } from 'vue';const a = ref(0);
const b = ref(1);
const c = ref(2);// 在这里暴露出去的值 父组件才可以拿到
defineExpose({a, b});
</script>

 接口、自定义类型、泛型

// src/types/index.ts
// 定义一个接口 用于限制person对象的具体属性
export interface PersonInter {name: string,age: number,id: string,
};// 一个自定义类型
// export type Persons = Array<PersonInter>; // 泛型
export type Persons = PersonInter[];
<template><div class="person"></div>
</template><script setup lang="ts" name="Person">
import { type PersonInter, type Persons } from '@/types';const person:PersonInter = {name: '张三',age: 18,id: '1',
};const persons:Array<PersonInter> = [{name: '张三',age: 18,id: '1',},{name: '李四',age: 18,id: '2',},
];const personList:Persons = [{name: '张三',age: 18,id: '1',},{name: '李四',age: 18,id: '2',},
];
</script>

组件通信--父传子

<template><div class="person"><!-- <h2>{{ a }}</h2> --><!-- <h2>{{ list }}</h2> --><ul><li v-for="item in list" :key="item.id">{{ item.name }} -- {{ item.age }}</li></ul></div>
</template><script setup lang="ts" name="Person">
// defineProps不用引入也可以使用
// 在vue3中 defineXXX 叫作宏函数 不用引入也可以使用
import { defineProps, withDefaults } from 'vue';
import {type Persons} from '@/types'// 接收a 同时保存起来 可以在脚本中使用
// const x = defineProps(['a', 'b']);
// console.log(x.a);// 接收list 但这样无法在脚本中使用
// defineProps(['list']);// 接收list 并限制类型
// defineProps<{list:Persons}>();// 接收list 并限制类型 并限制必要性 并指定默认值
withDefaults(defineProps<{list?:Persons}>(), {list: () => [{name: '张三',age: 18,id: '1',},{name: '李四',age: 20,id: '2',}]
});
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

集合卡尔曼滤波(EnsembleKalmanFilter)的MATLAB例程(三维、二维)

本 M A T L A B MATLAB MATLAB代码实现了一个三维动态系统的集合卡尔曼滤波&#xff08;Ensemble Kalman Filter, EnKF&#xff09;示例。代码的主要目的是通过模拟真实状态和测量值&#xff0c;使用 EnKF 方法对动态系统状态进行估计。 文章目录 参数设置初始化真实状态定义状…

OpenGL ES 共享上下文实现多线程渲染

OpenGL ES 共享上下文时,可以共享哪些资源? 共享上下文实现多线程渲染 EGL 概念回顾 EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信; 查询绘图表面的可用类型和配置; 创建绘图表面; 在OpenGL ES 和…

如何安装和使用SSH远程连接工具MobaXterm

文章目录 一、下载二、安装三、使用四、配置1、配置默认编辑器2、配置右键粘贴3、SSH配置4、关闭X-Server服务 一、下载 1、进入官网&#xff1a;https://mobaxterm.mobatek.net/download-home-edition.html 2、Download——>Home Edition。 3、下载绿色安装版本。 二、安…

Java项目实战II基于微信小程序的原创音乐小程序(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着移动互…

linux-文件的读写

操作系统一切皆文件&#xff0c;访问文件实际上就是访问硬件&#xff0c;因为文件都保存在硬件上&#xff0c;或者文件就是硬件&#xff0c;而要访问硬件&#xff0c;就需要操作系统提供的系统调用&#xff0c;所以c/c函数中关于访问硬件设备&#xff0c;基本上是由系统调用封装…

「实战应用」如何可视化 DHTMLX Scheduler 中的资源工作量?

DHTMLX Scheduler是一个全面的 UI 组件&#xff0c;用于处理面向业务的 Web 应用程序中复杂的调度和任务管理需求。但是&#xff0c;某些场景可能需要自定义解决方案。例如&#xff0c;如果项目的资源&#xff08;即劳动力&#xff09;有限&#xff0c;则需要确保以更高的精度分…

RNA-seq 差异分析的点点滴滴(2)

引言 本系列[1]将开展全新的转录组分析专栏&#xff0c;主要针对使用DESeq2时可能出现的问题和方法进行展开。 Tximeta&#xff1a;自动导入并附加元数据 Bioconductor 家族中的 tximeta 包&#xff0c;在 tximport 的基础上进行了扩展&#xff0c;不仅保留了原有功能&#xff…

Pycharm PyQt5 环境搭建创建第一个Hello程序

第一步: 创建Pycharm项目,下载包: pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/pip install PyQt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/下载好了之后,可以看到相应包: PyQt5:PyQt5是一套Python绑定Digia QT5应用的框架。Qt库是最…

安装luasocket模块时提示“sudo: luarocks:找不到命令“问题,该如何解决?

大家好&#xff0c;我是袁庭新。分享一个我在使用luarocks来安装luarocks模块报错的解决方法。 在Unix系统中安装LuaRocks。本文我以CentOS 7.x系统为例&#xff0c;来讲解如何安装LuaRocks。 $ cd /opt $ wget https://luarocks.org/releases/luarocks-3.11.1.tar.gz $ tar …

Axure安装步骤及免费替代方案

Axure作为一款强大的原型设计工具&#xff0c;因其丰富的功能而受到设计师的青睐。它包括动态面板、复杂表格编辑、协同设计和高保真原型设计等&#xff0c;这些功能可以简化复杂的设计流程&#xff0c;提高团队效率。本文将介绍Axure的安装方法&#xff0c;并探索一款新兴的Ax…

分布式数据库:架构、优势与实践应用

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 分布式数据库在现代信息技术中扮演着至关重要的角色&#xff0c;尤其在需要处理大规模数据和实现高可用性、可扩展性的应用中更是…

小试银河麒麟系统OCR软件

0 前言 今天在国产电脑上办公&#xff0c;需要从一些PDF文件中复制文字内容&#xff0c;但是这些PDF文件是图片转换生成的&#xff0c;不支持文字选择和复制&#xff0c;除了手工输入&#xff0c;我们还可以使用OCR。 1 什么是OCR OCR &#xff08;Optical Character Recogni…

np.zeros_like奇怪的bug

import numpy as np aa np.array([[1,2,3],[2,3,3]]) cc np.random.randn(2,3) print(aa) print(cc)bb np.zeros_like(aa) print(bb)for i in range(bb.shape[0]):for j in range(bb.shape[1]):bb[i,j] cc[i,j]print(bb)结果如下 这里发现这个bb的结果是没有赋值的 正确做…

C++(Qt)软件调试---内存泄漏分析工具MTuner (25)

C(Qt)软件调试—内存泄漏分析工具MTuner &#xff08;25&#xff09; 文章目录 C(Qt)软件调试---内存泄漏分析工具MTuner &#xff08;25&#xff09;[toc]1、概述&#x1f41c;2、下载MTuner&#x1fab2;3、使用MTuner分析qt程序内存泄漏&#x1f9a7;4、相关地址&#x1f41…

apk反编译修改教程系列-----apk应用反编译中AndroidManifest.xml详细代码释义解析 包含各种权限 代码含义

在反编译apk应用中。需要增加或者减少有些apk功能或者权限类的修改。其中大多都在于 AndroidManifest.xml文件中。了解AndroidManifest.xml其中每串代码代表的含义对修改apk有着至关重要的作用。 通过博文了解💝💝💝💝 1💝💝💝💝----AndroidManifest.xml中代…

项目功能--运营数据统计

一、需求分析 通过运营数据统计可以展示出体检机构的运营情况&#xff0c;包括会员数据、预约到诊数据、热门套餐等信息。我们要通过一个表格的形式来展示这些运营数据。如下图&#xff1a; 二、代码实现 实现步骤&#xff1a; 步骤一&#xff1a;定义数据模型&#xff0c;通过…

电子制造行业Top5贴片机品牌

在电子制造业的快速发展中&#xff0c;SMT&#xff08;Surface Mount Technology&#xff09;表面贴装技术扮演着至关重要的角色。贴片机作为SMT生产线的核心设备&#xff0c;其性能直接关系到整个生产线的效率和产品质量。 SPEA作为全球领先的自动化测试设备服务商&#xff0…

【maven踩坑】一个坑 junit报错 但真正导致这个的不是junit的原因

目录 事件起因环境和工具操作过程解决办法结束语 事件起因 报错一&#xff1a; Internal Error occurred. org.junit.platform.commons.JUnitException: TestEngine with ID junit-vintage failed to discover tests报错二&#xff1a; Internal Error occurred. org.junit.pl…

拷贝和浅拷贝的区别,以及对于循环引用如何处理深拷贝

深拷贝和浅拷贝的区别&#xff0c;以及对于循环引用如何处理深拷贝 浅拷贝仅拷贝对象的第一层属性值&#xff0c;对于基本数据类型&#xff0c;会复制其值&#xff1b;对于引用数据类型&#xff0c;仅复制引用地址而不复制实际的对象内容。浅拷贝后的新对象与原对象中的引用类…

gitlab与jenkins

一 gitlab代码仓库 1.1 gitlab简介 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用 Git 作为代码管理工具&#xff0c;并在此基础上搭建起来的 web 服务。GitLab 具有很多功能&#xff0c;比如代码托管、持续集成和持续部署&#xff08;CI/CD&#xff09;、问题跟踪…