toRefs与toRef
作用:将一个响应式对象的属性 都换转换ref对象
<template>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>性别:{{ person.gender }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeGender">修改性别</button>
</template>
<script lang="ts" setup name="Person">
import {reactive, toRef, toRefs} from "vue";
let person = reactive({name: '张三', age: 20, gender: '男'})
//通过toRefs 将person中的属性 批量取出(ref),保持响应式
let {name, gender} = toRefs(person)
//通过toRef将person中的一个属性 取出来(ref) 保持响应式
let age = toRef(person, 'age');
const changeName = () => {
name.value += "*";
}
const changeAge = () => {
age.value += 1;
}
const changeGender = () => {
gender.value = "女"
}
</script>
<style scoped>
</style>
computed
作用:根据已有属性计算新的属性,有缓存机制 当已有属性改变时计算属性也会变
<template>
姓:<input type="text" v-model="firstName"/><br/><br/>
名:<input type="text" v-model="laseName"/><br/><br/>
<!-- 全名:<span>
{{ fullName }}
{{ fullName }}
{{ fullName }}
{{ fullName }}
</span>-->
全名:<input type="text" v-model="fullName"/>
</template>
<script lang="ts" setup name="Person">
import {computed, ref} from "vue";
let firstName = ref("张");
let laseName = ref("三");
//通过计算属性(只读取)不修改
// let fullName = computed(() => {
// console.log("执行了计算属性 fullName")
// return firstName.value + "-" + laseName.value;
// })
//通过计算属性(读/写)不修改
let fullName = computed({
get() {
//读取
console.log("fullName get");
return firstName.value + "-" + laseName.value;
},
set(value) {
//写入
console.log("fullName set,", value);
let arr = value.split("-");
firstName.value = arr[0];
laseName.value = arr[1];
}
})
</script>
<style scoped>
</style>
watch 监视
在Vue3中 watch只能监视四中数据
1.ref定义的数据
2.reactive定义的数据
3.函数返回的一个值
4.包含上述内容的数组
监视ref定义的基本数据类型
<template>
<h1>情况一:监视ref定义的数据</h1>
<h2>count:{{ count }}</h2>
<button @click="changeCount">点击count+1</button>
</template>
<script lang="ts" setup name="Person">
import {ref, watch} from "vue";
let count = ref(0);
const changeCount = () => {
count.value += 1;
}
//监视ref定义的数据
const stopWatch = watch(count, (newValue, oldValue) => {
console.log("count改变了", newValue, oldValue)
if (count.value >= 5) {
//停止监视
stopWatch();
}
})
</script>
<style scoped>
</style>
监视ref定义的对象类型数据
数据:直接写数据名,监视的是对象的地址,如果要监视对象的属性,启用深度监视
<template>
<h1>情况二:监视ref定义的对象类型数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="changeName">修改姓名</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改对象</button>
</template>
<script lang="ts" setup name="Person">
import {ref, watch} from "vue";
let person = ref({name: "张三", age: 25});
const changeName = () => {
person.value.name += "~";
}
const changeAge = () => {
person.value.age += 1;
}
const changePerson = () => {
person.value = {name: "李四", age: 30};
}
//监视ref定义的对象类型数据
//监视person对象的整体改变
// watch(person, (newValue, oldValue) => {
// console.log("person改变了", newValue, oldValue)
// })
//deep: true 深度监视 监视对象下所有的属性
/***
* 参数1:被监视的数据
* 参数2:监视的回调函数
* 参数3,配置对象(deep.immediate.....)
*/
watch(person, (newValue, oldValue) => {
console.log("person改变了", newValue, oldValue)
}, {deep: true})
</script>
<style scoped>
</style>
监视reactive定义的对象类型数据
默认开启深度监视
<template>
<h1>情况二:监视ref定义的对象类型数据</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.d }}</h2>
<button @click="test">修改d</button>
</template>
<script lang="ts" setup name="Person">
import {reactive, watch} from "vue";
let person = reactive({name: "张三", age: 25});
let obj = reactive({a: {b: {c: {d: 666}}}})
const changeName = () => {
person.name += "~";
}
const changeAge = () => {
person.age += 1;
}
const changePerson = () => {
// person = {name: "李四", age: 30};
Object.assign(person, {name: "李四", age: 30})
}
const test = () => {
obj.a.b.c.d = 888;
}
/**
* 通过 reactive 定义的对象类型数据 监视 默认开启深度监视
*/
watch(person, (newValue, oldValue) => {
console.log("person改变了", newValue, oldValue)
})
watch(obj, (newValue, oldValue) => {
console.log("obj改变了", newValue, oldValue)
})
</script>
<style scoped>
</style>
监视ref或者reactive定义的对象类型数据中的 "某个属性"
<template>
<div>
<h2>监视reactive或者 ref定义的对象类型的某个属性</h2>
<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: 25,
car: {
c1: '比亚迪',
c2: "雅迪"
}
})
const changeName = () => {
person.name += "!";
}
const changeAge = () => {
person.age += 1;
}
const changeC1 = () => {
person.car.c1 = "奥迪";
}
const changeC2 = () => {
person.car.c2 = "小牛";
}
const changeCar = () => {
person.car = {c1: "爱玛", c2: '小刀'};
}
//监视响应式对象中的某个数据 并且该数据是基本类型,要写函数式
// watch(() => person.name, (newValue, oldValue) => {
// console.log("name发生了改变",newValue, oldValue);
// })
/**
* 监视响应式对象中的 某个属性 并且改属性为对象类型,
* 直接写,写函数,更推荐函数式
*/
watch(() => person.car, (newValue, oldValue) => {
console.log("car发生了改变", newValue, oldValue);
}, {deep: true})
//直接写的方式监视 只能监视到 属性的改变,并且在替换后 不能在监视
watch(person.car, (newValue, oldValue) => {
console.log("car发生了改变", newValue, oldValue);
}, {deep: true})
</script>
<style scoped>
</style>
监视上述多个数据
<template>
<div>
<h2>监视上述多个数据</h2>
<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: 25,
car: {
c1: '比亚迪',
c2: "雅迪"
}
})
const changeName = () => {
person.name += "!";
}
const changeAge = () => {
person.age += 1;
}
const changeC1 = () => {
person.car.c1 = "奥迪";
}
const changeC2 = () => {
person.car.c2 = "小牛";
}
const changeCar = () => {
person.car = {c1: "爱玛", c2: '小刀'};
}
watch([() => person.name, person.car], (newValue, oldValue) => {
console.log("person.name, person.car",newValue, oldValue)
}, {deep: true});
</script>
<style scoped>
</style>