vite创建
npm init vite-app <project-name>
npm install
vue3改变
- 数据监听
- 将全局的API,即:Vue.xxx调整到应用实例(app)上
- 移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes
- 移除v-on.native修饰符
- 移除过滤器(filter)
Vue3的数据监听
- vue2因为使用Object.defineProperty实现,存在弊端(因为只能监听到get | set):
- 无法监听对象增加属性和改变原数组操作
- 需要使用Vue.set或者vue封装的数组方法实现
- vue3使用 proxy+Reflect 实现,
setup()
- 组件中的数据、各种内置方法、生命周期都写在里面
- 类似函数式组件的意思,学react
- setup中的返回值:
- 对象(常用):
- 对象中的属性、方法,在vue模板中可使用
- 渲染函数
- 对象(常用):
- setup执行时机在beforeCreate之前,this时undefined(类似react的函数式,babel开启严格模式)
- 参数:
- props:对象
- 前提:组件内部必须使用props声明(vue2)
- context:对象
- attrs:相当于vue2的
this.$attrs - slots:相当与vue2的
this.$slots - emit:相当于vue2的
this.$emit
- attrs:相当于vue2的
- props:对象
- 与vue2混用:
- 2可以访问3
- 3不能访问2
- 重名3优先
- 使用async无效(除非spensens)
ref()
ref依然可用,这个是函数
const data = ref(initData)
-
创建一个包含响应式数据的代理对象
-
initData为非对象时,使用Object.defineProperty监听,只有获取值需要调用
.value,模板中读取不用加
.value -
initData为对象时,内部会去调用reactive()
reactive()
const data = reactive(initObj)
-
创建一个包含响应式数据(只限于对象类型)的代理对象
-
使用proxy+Reflect实现数据监视
toRef与toRefs
const data=toref(obj,value)
const data=toref(obj)
- 创建一个ref对象,目的是获取到响应式的某个属性,并且还保持该属性为相应式的
- toRef是获取某个属性,toRefs是获取所有
computed
- 与Vue2.x中
computed配置功能一致
import {computed} from 'vue'
setup(){
...
//计算属性 —— 简写
let fullName = computed(()=>{
return ...
})
//计算属性 —— 完整
let fullName = computed({
get(){
},
set(value){
}
})
}
watch
- 与vue2基本一致,但也有一些区别
-
监视ref定义的数据
watch(sum,(newValue,oldValue)=>{}, {immediate:true}) -
监视多个ref定义的数据
watch([sum,msg],(newValue,oldValue)=>{}) -
监视reactive定义的数据
- 如果为对象,则无法获得 oldValue
- 强制开启了deep
watch(person,(newValue,oldValue)=>{}, {immediate:true,deep:false}) //此处的deep配置无效 -
监视 reactive 定义的数据的某个属性
- 如果该属性是对象,需要开启deep
watch(()=>person.job,(newValue,oldValue)=>{},{immediate:true,deep:true}) //需要开启deep -
监视多个reactive定义的数据中的某些属性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{}, {immediate:true,deep:true})
生命周期
beforeCreate=>setup()
created=>setup()
beforeMount =>onBeforeMount
mounted=>onMounted
beforeUpdate=>onBeforeUpdate
updated =>onUpdated
beforeUnmount =>onBeforeUnmount
unmounted =>onUnmounted

自定义Hook(mixin)
- 提出为函数
shallowReactive 与 shallowRef
shallowReactive:只处理对象第一层属性的响应式(浅响应式)。shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。- 什么时候使用?
- 如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===>
shallowReactive。 - 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===>
shallowRef。
- 如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===>
readonly 与 shallowReadonly
readonly: 让一个响应式数据变为只读的(深只读)。shallowReadonly:让一个响应式数据变为只读的(浅只读)。- 应用场景: 不希望数据被修改时。
toRaw 与 markRaw
raw:原始
toRaw- 作用:将一个由
reactive生成的响应式对象转为普通对象。 - 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
- 作用:将一个由
markRaw- 作用:标记一个对象,使其永远不会再成为响应式对象。
- 应用场景:
- 有些值不应被设置为响应式的,例如复杂的第三方类库等。
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
customRef
function myRef(value){
let timer;//防抖
return customRef((track,trigger)=>{
return{
get(){
track()//追踪
return value
},
set(newValue){
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger(); // 触发
}, 500);
}
}
})
}
祖孙通信 provide 与 inject
-
父组件有一个
provide选项来提供数据setup(){ ...... let car = reactive({name:'奔驰',price:'40万'}) provide('car',car) // 给自己的后代组件传递数据 ...... } -
后代组件有一个
inject选项来使用数据setup(props,context){ ...... const car = inject('car') // 拿到祖先的数据 return {car} ...... }
响应式数据的判断
isRef: 检查一个值是否为一个ref对象isReactive: 检查一个对象是否是由reactive创建的响应式代理isReadonly: 检查一个对象是否是由readonly创建的只读代理isProxy: 检查一个对象是否是由reactive或者readonly方法创建的代理
Fragment
- 在Vue2中: 组件必须有一个根标签
- 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个
Fragment虚拟元素中
Teleport
- 将组件html结构移动到指定位置
- 移动位置:css选择器
<teleport to="移动位置">
<div v-if="isShow" class="mask">
<div class="dialog">
<h3>我是一个弹窗</h3>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</teleport>
Suspense
-
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
-
异步引入组件
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
- 使用
Suspense包裹组件,并必须配置好default与fallback- 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>
本文深入探讨Vue3的全新特性,包括使用proxy替代Object.defineProperty进行数据监听,setup函数的使用方式及其参数说明,以及ref、reactive等API的介绍。此外,还介绍了生命周期的变化、自定义Hook的使用、Fragment、Teleport和Suspense等新API。

822

被折叠的 条评论
为什么被折叠?



