vue3学习三
五 计算属性
定义
选项式
export default {
data(){
return {
num:1
}
},
computed:{
num1(){
this.num+=1
}
}
}
组合式
import {ref,computed} from 'vue'
let num=ref(0);
//仅读
let num1 = computed(()=>{
return num.value+=1
})
计算时依赖的变量数据发生变化,则计算属性值发生变化。
计算时依赖的变量数据没有发生变化,则使用缓存数据,不再重新计算。
方法计算的值没有缓存,即选项式中methods、组合式function中没有使用缓存,每次都会重新计算。
若根据大量数据计算出数据,推荐使用计算属性。
修改
和改变逻辑依赖变量导致计算结果不同,通过改计算属性结果修改其依赖的变量。
计算属性定义的对象为响应式对象,为ref形式的对象,但是其value属性为只读属性。
get函数读操作触发,set函数写操作出发。
//可读 可写
let num1 = computed({
//读属性
get(){
return num.value+=1
},
//写属性
set(value){
num.value = value
}
})
六 监视watch
官网:https://cn.vuejs.org/guide/essentials/watchers.html
watch监视数据的变化,与vue2中作用一致。
监视数据类型:
- ref定义的数据
- reactive定义的数据
- 函数返回值(getter函数)
- 包含上述内容的数组
监视ref定义基本类型数据
watch第一个参数为响应式对象,而不是其值。
watch监视ref定义的数据,使用stopWatch()取消监视。
import {ref,watch} from 'vue'
let num = ref(0)
function changenum(){
num.value+=1
}
let num_watch = watch(num,(newvalue,oldvalue)=>{
console.log(newvalue,oldvalue)
if(newvalue >= 2){
stopWatch()//取消监视
}
})
监视ref定义的对象类型数据
监视整个对象时,仅修改vlaue中属性,监视不会被触发,但是修改整个value属性监视会被触发。
开启深度监视,可以监视到value中属性。
watch中第三个对象参数,做为配置项:
- deep:true 深度监视,在 Vue 3.5+ 中,
deep
选项还可以是一个数字,表示最大遍历深度——即 Vue 应该遍历对象嵌套属性的级数 - immediate:true 立即监视,先执行监视
- once: true 一次性监听器,仅支持 3.4 及以上版本
import {ref,watch} from 'vue'
let item = ref({
title:"11",
sort:1
})
function changetitle(){
item.value.title+="~"
}
function changesort(value){
item.value.sort+="~"
}
function changeitem(){
item.value = {
title:"12",
sort:2
}
}
watch(item,(newvalue,oldvalue)=>{
console.log('watch1',newvalue,oldvalue)
})
watch(item,(newvalue,oldvalue)=>{
console.log('watch2',newvalue,oldvalue)
},{
deep:true//开启深度监视
}
)
newvalue和oldvalue指的是对象的引用地址,所以引用地址不变,即不定义为新对象数据,其都指向一个地址,所以俩值相同。
监视recative定义的对象类型数据
监视整个对象时,默认开启深度监视,修改对象中的属性,也会被监视。
这种深度监视不可关闭,即deep:false无效果。
import {reactive,watch} from 'vue'
let item=reactive({
title:"title",
sort:1
})
function changetitle(){
item.title+="~"
}
function changeitem(){
let new_item = {
title:"title1",
sort:2
}
Object.assign(item,new_item)
}
watch(item,(newvalue,oldvalue)=>{
console.log(newvalue,oldvalue)
},{deep:false})
不管修改整个对象或者单个属性,newvalue和oldvalue都相同,道理同上。
监视getter数据
监视的数据不是对象类型,使用getter。
getter即匿名方法中返回要监听的值,可用于监听对象中的某个属性。
import {ref,reactive,watch} from 'vue'
let item=reactive({
title:"title",
sort:1,
books:{
b1:"123",
b2:"qwe"
}
})
function changetitle(){
item.title+="~"
}
watch(()=>{return item.title},(newv,oldv)=>{
console.log(newv,oldv)
})
仅修改title时会触发监听。
newv为改后的值,oldv为改后的值。
因为监视的为单个数据,修改内容为原内容副本,数据前后地址会变,所以修改前后的值不同。
function changebooks(){
item.books = {b1:"test1",b2:"test2"}
}
function changebook1(){
item.books.b1+="~"
}
watch(item.books,(newv,oldv)=>{
console.log("watch2",newv,oldv)
})
watch(()=>item.books,(newv,oldv)=>{
console.log("watch3",newv,oldv)
})
watch(()=>item.books,(newv,oldv)=>{
console.log("watch4",newv,oldv)
},{deep:true})
若监听reactive对象中的嵌套的对象,建议也用函数式,否则修改对象地址之后监视不到。
像代码中changebook1会输出watch2、watch4,changebooks中整个对象修改会输出watch3。
所以监视reactive对象或ref对象中嵌套的对象,最好使用getter和深度监视。
监视多个数据
监视多个属性,传递数组。
非对对象属性使用getter,对象属性直接使用。
import {ref,reactive,watch} from 'vue'
let item=reactive({
title:"title",
sort:1,
books:{
b1:"123",
b2:"qwe"
}
})
function changetitle(){
item.title+="~"
}
function changesort(){
item.sort+=2
}
function changebook1(){
item.books.b1+="~"
}
watch([()=>item.title,()=>item.sort],(newv,newo)=>{
console.log("watch5")
console.log(newv,newo)
})
如代码所示,执行changetitle、changesort、changetest1监视都会被执行,但执行changebook1监视不会被执行。
返回的newv和newo都是数组,数组值和参数的位置相对应。