vue3中有几个重要的点
- API的风格改变,vue2使用的是选项式API,v3使用的是组合式API
v2选项式API方式: 定义好了方法配置就可以 export default { // 接收参数 props: {}, // 注册组件 components: {}, // 数据 data() { return {}; }, // 计算属性 computed: {}, // 方法 methods: {}, // 监听器 watch: {}, created() {}, mounted() {}, }; v3选项式API方式 使用需要先 import导入 import { onBeforeMount, onMounted,computed } from 'vue' setup() { onBeforeMount(()=> { console.log('onBeforeMount'); }) onMounted(() => { console.log('onMounted') }) } - 生命周期的改变:
v2中使用: befaultCeate() create() befaultMount() mount() befaultUpdate() update() befaultDestroy() destroyed() v3中有几个改变 1前两个befalutCreate,create有setUp()代替, 2最后销毁的两个回调函数更加的语义化 setUp() onbefaultMount() onMounted() onbefaultUpdate() onUpdate() befauleonUnMount() onUnMount()
3.setup()
setUp()是V3中的一个新配置项,值为一个函数,setUp()是组合式API的一个基础,组件中所用到的:数据、方法等等,均要配置在setup中
注意点:v2选项式API可以访问到V3setup()中的数据和方法,但是v3setup()不能那个访问到v2选项式API中的配置,如有重名setUp()优先,在beforeCreate之前执行一次,this是undefined
【所以避免v2-v3混用】
4.ref函数:
定义一个响应式数据(定义基本类型)
语法:
const xxx = ref(initValue)
创建一个包含响应式数据的**引用对象(reference对象,简称ref对象)** 。
JS中操作数据:
xxx.value
模板中读取数据: 不需要.value,直接:
{{xxx}}
备注:
接收的数据可以是:基本类型、也可以是对象类型。
基本类型的数据:响应式依然是靠
Object.defineProperty()的
get与set完成的。
对象类型的数据:内部 *“ 求助 ”* 了Vue3.0中的一个新函数——
reactive函数。
-
reactive函数:定义响应式数据(对象/或数组)
语法: const 代理对象= reactive(源对象)接收一个对象(或数组)返回一个代理对象(Proxy的实例对象,简称proxy对象) reactive定义的响应式数据是“深层次的”。 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。 -
reactive对比ref
ref用来定义基本数据类型 reactive用来定义(对象、数组) 备注:ref也可以定义对象、数组,内部会自动通过reactive来转为(代理对象) ref是用过Object.defineProperty()的get与set来实现响应式(数据劫持。 reactive通过使用Proxy实现响应式(数据劫持),并通过Reflect操作源对象内不数据 ref定义的数据,操作时需要使用.value 模版中不需要.value reactive定义的数据,均不需要.value -
计算属性与监视
Computed()计算属性计算属性computed函数与v2中配置功能一致 需要先导入 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] } }) }watch()函数
两个小“坑”: 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。 监视reactive定义的响应式数据中某个属性时:deep配置有效。 import {watch} from 'vue' //情况一:监视ref定义的响应式数据 watch(sum,(newValue,oldValue)=>{ console.log('sum变化了',newValue,oldValue) },{immediate:true}) //情况二:监视多个ref定义的响应式数据 watch([sum,msg],(newValue,oldValue)=>{ console.log('sum或msg变化了',newValue,oldValue) })watchEffect函数
watch的套路是:既要指明监视的属性,也要指明监视的回调。 watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。 watchEffect有点像computed: 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。 //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。 watchEffect(()=>{ const x1 = sum.value const x2 = person.age console.log('watchEffect配置的回调执行了') }) -
自定义hook函数
自定义hook函数是重点 在使用v2选项式API时如果代码比较多就会有一种情况需要上下拉取来查找或者更改代码,数据方法太分散, v3中选项式API就提出吧相关的数据方法全部写在一块,这就需要借助hook函数, 可以在文件中为功能自定义hook在页面中引用,就这就把该功能的数据方法全部放在一块,页面也比较简洁 -
Vue3.0中的响应式原理
实现原理: 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。 通过Reflect(反射): 对源对象的属性进行操作。 -
toRef() 可以在组件中使用单独的 ref 来追踪某个响应式对象的特定属性,而不需要将整个对象都转换为 ref。
import { reactive, toRef } from 'vue'; const state = reactive({ name: 'John', age: 25, }); const ageRef = toRef(state, 'age'); console.log(ageRef.value); // 输出: 25 state.age = 30; console.log(ageRef.value); // 输出: 30 ageRef.value = 35; console.log(state.age); // 输出: 35 在上面的例子中,我们首先创建了一个响应式对象 `state`,其中包含 `name` 和 `age` 两个属性。 然后,我们使用 `toRef` 函数将 `state` 对象的 `age` 属性转换成了一个 ref,赋值给了 `ageRef` 变量。 通过访问 `ageRef.value`,我们可以获取到 `age` 的当前值。 当修改 `state` 对象的 `age` 属性时,`ageRef.value` 也会相应地更新。 同时,我们也可以直接通过 `ageRef.value` 修改 `state` 对象的 `age` 属性的值. -
其它 Composition API
1.shallowReactive 与 shallowRef shallowReactive:只处理对象最外层属性的响应式(浅响应式)。 shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。 什么时候使用? 如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive。 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===> shallowRef。 -
readonly 与 shallowReadonly
readonly: 让一个响应式数据变为只读的(深只读)。 shallowReadonly:让一个响应式数据变为只读的(浅只读)。 应用场景: 不希望数据被修改时。 -
3.toRaw 与 markRaw
toRaw作用:将一个由 reactive生成的响应式对象转为普通对象。 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。 markRaw: 作用:标记一个对象,使其永远不会再成为响应式对象。 应用场景: 有些值不应被设置为响应式的,例如复杂的第三方类库等。 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。 -
新的组件
1.Fragment vue2中必须有根标签 vue3中可以没有根标签,内部多个标签会被包裹到Fragment虚拟元素中,框架已实现不必自己实现 这样可以减少打体积,页面跟简洁 3.Teleport 可是实现在任意位置展示 <teleport to="移动位置"> <div v-if="isShow" class="mask"> <div class="dialog"> <h3>我是一个弹窗</h3> <button @click="isShow = false">关闭弹窗</button> </div> </div> </teleport> 5.Suspense 等待异步组件时渲染一些额外内容,让应用有更好的用户体验 使用步骤: 异步引入组件import {defineAsyncComponent} from 'vue' const Child =defineAsyncComponent(()=>import('./components/Child.vue')) 使用Suspense包裹组件,并配置好default 与fallback <template> <div class="app"> <h3>我是App组件</h3> <Suspense> <template v-slot:default> <Child/> </template> <template v-slot:fallback> <h3>加载中.....</h3> </template> </Suspense> </div> </template>