1

1,Vue组件的生命周期有哪些,它们的执行顺序是什么?

Vue组件的生命周期包括beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy和destroyed等。它们的执行顺序如下:beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed 

2,什么是计算属性,它和方法有什么区别

计算属性(computed)是Vue中的一个属性,它是一个函数,根据响应式的数据进行计算返回结果。计算属性可以多次使用,并且当计算属性所依赖的响应式数据改变时会重新计算,避免了不必要的计算。而方法(methods)则需要手动调用,无法自动触发并且不能被缓存,所以当方法所依赖的数据需要更新时需要手动调用。

3,VueRouter的路由模式有哪几种

VueRouter路由模式有三种:hash模式、history模式和abstract模式。hash模式使用URL的hash(#)来模拟一个完整的URL,当URL有变化时,页面不会重新加载,而是通过hashchange事件监听到URL的变化,然后通过hash来实现视图的更新;history模式使用HTML5的History API来进行URL跳转,通过pushState和replaceState方法可以动态改变浏览器的URL,而不需要刷新页面;abstract模式将路由进行抽象,不依赖于浏览器的URL,主要用于非浏览器环境下的应用。

4,什么是Vuex,它的作用是什么?

Vuex是Vue的状态管理库,它将组件的共享状态抽取出来,以一个全局单例模式进行管理,使得多个组件可以共享同一状态。Vuex包含了状态管理、状态获取、状态修改、同步数据和异步数据管理等功能,它的作用是方便了组件之间的数据交互,特别是在大型复杂应用中非常有用。

5,简单介绍下Vue的父子组件传值,以及传值方式有哪些

父子组件传值是指在Vue组件中,通过组件之间的数据传递方式,让父组件向子组件传递数据或者让子组件向父组件传递数据。Vue的父子组件传值方式有props、a t t r s 、attrs 、 listeners、v-bind和v-on等,其中props是最常用的一种方式,它可以向子组件传递数据并且可以设置数据类型、默认值和校验等。a t t r s 和 attrs和listeners则是用于解决父组件向子组件传递不符合规范的属性和监听事件。v-bind和v-on是Vue的两个指令,用于绑定属性和事件,可以实现父组件向子组件传递数据和接收子组件的事件。

6,Vue 框架中是否有 MVC 的思想

是的,Vue 框架本身就具有 MVVM 思想(将 Model、View、ViewModel 分离),并且通过数据绑定的方式实现了数据与视图的同步。

7,Vue 中的组件通信有哪些方式?

Vue 中的组件通信有父子组件通信、兄弟组件通信、跨越多级组件的祖孙组件通信、任意组件之间的通信,可以使用 props、、emit、refs、事件中心、Vuex 等方法进行实现。

8,nextTick方法有什么作用

nextTick 方法可以用于在 DOM 更新后对页面进行操作,在 Vue 生命周期中的 updated 阶段完毕后执行回调函数,确保数据已经更新的情况下再进行操作。

9,Vue 中的 v-model 指令有什么作用?

v-model 指令可以完成双向数据绑定,即实时将用户在输入框中输入的值绑定到 Vue 数据模型中,并且在 Vue 数据模型中的数据发生变化时,可以自动同步到输入框中。
 

10,Vue 中的 mixin 有什么作用?

mixin 可以通过复用已有的 Vue 实例对象中的选项,比如 data、methods、components 等,来增强 Vue 实例的功能。mixin 可以用于扩展多个组件之间的公共逻辑,降低代码的重复度
 

11,computed 和 watch 的区别和运用的场景?

  • computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
  • watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

 
运用场景:

当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;

当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态,这些都是计算属性无法做到的。

12,v-show 与 v-if 有什么区别?

v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。

所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。 

13,我们一般在哪个生命周期内调用异步请求

可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。但是本人推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:

  • 能更快获取到服务端数据,减少页面 loading 时间;
  • ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

14,Vue是如何实现双向数据绑定的

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

15,简单介绍下vuex五大核心,以及它们的作用

  • state:Vuex中的基本数据,辅助函数mapState。
  • getters:即从store的state中派生出的状态,有点类似计算属性,辅助函数mapGetters。
  • mutations:是更改Vuex中的store中的状态的唯一方法,是同步的,辅助函数mapMutations。
  • actions:Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作,辅助函数mapActions
  • Modules:Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutations、actions、getters、甚至是嵌套子模块——从上至下进行类似的分割。

16,使用过 Vue SSR 吗,说说 SSR的优缺点

SSR 也就是服务端渲染,也就是将 Vue 在客户端把标签渲染成 HTML 的工作放在服务端完成,然后再把 html 直接返回给客户端。

  • 优点:SSR 有着更好的 SEO、并且首屏加载速度更快
  • 缺点: 开发条件会受到限制,服务器端渲染只支持 beforeCreate 和 created 两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于 Node.js 的运行环境,需要服务器会有更大的负载需求。

17,Vue3.0与Vue2.0的区别

vue3.0和vue2.0最大的区别就是api从原来的options API 变成了 composition API + options API ,编写代码更灵活、复用率更高。体现在如下几点:

  • vue3.0比vue2.0快2倍,Tree-shaking 更友好
  • vue3.0支持TypeScript以及PWA
  • 数据双向绑定从Object.defineProperty变成了 new Proxy,不用再使用$set了
  • 其他方面的更改:支持自定义渲染器、支持 Fragment和 Protal组件等。

18,简单介绍下axios 网络请求库

Axios 是一个基于 promise 的 HTTP 网络请求库,可以用在浏览器和 node.js环境中执行网络请求,react/vue 官方都推荐使用 axios 发 ajax 请求,特点:

  • 基于 promise 的异步 ajax 请求库,支持promise所有的API
  • 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests
  • 支持请求/响应拦截器
  • 支持请求取消
  • 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
  • 批量发送多个请求
  • 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。

19,简单介绍下虚拟DOM,以及为什么要使用虚拟DOM

虚拟 DOM(Virtual DOM) 是使用 JavaScript 对象来描述 DOM,虚拟 DOM 的本质就是JavaScript 对象,使用 JavaScript 对象来描述 DOM 的结构。应用的各种状态变化首先作用于虚拟 DOM,最终映射到 DOM。

那为啥要创建虚拟DOM呢,有以下几点:

  • 创建真实DOM的代价高:真实的 DOM 节点 node 实现的属性很多,而 vnode 仅仅实现一些必要的属性,相比起来,创建一个 vnode 的成本比较低。
  • 触发多次浏览器重绘及回流:使用 vnode ,相当于加了一个缓冲,让一次数据变动所带来的所有 node 变化,先在 vnode 中进行修改,然后 diff 之后对所有产生差异的节点集中一次对 DOM tree 进行修改,以减少浏览器的重绘及回流。
  • 虚拟dom由于本质是一个js对象,因此天生具备跨平台的能力,可以实现在不同平台的准确显示。
  • Virtual DOM 在性能上的收益并不是最主要的,更重要的是它使得 Vue 具备了现代框架应有的高级特性。

20,slot 是什么,有什么作用

slot 又名插槽,是 Vue 的内容分发机制,组件内部的模板引擎使用 slot 元素作为承载分发内容的出口。插槽 slot 是子组件的一个模板 标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决 定的。slot 又分三类,默认插槽,具名插槽和作用域插槽。

  • 默认插槽:又名匿名插槽,当 slot 没有指定 name 属性值的时候一个 默认显示插槽,一个组件内只有有一个匿名插槽。
  • 具名插槽:带有具体名字的插槽,也就是带有 name 属性的 slot,一 个组件可以出现多个具名插槽。
  • 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也 可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可 以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过 来的数据决定如何渲染该插槽。

实现原理

当子组件 vm 实例化时,获取到父组件传入的 slot 标签的 内容,存放在 vm.$slot 中,默认插槽为 vm.$slot.default,具名插 槽为 vm.$http://slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇 到 slot 标签,使用$slot 中的内容进行替换,此时可以为插槽传递 数据,若存在数据,则可称该插槽为作用域插槽。

21,简单介绍下$nextTick的作用及其原理

Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的 一种应用。
nextTick 的 核 心 是 利 用 了 如 Promise 、 MutationObserver 、setImmediate、setTimeout 的原生 JavaScript 方法来模拟对应的 微/宏任务的实现,本质是为了利用 JavaScript 的这些异步回调任务队列来实现 Vue 框架中自己的异步回调队列。

nextTick 不仅是 Vue 内部的异步队列的调用方法,同时也允许开发 者在实际项目中使用这个方法来满足实际应用中对 DOM 更新数据时机的后续逻辑处理。

nextTick 是典型的将底层 JavaScript 执行原理应用到具体案例中的示例,引入异步更新队列机制的原因:如果是同步更新,则多次对一个或多个属性赋值,会频繁触发 UI/DOM 的渲染,可以减少一些无用渲染。

同时由于 VirtualDOM 的引入,每一次状态发生变化后,状态变化的 信号会发送给组件,组件内部使用 VirtualDOM 进行计算得出需要更 新的具体的 DOM 节点,然后对 DOM 进行更新操作,每次更新状态后 的渲染过程需要更多的计算,而这种无用功也将浪费更多的性能,所以异步渲染变得更加至关重要。

Vue 采用了数据驱动视图的思想,但是在一些情况下,仍然需要操作 DOM。有时候,可能遇到这样的情况,DOM1 的数据发生了变化,而 DOM2 需要从 DOM1 中获取数据,那这时就会发现 DOM2 的视图并没有更新,这时就需要用到了 nextTick 了。

由于 Vue 的 DOM 操作是异步的,所以,在上面的情况中,就要将 DOM2 获取数据的操作写在$nextTick 中。

所以,在以下情况下,会用到 nextTick:

  • 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变 化的 DOM 结构的时候,这个操作就需要方法在 nextTick()的回调函 数中。
  • 在 vue 生命周期中,如果在 created()钩子进行 DOM 操作,也一定要 放在 nextTick()的回调函数中。

因为在 created()钩子函数中,页面的 DOM 还未渲染,这时候也没办 法操作 DOM,所以,此时如果想要操作 DOM,必须将操作的代码放在 nextTick()的回调函数中。

22,Vue 单页应用与多页应用的区别

SPA 单页面应用(SinglePage Web Application),指只有一个主页 面的应用,一开始只需要加载一次 js、css 等相关资源。所有内容都 包含在主页面,对每一个功能模块组件化。单页应用跳转,就是切换 相关组件,仅仅刷新局部资源。

MPA 多页面应用 (MultiPage Application),指有多个独立页面的 应用,每个页面必须重复加载 js、css 等相关资源。多页应用跳转,需要整页资源刷新。

单页面的优缺点如下:

优点:

  • 用户体验好:由于页面内容动态加载,只需要局部刷新,用户切换页面时不需要重新加载整个页面,提升了用户体验。
  • 前后端分离:前端负责页面展示和交互逻辑,后端负责数据接口提供,可以更好地实现前后端分离开发。
  • 更好的性能:SPA可以通过合理的使用缓存和懒加载等技术来提升性能,减少不必要的请求和加载。
  • 开发效率高:使用前端框架可以提高开发效率,组件化开发方式方便代码复用和维护。

缺点:

  • SEO不友好:由于SPA只有一个HTML文件,搜索引擎难以获取到完整的页面内容,对于SEO有一定的不利影响。
  • 首屏加载慢:由于SPA需要加载整个应用的JavaScript和CSS文件,首次加载时可能会比较慢。
  • 浏览器兼容性问题:SPA使用了大量的前端技术,对浏览器的兼容性要求较高。

多页面应用优缺点
优点:

  • SEO友好:每个页面都有独立的URL,搜索引擎可以直接抓取到每个页面的内容,对于SEO更友好。
  • 浏览器兼容性好:MPA使用传统的后端技术,对浏览器的兼容性要求较低。
  • 首屏加载快:每个页面只加载当前页面所需的资源,首次加载速度较快。

缺点:

  • 用户体验差:每次页面切换都需要重新加载整个页面,用户体验较差。
  • 开发效率低:每个页面都需要独立开发和维护,代码复用和维护成本较高。

23,Vue data 中某一个属性的值发生改变后,视图会立即执行重新渲染吗

不会立即同步执行重新渲染。Vue 实现响应式并不是数据发生变化之 后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化, Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。

如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在 缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要 的。然后,在下一个的事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。

24,简单介绍下Vue 模版的编译原理

vue 中的模板 template 无法被浏览器解析并渲染,因为这不属于浏 览器的标准,不是正确的 HTML 语法,所有需要将 template 转化成一 个 JavaScript 函数,这样浏览器就可以执行这一个函数并渲染出对 应的 HTML 元素,就可以让视图跑起来了,这一个转化的过程,就成 为模板编译。模板编译又分三个阶段,解析 parse,优化 optimize,生成 generate,最终生成可执行函数 render。

  • 解析阶段:使用大量的正则表达式对 template 字符串进行解析,将 标签、指令、属性等转化为抽象语法树 AST。
  • 优化阶段:遍历 AST,找到其中的一些静态节点并进行标记,方便在 页面重渲染的时候进行 diff 比较时,直接跳过这一些静态节点,优 化 runtime 的性能。
  • 生成阶段:将最终的 AST 转化为 render 函数字符串。

25,谈谈你对 Vue 组件化的理解

组件是独立和可复用的代码组织单元。组件系统是 Vue 核心特性之 一,它使开发者使用小型、独立和通常可复用的组件构建大型应用;

  • 组件化开发能大幅提高应用开发效率、测试性、复用性等;
  • 组件使用按分类有:页面组件、业务组件、通用组件;
  • vue 的组件是基于配置的,我们通常编写的组件是组件配置而非组 件,框架后续会生成其构造函数,它们基于 VueComponent,扩展于 Vue;
  • vue 中常见组件化技术有:属性 prop,自定义事件,插槽等,它们 主要用于组件通信、扩展等;6.合理的划分组件,有助于提升应用性 能;
  • 组件应该是高内聚、低耦合的;
  • 遵循单向数据流的原则。

26,介绍下Vue的生命周期

Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是 Vue 的⽣命周期。

  • beforeCreate(创建前):数据观测和初始化事件还未开始,此时 data 的响应式追踪、event/watcher 都还没有被设置,也就是说不 能访问到 data、computed、watch、methods 上的方法和数据。
  • created(创建后) :实例创建完成,实例上配置的 options 包 括 data、computed、watch、methods 等都配置完成,但是此时渲染 得节点还未挂载到 DOM,所以不能访问到 $el 属性。
  • beforeMount(挂载前):在挂载开始之前被调用,相关的 render 函数首次被调用。实例已完成以下的配置:编译模板,把 data 里面 的数据和模板生成 html。此时还没有挂载 html 到页面上。
  • mounted(挂载后):在 el 被新创建的 vm.$el 替换,并挂载到实 例上去之后调用。实例已完成以下的配置:用上面编译好的 html 内 容替换 el 属性指向的 DOM 对象。完成模板中的 html 渲染到 html 页 面中。此过程中进行 ajax 交互。
  • beforeUpdate(更新前):响应式数据更新时调用,此时虽然响应 式数据更新了,但是对应的真实 DOM 还没有被渲染。
  • updated(更新后) :在由于数据更改导致的虚拟 DOM 重新渲染和 打补丁之后调用。此时 DOM 已经根据响应式数据的变化更新了。调 用时,组件 DOM 已经更新,所以可以执行依赖于 DOM 的操作。然而 在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更 新无限循环。该钩子在服务器端渲染期间不被调用。
  • beforeDestroy(销毁前):实例销毁之前调用。这一步,实例仍 然完全可用,this 仍能获取到实例。
  • destroyed(销毁后):实例销毁后调用,调用后,Vue 实例指示 的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例 也会被销毁。该钩子在服务端渲染期间不被调用。

另外还有 keep-alive 独有的生命周期,分别为 activated 和deactivated。用 keep-alive 包裹的组件在切换时不会进行销毁,而 是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执 行 activated 钩子函数。

27,Vuex 和 localStorage 的区别

  • 主要区别: vuex 存储在内存中,localstorage 则以文件的方式存储在本地,只能存储字符串类型的 数据,存储对象需要 JSON 的 stringify 和 parse 方法进行处理。 读取内存比读取硬盘速度要快。
  • 应用场景:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一 种可预测的方式发生变化。vuex 用于组件之间的传值。localstorage 是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用 。Vuex 能做到数据的响应式,localstorage 不能。
  • 数据时效性:刷新页面时 vuex 存储的值会丢失,localstorage 不会。

28,介绍下Vue3.0 的更新

相比于2.x,3.0版本带来了如下一些变化:

1,监测机制的改变

3.0 将带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪,消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制:

2,只能监测属性,不能监测对象

检测属性的添加和删除;检测数组索引和长度的变更;支持 Map、Set、WeakMap 和 WeakSet。

3,模板

作用域插槽,2.x 的机制导致作用域插槽变了,父组件会重新渲染,而 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。同时,对于 render 函数的方面,vue3.0 也会进行一系列更改来方 便习惯直接使用 api 来生成 vdom 。

4,对象式的组件声明方式

vue2.x 中的组件是通过声明的方式传入一系列option的, 和TypeScript的结合需要通过一些装饰器的方式来做,虽然能实现功 能,但是比较麻烦。3.0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易。

5,其它方面的更改

-支持自定义渲染器,从而使得 weex 可以通过自定义渲染器的方式来 扩展,而不是直接 fork 源码来改的方式。
支持 Fragment(多个根节点)和 Protal(在 dom 其他部分渲染组 建内容)组件,针对一些特殊的场景做了处理。
基于 tree shaking 优化,提供了更多的内置功能。

29,Vue3.0 为什么要用 proxy

在 Vue2 中, 0bject.defineProperty 会改变原始数据,而 Proxy 是创建对象的虚拟表示,并提供 set 、get 和 deleteProperty 等 处理器,这些处理器可在访问或修改原始对象上的属性时进行拦截,Proxy有以下特点∶

  • 不需用使用 Vue.$set 或 Vue.$delete 触发响应式。
  • 全方位的数组变化检测,消除了 Vue2 无效的边界情况。
  • 支持 Map,Set,WeakMap 和 WeakSet。
  • Proxy 实现的响应式原理与 Vue2 的实现原理相同,实现方式大同小异∶
  • get 收集依赖
  • Set、delete 等触发依赖
  • 对于集合类型,就是对集合对象的方法做一层包装:原方法执行后执 行依赖相关的收集或触发逻辑。

30,Vue 中 key 有什么作用

Vue 中 key 的作用可以分为两种情况来考虑:

  • 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元 素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来 实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个 元素就会被复用。如果是相同的 input 元素,那么切换前后用户的 输入不会被清除掉,这样是不符合需求的。因此可以通过使用 key 来 唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识一个独立的元素。
  • 第二种情况是 v-for 中使用 key。用 v-for 更新已渲染过的元素列 表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改 变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此 处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为 了高效的更新渲染虚拟 DOM。

key 是为 Vue 中 vnode 的唯一标记,通过这个 key,diff操作可以更准确、更快速。

31,简单介绍下双向数据绑定的原理

Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几 个步骤:

  1. 需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter 这样的话,给这个对象的某个值赋值,就会 触发 setter,那么就能监听到了数据变化
  2. compile 解析模板指令,将模板中的变量替换成数据,然后初始化 渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数 据的订阅者,一旦数据有变动,收到通知,更新视图
  3. Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做 的事情是: ①在自身实例化时往属性订阅器(dep)里面添加自己 ② 自身必须有一个 update()方法 ③待属性变动 dep.notice()通知时,能调用自身的 update()方法,并触发 Compile 中绑定的回调,则成功 成身退。
  4. MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input)-> 数据 model 变更的双向绑定效果。

image.png

32,路由的 hash 和 history 模式有什么区别

Vue-Router 有两种模式:hash 模式和 history 模式。默认的路由模 式是 hash 模式。

hash 模式

hash 模式是Vue开发中默认的模式,它的 URL 带着一个#,例如:,它的 hash 值就是#/vue。hash 值会出现在 URL 里面,但是不会出现在 HTTP 请求中,对后端完全没有影响。所以改变 hash 值,不会重新加载页面。这种模 式的浏览器支持度很好,低版本的 IE 浏览器也支持这种模式。hash 路由被称为是前端路由,已经成为 SPA(单页面应用)的标配。

history 模式

history 模式的 URL 中没有#,它使用的是传统的路由分发模 式,即用户在输入一个 URL 时,服务器会接收这个请求,并解析这个 URL,然后做出相应的逻辑处理。当 使 用 history 模 式 时 , URL 就 像 这 样 :。相比 hash 模式更加好看。但是,history 模式需要后台配置支持。如果后台没有正确配置,访问时会返回 404。

两种模式对比

调用 history.pushState() 相比于直接修改 hash,存在以下优势:

  • pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL;
  • pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把 记录添加到栈中;而 hash 设置的新值必须与原来不一样才会触发动 作将记录添加到栈中;
  • pushState() 通过 stateObject 参数可以添加任意类型的数据到记 录中;而 hash 只可添加短字符串;
  • pushState() 可额外设置 title 属性供后续使用。
  • hash 模式下,仅 hash 符号之前的 url 会被包含在请求中,后端如果 没有做到对路由的全覆盖,也不会返回 404 错误;history 模式下,前端的 url 必须和实际向后端发起请求的 url 一致,如果没有对用的 路由处理,将返回 404 错误。

xiangzhihong
5.9k 声望15.3k 粉丝

著有《React Native移动开发实战》1,2,3、《Kotlin入门与实战》《Weex跨平台开发实战》、《Flutter跨平台开发与实战》1,2和《Android应用开发实战》