一 computd计算属性
computed 是 Vue 3 中用于创建计算属性的功能。它允许你定义基于响应式数据的动态值,这些值会在其依赖的数据发生变化时自动更新。
- 使用场景
- 依赖于其他响应式数据的计算结果:你可以创建一个计算属性,其值依赖于其他响应式数据,并在这些数据变化时自动更新。
- 性能优化:computed 属性会进行缓存,只有当其依赖的数据发生变化时,才会重新计算,从而提高性能。
只读计算属性
<template> <div> <p>名称: {{ name }}</p> <p>全名: {{ fullName }}</p> </div> </template> <script> import { ref, computed } from 'vue'; export default { setup() { const firstName = ref('John'); const lastName = ref('Doe'); const fullName = computed(() => `${firstName.value} ${lastName.value}`); return { firstName, lastName, fullName }; } } </script>
复制
关键点
定义:使用 computed 来创建计算属性。例如:
const fullName = computed(() => firstName.value{lastName.value});
复制
访问:计算属性的值可以直接使用,如 {{ fullName }},不需要 .value。
缓存:计算属性会缓存计算结果,只有在依赖的响应式数据变化时才会重新计算。
在 Vue 3 中,computed 属性默认是只读的,但你可以使用一个带有 getter 和 setter 的 computed 属性来实现读写功能。这种方式允许你定义一个计算属性,并同时为它指定一个 setter 函数来处理值的设置。
使用读写计算属性
<template> <div> <p>Count: {{ count }}</p> <p>Doubled: {{ doubled }}</p> <input v-model="doubled" /> </div> </template> <script> import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubled = computed({ get: () => count.value * 2, set: (value) => { count.value = value / 2; } }); return { count, doubled }; } } </script>
复制
在这个模板中,doubled 计算属性可以通过输入框进行双向绑定,因为它同时有 getter 和 setter 函数。这样,当输入框的值改变时,count 也会相应地更新。
二 watch
watch 是 Vue 3 中用于观察响应式数据变化并执行相应逻辑的功能。它允许你监控一个或多个响应式数据的变化,并在这些数据发生变化时执行回调函数。
- 作用:监视数据的变化(和
Vue2
中的watch
作用一致) - 特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。- 一个包含上述内容的数组。
- 监视 ref 数据
- 监视
ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
import { ref, watch } from 'vue'; export default { setup() { const count = ref(0); watch(count, (newValue, oldValue) => { console.log(`Count changed from ${oldValue} to ${newValue}`); }); return { count }; } }
复制
- 监视
ref
定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
```vue <template> <div class="person"> <h1>情况二:监视【ref】定义的【对象类型】数据</h1> <h2>姓名:{{ person.name }}</h2> <h2>年龄:{{ person.age }}</h2> <button @click="changeName">修改名字</button> <button @click="changeAge">修改年龄</button> <button @click="changePerson">修改整个人</button> </div> </template> <script lang="ts" setup name="Person"> import {ref,watch} from 'vue' // 数据 let person = ref({ name:'张三', age:18 }) // 方法 function changeName(){ person.value.name += '~' } function changeAge(){ person.value.age += 1 } function changePerson(){ person.value = {name:'李四',age:90} } watch(person,(newValue,oldValue)=>{ console.log('person变化了',newValue,oldValue) },{deep:true}) </script>
复制
- 监视
ref
定义的【对象类型】数据中的某个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
let person = ref({ name:'张三', age:18, car:{ c1:'奔驰', c2:'宝马' } }) watch(()=> person.name,(newValue,oldValue)=>{ console.log('person.name变化了',newValue,oldValue) }) watch(()=>person.car,(newValue,oldValue)=>{ console.log('person.car变化了',newValue,oldValue) },{deep:true})
复制
2- 监视 reactive 数据
- 监视
reactive
定义的【对象类型】数据,且默认开启了深度监视。
let person = reactive({ name:'张三', age:18 }) watch(person,(newValue,oldValue)=>{ console.log('person变化了',newValue,oldValue) })
复制
- 监视
reactive
定义的【对象类型】数据中的某个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
let person = ref({ name:'张三', age:18, car:{ c1:'奔驰', c2:'宝马' } }) watch(()=> person.name,(newValue,oldValue)=>{ console.log('person.name变化了',newValue,oldValue) }) watch(()=>person.car,(newValue,oldValue)=>{ console.log('person.car变化了',newValue,oldValue) },{deep:true})
复制
- 监视函数返回值(getter 函数)
import { ref, computed, watch } from 'vue'; export default { setup() { const count = ref(0); const doubled = computed(() => count.value * 2); watch(doubled, (newValue, oldValue) => { console.log(`Doubled value changed from ${oldValue} to ${newValue}`); }); return { count, doubled }; } }
复制
- 监视多个数据源(数组)
import { ref, reactive, watch } from 'vue'; export default { setup() { const count = ref(0); const state = reactive({ name: 'Vue' }); watch([count, () => state.name], ([newCount, newName], [oldCount, oldName]) => { console.log(`Count changed from ${oldCount} to ${newCount}`); console.log(`Name changed from ${oldName} to ${newName}`); }); return { count, state }; } }
复制
三 watchEffect
watchEffect 是 Vue 3 中用于自动执行副作用的功能,它会根据内部使用的响应式数据自动追踪和重新运行。与 watch 不同,watchEffect 不需要指定数据源,它会在副作用函数中自动追踪所有使用的响应式数据。
watch
对比watchEffect
都能监听响应式数据的变化,不同的是监听数据变化的方式不同
watch
:要明确指出监视的数据
watchEffect
:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。
使用场景
- 简单的副作用:当你只需要执行副作用而不需要控制特定的数据源时。
- 自动追踪:当你希望副作用函数自动追踪其内部引用的所有响应式数据时。
import { ref, watchEffect } from 'vue'; export default { setup() { const count = ref(0); const name = ref('Vue'); watchEffect(() => { console.log(`Count is ${count.value}, Name is ${name.value}`); }); return { count, name }; } }
复制