Vue2的双向数据绑定原理:
Vue2的双向数据绑定主要是通过数据劫持和发布订阅模式实现的。
1.数据劫持:Vue2会用Object.defineProperty方法劫持每个属性的getter和setter,当数据发生变化时触发setter。
2.发布订阅模式:通过Dep(依赖)收集所有的Watcher(观察者),当数据变化后,通过Dep通知所有的Watcher,然后执行相应的视图更新函数。
如果模板中使用了这个数据,那么会被解析为一个Watcher,然后通过getter进行依赖收集,收集到Dep中。
这样,当数据发生变化时,就可以通过Dep通知到每个Watcher,然后更新视图。但是,由于Object.defineProperty的限制,Vue2无法检测到对象属性的添加或删除,以及数组的变化。
缺点:
Vue3的双向数据绑定原理:
Vue3则是通过Proxy和Reflect这两个ES6的新特性来实现的双向数据绑定。
1.数据劫持:Vue3通过Proxy创建一个代理对象,来劫持用户的数据。
2.依赖收集:当我们把这个数据绑定在视图上时,Vue3会通过getter函数进行依赖收集,把当前的数据添加到对应的观察者列表中。
3.派发更新:当数据发生变化时,Vue3会通过setter函数,通知对应的观察者,然后观察者会去更新视图。
相比于Vue2,Vue3的双向数据绑定机制能够更好的处理数组和对象的变化,并且性能更优。
vue2生命周期钩子:
beforeCreate:实例刚在内存中被创建出来,还未初始化属性
created:实例已经创建完成,属性已经绑定,但DOM还未生成
beforeMount:模板已经编译完成,但还未挂载到页面中
mounted:模板已经挂载到页面中,用户已经可以看到渲染结果
beforeUpdate:数据发生变化,视图还未更新
updated:数据已经更新,视图也同步更新
beforeDestroy:实例销毁之前调用
destroyed:实例销毁后调用
activated – 被 keep-alive 缓存的组件激活时调用。
deactivated – 被 keep-alive 缓存的组件停用时调用
mounted 表示页面已经渲染完了,created页面还没有进行渲染,但是vue实例初始化了
vue3生命周期钩子
beforeCreate 和 created 在 Vue3 中被替换为 setup this指向为undefined
onBeforeMount – 在挂载开始之前被调用:相关的 render 函数首次被调用。
onMounted – 组件挂载时调用
onBeforeUpdate – 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
onUpdated – 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
onBeforeUnmount – 在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。
onUnmounted – 卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。
onActivated – 被 keep-alive 缓存的组件激活时调用。
onDeactivated – 被 keep-alive 缓存的组件停用时调用
相同点:都可以控制dom元素的显示和隐藏
不同点:v-show只是改变display属性,dom元素并未消失,切换时不需要重新渲染页面,v-if直接将dom元素从页面删除,再次切换需要重新渲染页面
如果需要非常频繁地切换dom元素,v-show 更好,否则v-if 更好。
快速查找到节点,减少渲染次数,提升渲染性能
m->model(模型),v->view(视图),vm->viewModel(视图模型)。
当模型的数据发生变化时,视图模型会自动更新视图;当用户在视图中进行操作时,视图模型会自动更新模型的数据
缓存,data不变不会重新计算,提高性能
data选项被定义为函数而不是对象是为了确保每个Vue组件实例拥有独立的数据对象,避免数据共享问题,并方便访问组件实例的上下文。
使用异步组件:将页面划分为异步组件,根据需要按需加载,减少初始加载时间。
列表渲染优化:在使用v-for指令渲染列表时,使用key属性提供唯一标识符,以便Vue能够高效地更新和重用元素。
缓存计算属性:使用计算属性(computed)时,考虑使用缓存选项(cached: true)来缓存计算结果,避免不必要的重复计算。
合理使用v-if和v-show:根据情况选择合适的指令。v-if在条件为假时会销毁和重新创建元素,而v-show只是切换元素的显示和隐藏。如果需要频繁切换,使用v-show会更高效。
避免不必要的监听器:在使用watch监听数据变化时,确保只监听必要的数据,并避免监听大型、深层次的对象或数组。
利用v-once:对于静态内容,可以使用v-once指令使其只渲染一次,避免不必要的更新。
懒加载图片:对于大量图片或需要滚动加载的图片,可以使用懒加载技术,只在图片进入视口时再进行加载。
使用keep-alive:对于频繁切换的组件,使用keep-alive组件进行缓存,避免每次都销毁和重新创建组件。
使用合适的构建工具:在生产环境中,使用Webpack等构建工具进行代码压缩、代码分割和按需加载,以减小文件体积和提高加载速度。
// 绑定自定义事件
event.$on('xxx', this.add) //第二个参数为函数
// 调用自定义事件
event.$emit('xxx', this.title) //第二个参数传值
注意:event 为new Vue() 实例,绑定自定义事件第二个参数为函数的原因是因为在组件销毁的时候进行事件销毁,否则造成内存泄漏
// 销毁
event.$off('xxx', this.add)
创建以及渲染
father created -> son created -> son mounted -> father mounted
添加修改数据时,值传给子组件
father beforeUpdate -> son beforeUpdate -> son updated -> father updated
组件销毁时
father beforeDestroy -> son beforeDestroy -> son destroyed -> father destroyed
// 父组件
<MysonVmodel v-model="name" />
// 子组件
<template>
<input type="text" :value="text1" @input="$emit('change',$event.target.value)">
template>
model: {
prop: 'text1',
event: 'change'
},
props: {
text1: {
type: String,
default(){
return ''
}
}
},
vuex的基本使用
Composition API:更好的代码组织、更好的逻辑复用、更好的类型推导 (应对大型复杂的项目)
Options API:逻辑简单,小型项目可以使用
为何需要ref:
为何需要.vale:
为何需要toRef和toRefs:
createApp
emits属性
生命周期
多事件
移除.sync
异步组件的写法
移除filter
Teleport
Suspense
10.Composition API
开发环境使用ES6 Module,无需打包 非常快
生产环境使用rollup,并不会快很多