Vue3笔记
一、常用Composition API(常用组合式API)
1. man.js文件
// 引入一个工厂函数 createApp import { createApp } from 'vue' import App from './App.vue' // 创建应用实例对象 app --- 类似于vue2中的vm,但app比vm更'轻' const app = createApp(App) console.log('app', app) app.mount('#app')
2. setup函数
是vue3中一个新的配置,值是一个函数。组件中所用到的数据,方法等等,均要配置在setup中。setup有两种返回值,若返回对象,则对象中的属性,方法,在模板中均可以直接使用。若返回一个渲染函数,则可以自定义渲染内容。一般不推荐vue2和vue3混用,若data和setup混用,则data可以访问setup中的属性,方法,setup不能访问data中的内容,如果有重名,setup的值优先使用。setup不能用async修饰。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)。
3. ref函数
作用:定义响应式数据。
语法:const xxx = ref(initValue)
创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
js中操作数据:xxx.value;。
模板中读取数据:不需要.value, 直接 <div>{{xxx}}</div>
备注:
接收的数据可以是:基本类型、也可以是对象类型。
基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的。
对象类型的数据:内部使用了vue3.0中的一个新函数reactive函数。
3. reactive函数
作用:定义一个对象类型的响应数据(基本类型不要用它,要用ref函数)。
语法:const 代理对象 = reactive(源对象)接收一个对象或 数组,返回一个代理对象(Proxy的实例对象,简称proxy对象)。
reactive定义的响应式数据是“深层次的”。
内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作。
4. vue3.0 中的响应式原理
vue2.0响应式的实现原理:
对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)。
数组类型:通过 重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
存在问题:新增属性,删除属性,界面不会更新。直接通过下标修改数组,界面不会自动更新。
vue3.0响应式实现原理:
通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等。
通过Reflect(反射):对被代理对象的属性进行操作。
6. setup的两个注意点
setup执行的时机:在beforeCreate之前执行一次,this是undefined。
setup的参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
context:上下文对象。
attrs:值为对象,包含:组织外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs。
slots:收到的插槽内容,相当于this.$slots。
emit:分发自定义事件的函数,相当于this.$emit。
7. 计算属性与监听
computed函数(与vue2.0配置功能一致)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import {computed} from 'vue' export default { setup() { // 计算属性---简写(没有考虑计算属性被修改的情况) /*person.fullName = computed(() => { return person.firstName + '-' + person.lastName })*/ // 计算属性---完整写法,考虑读和写 person.fullName = computed({ get(){ return person.firstName + '-' + person.lastName }, set(val){ const nameArr = val.split( '-' ) person.firstName = nameArr[0] person.lastName = nameArr[1] } }) } } |
watch函数
监视reactive定义的响应式数据时:oldValue无法正确获取,强制开启了深度监视(deep无效)。
监视reactive定义的响应式数据中某个属性时:deep配置有效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // 情况一:监视ref所定义的一个响应式数据 watch(sum, (newVal, oldVal) => { console.log(`sum的值变化了${newVal}, ${oldVal}`) }, {immediate: true , deep: true }) // 情况二:监视ref所定义的多个响应式数据 watch([sum, msg], (newVal, oldVal) => { console.log(newVal); console.log(oldVal); console.log(`sum的值变化了${newVal}, ${oldVal}`) }, {immediate: true , deep: true }) // 情况三:监视reactive所定义的一个响应式数据 // 注意:无法正确获取oldValue // 注意:强制开启了深度监听(deep配置无法关闭) watch(person, (newVal, oldVal) => { console.log( 'person变化了' ,newVal, oldVal) }, {deep: false }) // 情况四:监视reactive所定义的一个响应式数据中的某个属性 watch(() => person.age, (newVal, oldVal) => { console.log( 'person的age变化了' ,newVal, oldVal) }) // 情况五:监视reactive所定义的一个响应式数据中的某些属性 watch([() => person.age, () => person.name], (newVal, oldVal) => { console.log( 'person的age或name变化了' ,newVal, oldVal) }) // 特殊情况 (监听对象中的某个属性对象,需要开启deep:true配置) watch(() => person.job, (newVal, oldVal) => { console.log( 'person的job变化了' ,newVal, oldVal) }, {deep: true }) |
watchEffect函数
watchEffect不用指定监视哪一个属性,监视的回调中用到哪个属性,就监视哪个属性。
8. 生命周期函数
配置形式的生命周期钩子。
组合式api形式的生命周期钩子,放在setup中执行。两种形式同时写的话,组合式api的形式执行早于配置式。
9. 自定义hook函数
把setup函数中使用的Composition API进行了封装。
类似vue2.x中的mixin。
自定义hook的优势:复用代码,让setup中的逻辑更清除易懂。
10. toRef
作用:创建一个ref对象,其value值指向另一个对象中的某个属性。
语法:const name = toRef(person,'name');。
应用:要将响应式对象中的某个属性单独提供给外部使用时。
扩展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法:toRefs(person);。
三、其他Composition API(其他组合式api,不常用,但需要了解)
1. shallowReactive与shallowRef
shallowReactive:只处理对象最外层属性的响应式(浅响应式)。
shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。
什么时候使用?
如果有一个对象数据,结构比较深,但变化时只是外层属性变化===>shallowReactive。
如果有一个对象数据,后续功能不会修改该对象中的属性,而是新的对象来替换===>shallowRef。
2. readonly与shallowReadonly
readonly:让一个响应式数据变为只读的(深只读),内层属性和外层属性都只读。
shallowReadonly:让一个响应式数据变为只读的(浅只读),外层属性只读,内层属性可以编辑。
应用场景:不希望数据被修改时。
3. toRaw与markRaw
toRaw:
作用:将一个由reactive生成的响应式对象转为普通对象。
使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
markRaw:
作用:标记一个对象,使其永远不会再成为响应式对象。
应用场景:
1. 有些值不应该被设置为响应式,例如复杂的第三方类库等。
2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
4. customRef
作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制。
5. provide与inject
作用:实现祖孙组件通信。
套路:父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据。
具体写法:
祖组件:provide('car', car);
后代组件:let car = inject('car');
6. 响应式数据的判断
isRef:检查一个值是否为一个ref对象。
isReactive:检查一个对象是否是由reactive创建的响应式代理。
isReadonly:检查一个对象是否由readonly创建的只读代理。
isProxy:检查一个对象是否由reacitve或者readonly方法创建的代理。
四、Composition API的优势
1. Options API 存在的问题
使用传统OptionsAPI中,新增或修改一个需求,就需要分别再data,methods,computed里修改。
2. Composition API的优势
我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。
五、新的组件
1. Fragment
在vue2中:组件中必须有一个根标签。
在vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中。
好处:减少标签层级,减小内存占用。
2. Teleport
Teleport是一种能够将我们的组件html结构移动到指定位置的技术。
3. Suspense
等待异步组件时渲染一些额外内容,让应用有更好的用户体验。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <Suspense> <template v-slot: default > <Child/> </template> <template v-slot:fallback> <h3>加载中...</h3> </template> </Suspense> import {defineAsyncComponent} from 'vue' // 异步引入组件 const Child = defineAsyncComponent(()=> import ( './components/Child' )) |
六、其他
1. 全局API的转移
vue2.x有许多全局API和配置。例如:注册全局组件、注册全局指令等。
vue3.x中对这些API做出了调整:将全局API,即Vue.xxx调整到应用实例(app)上。
2. 其他改变
data选项应该始终被声明为一个函数。
过渡类名的修改。
移除keyCode作为v-on的修饰符,同时也不再支持config.keyCodes。
移除v-on.native修饰符。
移除过滤器(filter)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构