欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > vue3入门知识(二)

vue3入门知识(二)

2025/2/24 10:10:01 来源:https://blog.csdn.net/qq_45937484/article/details/143556567  浏览:    关键词: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>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词