对前端感兴趣的可以关注一下我的博客,会持续更新前端相关的知识和学习笔记,一起学习。
计算属性与监视
computed 函数
- 与 Vue2.x 中 computed 配置功能一致
- vue2 写法
computed:{
fullName(){
return this.person.firstName + '-' + person.lastName
}
}
-
vue3 写法
import { computed } from 'vue' setup(){ ... //计算属性——简写 let fullName = computed(()=>{ return person.firstName + '-' + person.lastName }) //计算属性——完整 let fullName = computed({ get(){ return person.firstName + '-' + person.lastName }, set(value){ const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } }) return { ..., // 计算属性也需要单独返回 fullName, } }
-
注意:vue3 的计算属性需要单独在 return 内返回。
watch 监视属性
-
与 Vue2.x 中 watch 配置功能一致
-
vue2 写法
watch: { // 简写 sum(newVal, oldVal) { console.log(newVal, oldVal); }, // 完整写法 sum: { immediate: true, // 立即执行一次 deep: true, // 深度监视 handler(newVal, oldVal) { console.log(newVal, oldVal); }, }, },
-
vue3 写法
setup(){ let sum = ref(0); let msg = ref("sss"); let person = reactive({ name: "ss", age: 20, a: { b: { c: 600, }, }, }); // 监视 ref 定义的一个响应式数据 watch(sum, (newVal, oldVal) => { console.log(newVal, oldVal); },{ immediate : true }); // 监视 ref 定义的多个响应式数据 watch([sum,msg], (newVal, oldVal) => { console.log(newVal, oldVal); }); } // 监视 reactive 定义的响应式数据 watch(person, (newVal, oldVal) => { console.log(newVal, oldVal); },{ deep:false }); // 此处 newVal 与 oldVal 一样 并且强制开启深度监视,即使设置了 deep:false 也无效
注意:vue3 中监视 reactive 响应式数据无法获取 oldVal,并且强制开启深度监视,单独配置不生效。
- 当你需要监视 reactive 内的某个或某些属性时,需要这么写:
// 单个属性
watch(
() => person.age,
(newVal, oldVal) => {
console.log(newVal, oldVal);
}
);
// 多个属性
watch([() => person.age, () => person.name], (newVal, oldVal) => {
console.log(newVal, oldVal);
});
);
- 特殊情况: 此处由于监视的是 reactive 定义的对象中的某个属性,所以 deep 配置有效,并且当这个属性嵌套多个对象时,必须开启深度监视才能监听到嵌套对象内的数据改变
// 特殊情况
let person = reactive({
name: "ss",
age: 20,
a: {
b: {
c: 600,
},
},
});
watch(
() => person.a,
(newVal, oldVal) => {
console.log(newVal, oldVal);
},
{ deep: true } // 改变 c 的值时必须开启深度监视
- 使用 ref 定义一个对象属性时,要监视到对象内的属性改变,有两种方法:
let person = ref({
name: "ss",
age: 20,
a: {
b: {
c: 600,
},
},
});
// 第一种 —— 开启深度监视
watch(
person,
(newVal, oldVal) => {
console.log(newVal, oldVal);
},
{ deep: true }
);
// 第二种 —— 使用 person.value
watch(person.value, (newVal, oldVal) => {
console.log(newVal, oldVal);
});
第二种方法,因为此时的 person 是 ref 定义的,是 RefImpl 对象,对象内有个 value 属性就是 person 对象内的属性。
watchEffect 函数
-
watch 的套路是:既要指明监视的属性,也要指明监视的回调。
-
watchEffect 的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
-
watchEffect 有点像 computed:
- 但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
- 而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。 watchEffect(() => { const x1 = sum.value; const x2 = person.age; console.log("watchEffect配置的回调执行了"); });
vue3 生命周期
-
Vue3.0 中可以继续使用 Vue2.x 中的生命周期钩子,但有有两个被更名:
beforeDestroy
改名为beforeUnmount
destroyed
改名为unmounted
-
Vue3.0 也提供了 Composition API 形式的生命周期钩子,与 Vue2.x 中钩子对应关系如下:
beforeCreate
===>setup()
created
=======>setup()
beforeMount
===>onBeforeMount
mounted
=======>onMounted
beforeUpdate
===>onBeforeUpdate
updated
=======>onUpdated
beforeUnmount
==>onBeforeUnmount
unmounted
=====>onUnmounted
-
Vue3 中使用同种钩子时,setup 内使用的钩子优先级高于通过配置项使用的钩子,执行快于配置项。
自定义 hook 函数
-
什么是 hook?—— 本质是一个函数,把 setup 函数中使用的 Composition API 进行了封装。
-
类似于 vue2.x 中的 mixin。
-
自定义 hook 的优势: 复用代码, 让 setup 中的逻辑更清楚易懂。
-
举个例子,如下图在 src 文件下创建了一个 hooks 函数,专门放置自定义的功能函数,在 usePoint 中是完成某种功能的函数的代码
在某个组件中使用这个功能函数时,只需要引入并且使用即可。
toRef
-
作用:创建一个 ref 对象,其 value 值指向另一个对象中的某个属性。
-
语法:
const name = toRef(person,'name')
-
应用: 要将响应式对象中的某个属性单独提供给外部使用时。
-
扩展:
toRefs
与toRef
功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)
其它 Composition API
shallowReactive 与 shallowRef
-
shallowReactive:只处理对象最外层属性的响应式(浅响应式)。
-
shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。
-
什么时候使用?
-
如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive。
-
如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===> shallowRef。
-
语法:
let person = shallowReactive({...})
let person = shallowRef({...})
-
readonly 与 shallowReadonly
-
readonly: 让一个响应式数据变为只读的(深只读)。
-
shallowReadonly:让一个响应式数据变为只读的(浅只读)。
-
应用场景: 不希望数据被修改时。
语法:
person = readonly(person)
person = shallowReadonly(person)
toRaw 与 markRaw
- toRaw:
- 作用:将一个由
reactive
生成的响应式对象转为普通对象。 - 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
- 作用:将一个由
- markRaw:
- 作用:标记一个对象,使其永远不会再成为响应式对象。
- 应用场景:
- 有些值不应被设置为响应式的,例如复杂的第三方类库等。
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。