一、computed计算属性
<template><div class="person">姓:<input type="text" v-model="first_name"><br>名:<input type="text" v-model="last_name"><br><button @click="changeFullName">修改全名</button><br><!-- 计算属性的意义在于,full_name可以缓存起来,多次输出的时候,不用计算多次(如果使用函数,则会) -->全名<span>{{full_name}}</span><br>全名<span>{{full_name}}</span><br></div>
</template><script lang="ts">export default {name: 'Person'}
</script><script setup lang="ts">//1. 首先从vue引入refimport { ref, computed } from 'vue'let first_name = ref('zhang')let last_name = ref('san')// 此时full_name是只读的,并不能修改// let full_name = computed(() => {// return first_name.value.slice(0, 1).toUpperCase() + first_name.value.slice(1) + '-' + last_name.value// })// 如果full_name想要实现修改功能,需要实现set方法let full_name = computed({get() {return first_name.value.slice(0, 1).toUpperCase() + first_name.value.slice(1) + '-' + last_name.value},//当full_name被修改时,set被调用,且val会捕获到修改后的值set(val) {const [str1, str2] = val.split('-')first_name.value = str1last_name.value = str2}})function changeFullName() {//从这里引用方式(通过value才可以获取该值)可以看出,full_name其实是一个ref对象full_name.value = 'li-si'}</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 50px;}
</style>
二、watch监视
1、场景一
监视【ref】定义的【基本数据】类型
<template><div class="person"><h1>场景1:监视【ref】定义的【基本数据】类型</h1><br>sum的值: {{sum}}<br><button @click="changeSum">修改sum的值</button><br></div>
</template><script lang="ts">export default {name: 'Person'}
</script><script setup lang="ts">//1. 首先从vue引入refimport { ref, watch } from 'vue'let sum = ref(0)function changeSum() {sum.value += 1}let stopWatch = watch(sum, (newVal, oldVal) => {console.log('sum值变了', newVal, oldVal)if (newVal > 10) {stopWatch()}})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 50px;}
</style>
2、场景二
监视【ref】定义的【对象类型】数据
<template><div class="person"><h1>情况二:监视【ref】定义的【对象类型】数据</h1><br>姓名: {{person.name}}<br>年龄: {{person.age}}<br><button @click="changeName">修改name的值</button><br><button @click="changeAge">修改age的值</button><br><button @click="changePerson">修改person</button><br></div>
</template><script lang="ts">export default {name: 'Person'}
</script><script setup lang="ts">//1. 首先从vue引入refimport { ref, watch } from 'vue'let person = ref({name: 'Maple',age: 18})function changeName() {person.value.name = 'Max'}function changeAge() {person.value.age = 28}function changePerson() {person.value = { name: 'Kelly', age: 20 }}// 对于对象,watch监视的是对象的地址,所以如果只是对象的属性值(name和age)发生变化,并不会被监视到// 除非手动开启深度监视watch(person, (newVal, oldVal) => {console.log('person值变了', newVal, oldVal)}, { deep: true })</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 50px;}
</style>
3、场景三
监视【reactive】定义的【对象类型】数据
<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,(newValue,oldValue)=>{console.log('person变化了',newValue,oldValue)})watch(obj,(newValue,oldValue)=>{console.log('Obj变化了',newValue,oldValue)})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;}
</style>
与场景二不同的是,newVal和oldVal是一样的,表明通过Object.assign重新赋值的时候,并不是生成一个新的对象,而是新的值覆盖了旧值
4、场景四
监视【ref】或者【reactive】定义的【对象类型】数据的某个属性(基本数据类型或者对象类型-都建议写成函数形式)
<template><div class="person"><h1>情况四:监视【ref】或者【reactive】定义的【对象类型】数据的某个属性</h1><br>姓名: {{person.name}}<br>年龄: {{person.age}}<br>家人: {{person.family}}<br><button @click="changeName">修改name的值</button><br><button @click="changeAge">修改age的值</button><br><button @click="changePerson">修改person</button><br><button @click="changePersonFamily">修改person的family</button></div>
</template><script lang="ts">export default {name: 'Person'}
</script><script setup lang="ts">//1. 首先从vue引入refimport { reactive, watch } from 'vue'let person = reactive({name: 'Maple',age: 18,family: { 'father': 'David', 'mother': 'Lily' }})function changeName() {person.name = 'Max'}function changeAge() {person.age = 28}function changePersonFamily() {person.family = { 'father': 'Bob', 'mother': 'kathy' }}function changePerson() {Object.assign(person, { 'name': 'Jay', 'age': 30, family: { 'father': 'Bob', 'mother': 'kathy' } })}// 如果要监视某个属性,且该属性是基本数据类型,需要写成函数的形式(因为watch能够监视的对象只能是ref,reactive//、对象或者函数)watch(() => person.name, (newVal, oldVal) => {console.log('person的name值变了', newVal, oldVal)})//person.family虽然是对象数据类型,也要写成函数形式watch(() => person.family, (newVal, oldVal) => {console.log('person的family发生了变换', newVal, oldVal)}, { deep: true })
</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 50px;}
</style>
5、场景五
监视上述多个数据
<template><div class="person"><h1>情况五:监视上述多个数据</h1><br>姓名: {{person.name}}<br>年龄: {{person.age}}<br>家人: {{person.family}}<br><button @click="changeName">修改name的值</button><br><button @click="changeAge">修改age的值</button><br><button @click="changePerson">修改person</button><br><button @click="changePersonFamily">修改person的family</button></div>
</template><script lang="ts">export default {name: 'Person'}
</script><script setup lang="ts">//1. 首先从vue引入refimport { reactive, watch } from 'vue'let person = reactive({name: 'Maple',age: 18,family: { father: 'David', mother: 'Lily' }})function changeName() {person.name = 'Max'}function changeAge() {person.age = 28}function changePersonFamily() {person.family = { father: 'Bob', mother: 'kathy' }}function changePerson() {Object.assign(person, { 'name': 'Jay', 'age': 30, family: { father: 'Bob', mother: 'kathy' } })}// 如果要监视多个属性,以函数的形式放在数组里watch([() => person.name, () => person.family], (newVal, oldVal) => {console.log('person的name和family值变了', newVal, oldVal)}, { deep: true })</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 50px;}
</style>