双向绑定更新
vue2 的双向数据绑定是利⽤ES5 的⼀个 API ,Object.defineProperty()对数据进⾏劫持 结合 发布订阅模式的⽅式来实现的。
vue3 中使⽤了 ES6 的 ProxyAPI 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从⽽ 实现对数据的监控。
这⾥是相⽐于vue2版本,使⽤proxy的优势如下
1.defineProperty只能监听某个属性,不能对全对象监听 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
2.可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。
获取props
vue2在script代码块可以直接获取props,vue3通过setup指令传递
API不同
Vue2使⽤的是选项类型API(Options API),Vue3使⽤的是合成型API(Composition API)
建立数据data
vue2是把数据放入data中,vue3就需要使用一个新的setup()方法,此方法在组件初始化构造得时候触发。
生命周期不同
vue2 -------- vue3
beforeCreate -> setup() 开始创建组件之前,创建的是data和method
created -> setup()
beforeMount -> onBeforeMount 组件挂载到节点上之前执行的函数。
mounted -> onMounted 组件挂载完成后执行的函数
beforeUpdate -> onBeforeUpdate 组件更新之前执行的函数。
updated -> onUpdated 组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount 组件挂载到节点上之前执行的函数。
destroyed -> onUnmounted 组件卸载之前执行的函数。dszhuoyi
activated -> onActivated 组件卸载完成后执行的函数
deactivated -> onDeactivated
关于v-if和v-for的优先级:
vue2 在一个元素上同时使用 v-if 和 v-for v-for会优先执行
vue3 v-if 总会优先于 v-for生效
vue2和vue3的diff算法
vue2
vue3
对于Computed:它支持缓存,只有依赖的数据发生了变化,才会重新计算
不支持异步,当Computed中有异步操作时,无法监听数据的变化
computed的值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data声明过,或者父组件传递过来的props中的数据进行计算的。
如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,一般会使用computed
如果computed属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法。
对于Watch:它不支持缓存,数据变化时,它就会触发相应的操作
支持异步监听
监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
当一个属性发生变化时,就需要执行相应的操作监听数据必须是data中声明的或者父组件传递过来的props中的数据,当发生变化时,会触发其他操作,函数
有两个的参数:immediate:组件加载立即触发回调函数 deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化。
当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用watch。
单页面(Sing Page Application——SPA):顾名思义,只有一个页面。一般是一个主页和多个路由页面组成。
多页面(Multi Page Application——MPA):有多个HTML页面,跳转的时候是从一个html页面跳到另一个页面。
scoped 属性是 style 标签上的一个特殊属性(布尔值)。表示当前style 里的样式只属于当前模块。(作用域、私有化的思想)保证css的作用域不会变成全局 而被其它模块的css污染。
在vue中引入了scoped这个概念,scoped的设计思想就是让当前组件的样式不会修改到其它地方的样式,使用了data-v-hash的方式来使css有了它对应模块的标识,这样写css的时候不需要加太多额外的选择器,方便很多。
Vue.js 是采用数据劫持结合发布者-订阅者模式
的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几个步骤:
需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: ①在自身实例化时往属性订阅器(dep)里面添加自己 ②自身必须有一个update()方法 ③待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
Vue2和Vue3的语法不可以混用,因为Vue3在设计时进行了大幅度的改进,包括底层架构的变化以及语法上的更新,所以Vue3的语法与Vue2不完全兼容。
例如,Vue3中使用的Composition API是一种新的API风格,它与Vue2中的Options API有很大的不同,这就导致了在Vue2中使用Composition API会报错。同样地,Vue3中的模板指令和组件注册方式也与Vue2不同,这也导致了两个版本之间无法直接混用。
主要的区别有以下几点:
1.模板编译方式:Vue 2使用基于字符串的模板编译,而Vue 3则采用了基于函数的模板编译方式。
2.响应式系统:Vue 3中通过Proxy实现了更加高效的响应式系统,与Vue 2中的Object.defineProperty有很大不同。
3.组件注册方式:Vue 3中使用了新的API来注册组件,如createApp
和defineComponent
,而Vue 2中则是通过Vue.component
等全局API来注册组件。
Props
方式是Vue中最常见的一种父传子的一种方式,我们将数据以及对数据的操作定义在父组件,子组件仅做列表的一个渲染,子组件只需要对父组件传递的值进行渲染即可
emit
方式也是Vue中最常见的组件通信方式,该方式用于子传父,在子组件中点击【添加】按钮后,emit一个自定义事件,并将添加的值作为参数传递。在父组件中只需要监听子组件自定义的事件,然后执行对应的添加操作
provide和inject
是Vue中提供的一对API,该API可以实现父组件向子组件传递数据,无论层级有多深,都可以通过这对API实现。
Vuex
和 Pinia
是 Vue 3 中的状态管理工具,使用这两个工具可以轻松实现组件通信。
Refs
有时候想访问 r e f s 绑 定 的 组 件 的 属 性 或 者 方 法 , 我 们 会 使 用 refs绑定的组件的属性或者方法,我们会使用 refs绑定的组件的属性或者方法,我们会使用refs。但是Vue3不同于Vue2,在 Vue3的setup中我们是无法访问到this的,所以我们需要借助一个方法,那就是getCurrentInstance,该方法返回了当前的实例对象。
Vue.js 中的 v-if 和 v-show 都是用来控制元素显示和隐藏的指令,但它们有以下不同:
编译方式不同:v-if 是“条件渲染”,它会根据表达式的真假值来销毁或重建元素及其子组件;而 v-show 则是“条件展示”,它会通过修改元素的 CSS 样式来控制元素的显示或隐藏。
初始渲染开销不同:v-if 在初始渲染时,如果表达式为假,则不会渲染相应的元素及其子组件,从而可以减少页面的初始加载时间;而 v-show 在初始渲染时,会始终将元素渲染出来,并通过 CSS 样式来控制是否显示。
频繁切换开销不同:由于 v-if 是销毁和重建元素,因此在频繁切换时,可能会有较大的性能开销;而 v-show 只是通过修改 CSS 样式来控制元素的显示和隐藏,因此在频繁切换时性能开销较小。
总之,当需要频繁切换元素的显示状态时,建议使用 v-show;当元素的显示状态在初始化后就很少改变时,建议使用 v-if
Vuex 是 Vue.js 官方提供的状态管理库,它主要用于应对在大型单页应用程序中管理共享状态(例如用户登录状态、购物车内容等)时遇到的问题。Vuex 遵循了 Flux 和 Redux 的设计思想,将应用程序的共享状态存储在一个全局的 store 中,并通过一个可预测的方式进行修改和访问。
Vuex 包含以下几个核心概念:
State:存储应用程序的共享状态。
Mutations:用于修改 state 中的数据。
Actions:用于处理异步操作或批量的 mutations。
Getters:用于根据 state 计算派生出的状态值。
除此之外,Vuex 还提供了一些辅助函数如 mapState、mapMutations、mapActions 和 mapGetters 等,使得在组件中使用 Vuex 变得更加简单和便捷。
总之,Vuex 提供了一种数据流管理的思路和机制,可以帮助我们更好地组织和管理应用程序的共享状态,从而使得应用程序更加易于维护和扩展。
Proxy 是 JavaScript 中的一个高级特性,它可以用来代理对对象或函数的访问,从而可以在访问某个对象或函数时注入一些额外的行为或逻辑。其原理如下:
当我们使用 Proxy 对象来代理另一个对象(称为目标对象)时,所有对目标对象的操作都会被转发到 Proxy 对象上进行处理。在 Proxy 对象上,我们可以通过定义一些附加的方法(称为“捕获器”),来拦截并处理这些操作。例如,我们可以定义一个 get 捕获器,在代理对象读取目标对象中不存在的属性时,返回一个默认值而不是抛出异常;还可以定义一个 set 捕获器,在代理对象修改目标对象的属性时,执行一些额外的逻辑。
使用 Proxy 可以灵活地控制和影响对象的访问和行为,并且与 Object.defineProperty 相比,Proxy 的功能更加强大、灵活和易于扩展。但需要注意的是,由于 Proxy 是一个相对较新的特性,低版本的浏览器可能不支持,因此在使用 Proxy 时需要进行兼容性检查。
说说内存泄漏的理解?内存泄漏的情况有哪些?
内存泄漏指的是程序中已经不再需要的内存没有被及时释放,导致系统可用内存越来越少,最终可能导致系统崩溃或变得非常缓慢。
常见的内存泄漏情况有以下几种:
对象引用计数不正确:在某些编程语言中,对象的内存空间会被分配和释放,但如果引用计数没有正确地统计,就会导致无法释放掉不再需要的对象占用的内存。
循环引用:当两个或多个对象之间相互引用,而这些对象又没有被其他地方引用,就会导致它们之间形成一个循环引用,从而导致这些对象的内存无法被回收。
未及时清理定时器和事件监听器:如果定时器或事件监听器没有被及时清理,它们所占用的内存就会一直存在,从而导致内存泄漏。
大量数据的缓存:如果应用程序中缓存了大量的数据,而这些数据不再需要时没有被及时清除,就会导致内存泄漏。
浏览器标签页未关闭:在使用浏览器时,如果打开了大量的标签页而又没有关闭,就会导致浏览器占用的内存越来越多,最终导致系统变得非常缓慢。
针对以上情况,我们可以采取以下措施来避免内存泄漏:
显式地释放不再需要的内存空间;
避免出现循环引用;
及时清理定时器和事件监听器;
避免缓存大量的数据;
及时关闭不需要的浏览器标签页等。
HTTP(超文本传输协议)和 HTTPS(安全的超文本传输协议)都是用来在客户端和服务器之间传输数据的协议,它们的区别
主要体现在以下几个方面:
安全性:HTTP 传输的数据是明文的,容易被恶意用户截获、篡改或窃取,而 HTTPS 则通过 SSL/TLS 加密协议对数据进行加密,从而保证数据传输的安全性。
端口号:HTTP 默认使用80端口,HTTPS 默认使用443端口。
证书认证:HTTPS 的服务端需要具备数字证书,通过第三方机构进行认证,来确保通信双方的身份及数据的完整性。
HTTPS 的加密原理基于 SSL/TLS 协议,大致过程如下:
客户端向服务器发送请求连接,并提供自己支持的一种加密算法列表。服务器从中选出一种加密算法,并将其作为应答返回给客户端。
双方协商生成一个随机数,作为加密通信时的秘钥。
使用双方协商好的加密算法和秘钥,对数据进行加密和解密。
在握手过程中,服务器将自己的数字证书发送给客户端,客户端使用浏览器中保存的证书颁发机构公钥对服务器的数字证书进行验证,以确保服务器的身份和证书的有效性。
客户端使用服务器的公钥进行加密,将加密后的秘钥发送到服务器,从而实现通信双方的身份验证和数据加密。
总之,HTTPS 通过使用 SSL/TLS 协议对数据进行加密和认证,保证了数据传输的安全性和完整性,成为现代互联网中保障用户隐私安全的重要手段。
前缓存和协商缓存的区别
面试题总结3
面试大全
面试难忆总结
面试题总结4