vue3入门知识(二)

devtools/2024/11/15 23:58:36/

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值的改变

javascript"><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定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视

javascript"><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定义的【对象类型】数据,且默认开启了深度监视

javascript"><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)若该属性依然是【对象类型】,可直接写,也可写成函数,建议写成函数

javascript"><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. 监视响应式对象中的某几个属性

javascript"><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:不用明确指出监视的数据(其中用到哪些数据就监视哪些属性)

javascript"><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. 用在组件标签上,获取的是组件实例对象

javascript">// 父组件
<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>
javascript">// 子组件
<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>

 接口、自定义类型、泛型

javascript">// src/types/index.ts
// 定义一个接口 用于限制person对象的具体属性
export interface PersonInter {name: string,age: number,id: string,
};// 一个自定义类型
// export type Persons = Array<PersonInter>; // 泛型
export type Persons = PersonInter[];
javascript"><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>

组件通信--父传子

javascript"><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.ppmy.cn/devtools/134288.html

相关文章

数据仓库面试题集离线实时

一、Flink面试问题集 1、flinkkafka 如何保证精准一次 配置两阶段提交 2、Flink提交方式&#xff0c; 使用pre-job还是yarn-session模式&#xff0c;以及Application模式&#xff0c;好处&#xff1f; Flink提交模式模式对比 3、Flink UV统计实现 set布隆过滤器redis 有误…

云时代基础设施模型:可变与不可变之析

在基础设施管理的领域中&#xff0c;存在两种起着主导作用的方法&#xff0c;也就是可变基础设施与不可变基础设施。它们决定着资源的部署以及维护的模式&#xff0c;对更新的实施途径、基础设施的演进方向&#xff0c;还有不同环境之间的一致性保障起着关键的作用。 可变基础设…

比ChatGPT更酷的AI工具

相较于寻找比ChatGPT更酷的AI工具&#xff0c;这听起来似乎是个挑战&#xff0c;因为ChatGPT已经以它强大的综合性能在AI界大名鼎鼎。然而&#xff0c;每个工具都有其独特的优势&#xff0c;特别是在特定的应用场景下&#xff0c;其他AI工具可能会展现出与ChatGPT不同的魅力。接…

计算机视觉 ---常见图像文件格式及其特点

常见的图像文件格式及其特点如下&#xff1a; JPEG&#xff08;Joint Photographic Experts Group&#xff09; 特点&#xff1a; 有损压缩&#xff1a;通过丢弃一些图像数据来实现高压缩比&#xff0c;能显著减小文件大小&#xff0c;适合用于存储照片等色彩丰富的图像。但过…

<项目代码>YOLOv8 玉米地杂草识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

ScrumMaster认证机构及CSM、PSM、RSM价值解析

近十年Scrum在国内备受关注&#xff0c;成为一种最流行的现代敏捷工作方式。ScrumMaster这一独特的角色&#xff0c;在企业内部推动Scrum落地的过程中越来越重要。各种ScrumMaster认证课程也蜂拥而至&#xff0c;甚至鱼目混珠。 我们为大家梳理了目前市面上出现的ScrumMaster认…

安全见闻 -- 二进制与网络安全的关系

声明&#xff1a; 本文的学习内容来源于B站up主“泷羽sec”的公开分享&#xff0c;所有内容仅限于网络安全技术的交流学习&#xff0c;不涉及任何侵犯版权或其他侵权意图。如有任何侵权问题&#xff0c;请联系本人&#xff0c;我将立即删除相关内容。 本文旨在帮助网络安全爱好…

C# WPF FontDialog字体对话框,ColorDialog颜色对话框 引用

WPF 并没有内置FontDialog和ColorDialog&#xff0c;但可以通过引用 Windows Forms 的控件来实现字体和颜色选择对话框功能。FontDialog 允许用户选择字体、样式、大小等设置。 添加 Windows Forms的引用 项目工程&#xff1a;右键“引用”》“添加引用”》勾选System.Windows…