Vue相关

Vue特点

  • 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
  • 双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
  • 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
  • 数据驱动:通过特殊的语法将数据与页面元素绑定,无需手动操作dom,只要改变数据就能使dom同步更新
  • 遵循MVVM(Model–view–viewmodel)模型的框架
  • 代码简洁体积小,运行效率高,适合移动PC端开发;

详细说说MVVM

全称: Model-View-ViewModel

  • Model代表数据模型
  • View代表UI组件
  • ViewModel将Model和View关联起来

MVVM :数据绑定到viewModel层并自动将数据渲染到页面中,视图变化时通知viewModel层更新数据

MVC :Controller负责将model的数据用View显示出来

Vue是如何实现响应式数据的呢?(响应式数据原理)❗

  • 2.x版本通过Object.defineProperty 数据劫持和发布订阅模式实现

    • 当创建Vue实例时,Vue会遍历data选项的属性,通过 Object.defineProperty() 为属性添加getter/setter对数据的读取进行劫持,并在内部追踪相关依赖,在属性被访问和修改时通知变化
  • 3.x版本通过Proxy代理对象实现

为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

  • Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。

  • proxy可以劫持整个对象并返回一个新的对象。proxy不仅可以代理对象,还可以代理数组,还可以代理动态增加的属性

Vue的事件绑定原理

  • 原生事件绑定通过addEventListener绑定给真实元素
    • 原生 DOM 的绑定:Vue在创建真实DOM时会调用 createElm ,默认会调用 invokeCreateHooks 。会遍历当前平台下相对的属性处理代码,其中就有 updateDOMListeners 方法,内部会传入 add() 方法
  • 组件事件绑定是通过Vue自定义的$on方法实现的

v-model中的实现原理及如何自定义v-model

v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:

  1. v-bind绑定一个value属性;
  2. v-on指令给当前元素绑定input事件。

自定义:自己写 model 属性,里面放上 prop event

为什么Vue采用异步渲染呢?

Vue 是组件级更新,如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染,所以为了性能, Vue 会在本轮数据更新后,在异步更新视图。核心思想 nextTick

Vue渲染过程:

调用new watcher函数,监听数据变化;当数据变化时,Render函数执行生成VNode对象;调用patch()方法,对比新旧VNode对象;通过DOM diff算法添加、修改、删除真正的DOM元素。

虚拟 DOM 实现原理?

虚拟 DOM 的实现原理主要包括以下 3 部分:

  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;

  • diff 算法——比较两棵虚拟 DOM 树的差异;

  • pach 算法——将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

了解nextTick吗?

异步方法,异步渲染最后一步,与JS事件循环联系紧密。主要使用了宏任务微任务(setTimeoutpromise那些),定义了一个异步方法,多次调用nextTick会将方法存入队列,通过异步方法清空当前队列。

JS 执行是单线程的,它是基于事件循环的。事件循环大致分为以下几个步骤:

所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件,哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

Vue生命周期

Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载DOM-渲染、更新-渲染、卸载等一系列的过程,我们称这是 Vue 的生命周期。

在生命周期的不同阶段调用对应的钩子函数可以实现组件数据管理DOM渲染两大重要功能。

  • beforeCreate:创建前,此阶段为实例初始化之后,this指向创建的实例,此时的数据观察事件机制都未形成,不能获得DOM节点。data,computed,watch,methods 上的方法和数据均不能访问。
    可以在这加个loading事件。

  • created:创建后,此阶段为实例已经创建,完成数据(data、props、computed)的初始化导入依赖项。
    可访问 data computed watch methods 上的方法和数据。
    初始化完成时的事件写在这里,异步请求也适宜在这里调用(请求不宜过多,避免白屏时间太长)。
    可以在这里结束loading事件,还做一些初始化,实现函数自执行。
    未挂载DOM,若在此阶段进行DOM操作一定要放在Vue.nextTick()的回调函数中。

  • beforeMount:在挂载之前调用,相关 render 函数首次被调用
    beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。

  • mounted:挂载,完成创建vm.$el,和双向绑定
    完成挂载DOM和渲染,可在mounted钩子函数中对挂载的DOM进行操作。

    可在这发起后端请求,拿回数据,配合路由钩子做一些事情。

  • beforeUpdate:数据更新前,数据驱动DOM。
    在数据更新后虽然没有立即更新数据,但是DOM中的数据会改变,这是vue双向数据绑定的作用。

    可以在这个钩子中进一步的更改状态,不会触发重渲染。可在更新前访问现有的DOM,如手动移出添加的事件监听器。

  • updated:数据更新后,完成虚拟DOM的重新渲染和打补丁。
    组件DOM已完成更新,可执行依赖的DOM操作。
    注意:不要在此函数中操作数据(修改属性),会陷入死循环。

  • activated:在使用vue-router时有时需要使用<keep-alive></keep-alive>来缓存组件状态,这个时候created钩子就不会被重复调用了。
    如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。

  • deactivated:<keep-alive></keep-alive>组件被移除时使用。

  • beforeDestroy:销毁前,在实例销毁之前调用。实例仍然完全可用。
    我们可以在这时进行善后收尾工作,比如清除计时器。可做一些删除提示,如:您确定删除xx吗?

  • destroyed:在实例销毁之后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

v-if v-show 区别

  1. v-if是“真正”的条件渲染,在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  3. 使用v-show元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  4. v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
  5. 需要非常频繁地切换,则使用 v-show 较好
  6. 在运行时条件很少改变,则使用 v-if 较好

v-forv-if 为什么不能连用,如何解决?

v-for 会比 v-if 的优先级更高,所以导致每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降。

使用computed解决

注:Vue3中 v-if 的优先级更高

组件中的data为什么是一个函数?

避免组件中数据互相影响。组件是可复用的,data若为对象,则所有复用的组件都是引用同一个数据;data若为函数,每次函数都会创建一个新的数据,从而使每个组件数据相互独立

Vue组件通信

  • 父子组件通信

    • 父->子props,子->父 $on$emit

    • 获取父子组件实例 $parent$children

    • Ref 获取实例的方式调用组件的属性或者方法

    • Provideinject 官方不推荐使用,但是写组件库时很常用

  • 兄弟组件通信

    • Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue

    • Vuex

  • 跨级组件通信

    • Vuex

    • $attrs$listeners

    • Provideinject

插槽与作用域插槽的区别

  • 创建组件虚拟节点时,会将组件儿子的虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类 {a:[vnode],b[vnode]}

  • 渲染组件时会拿对应的 slot 属性的节点进行替换操作。(插槽的作用域为父组件)

  • 作用域插槽在解析的时候不会作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染。

  • 普通插槽渲染的作用域是父组件,作用域插槽的渲染作用域是当前子组件

vue-router 有哪几种导航钩子?

第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件

怎么定义 vue-router 的动态路由? 怎么获取传过来的值?

在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id。

vue-router的两种模式

  1. hash模式
    • 即地址栏 URL 中的 # 符号
    • 当#后面的hash发生变化,不会导致浏览器向服务器发出请求,浏览器不发出请求就不会刷新页面,会触发hasChange这个事件,通过监听hash值的变化来实现更新页面部分内容的操作
  2. history模式
    • 主要使用HTML5的pushState()和replaceState()这两个api来实现的
    • history.pushState(state, title[, url]):向当前浏览器会话的历史堆栈中添加一个状态(state)记录,不会造成 hashchange 事件调用,即使新的URL和之前的URL只是锚的数据不同
    • history.replaceState():把当前页面在浏览器历史中的记录修改
    • 浏览器地址栏会变成你传的地址,而页面并不会重新载入或跳转

vue-router实现路由懒加载( 动态加载路由 )

  1. vue异步组件技术 ==== 异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件。
  2. 路由懒加载(使用import)。
  3. webpack提供的require.ensure(),vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

actionmutation 的区别

  • mutation 是同步更新, $watch 严格模式下会报错
  • action 是异步操作,可以获取数据后调用 mutation 提交最终数据

在vuex中为什么要去区分action 和 mutation?

为了能用 devtools 追踪状态变化

什么是异步组件,什么是动态组件?

  • 动态组件就是 component 组件 ,是指不同组件之间进行动态切换。
  • 所谓的异步组件就是通过import或者require导入的vue组件。引入一些大的比如图表什么的会用到。在大型应用中,可能需要将应用分割为小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,vue运行以一个工厂函数的方式定义组件,这个工厂函数会异步解析组件。vue只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存供未来渲染。

为什么要使用异步组件?

  1. 节省打包出的结果,异步组件分开打包,采用jsonp的方式进行加载,有效解决文件过大的问题。
  2. 核心就是包组件定义变成一个函数,依赖 import() 语法,可以实现文件的分割加载

谈谈对keep-alive的了解

keep-alive 是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

keep-alive 可以实现组件的缓存,当组件切换时不会对当前组件进行卸载。

常用的2个属性 include/exclude ,2个生命周期 activated deactivated

vue2 和 vue3 的区别,做了哪些更改?

  1. vue2和vue3响应式原理发生了改变

  2. Vue3支持碎片(Fragments),就是说在组件可以拥有多个根节点。

  3. 数据和方法的定义

    • Vue2使⽤的是选项类型API(Options API)
    • Vue3使⽤的是组合式API(Composition API)
  4. 生命周期钩子

    vue2vue3说明
    beforeCreatesetup()组件创建之前
    createdsetup()组件创建完成
    beforeMountonBeforeMount组件挂载之前
    mountedonMounted组件挂载完成
    beforeUpdateonBeforeUpdate数据更新,虚拟DOM打补丁之前
    updatedonUpdated数据更新,虚拟DOM渲染完成
    beforeDestroyonBeforeUnmount组件销毁之前
    destroyedonUnmounted组件销毁后

    若组件被 <keep-alive> 包含,则多出下面两个钩子函数:

    • onActivated():被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行 。
    • onDeactivated():比如从 A组件,切换到 B 组件,A 组件消失时执行。
  5. 父子通信

Vue2 常见的缺陷:

  • 从开发维护的角度考虑:Vue2 使用 Flow.js 做类型校验,但是现在 Flow.js 已经停止维护;并且 Option API 在组织代码较多组件时不易维护。
  • 从社区的二次开发难度:Vue2 内部运行时直接执行浏览器 API,这会给 Vue2 的跨端带来问题。只能在 Vue 源码中进行相应的处理(例如 Vue2 中存在 Weex 的文件夹)
  • 从日常使用的角度:Vue2 的响应式并不是真正意义上的代理,而是基于 Object.defineProperty() 实现的。这个 API 是对某个属性进行拦截,因此有很多缺陷(例如无法监听删除数据)

Vue3 的新特性

  • Vue3 中使用 Proxy API 对数据进行代理(这个 API 是真正的代理,不过存在一些兼容性问题)
  • Vue3 使用最近流行的 monorepo 管理方式,把响应式、编译和运行时全部独立了(Vue2 内部所有模块都糅合在一起)
  • Vue3 全部模块使用 TypeScript 重构
  • Vue3 使用 Composition API(组合式 API)
  • Vue3 内置了 Fragment、Teleport、Suspense 三个新组件

vue3如何创建响应式数据?

  • 在 Vue2 中,我们只需要把数据放入 data 函数,Vue2 会遍历 data 中的所有属性,使用 Object.defineProperty 把每个 property 全部转为 getter/setter,getter 用来收集依赖,setter 用来执行 notify,发布更新事件。Vue2 对每个属性创建一个 Dep 对象,作为订阅发布模式的中间机构来收集依赖。Vue 追踪这些依赖,在其被访问和修改时通知变更。
  • Vue3 中引入了 ref,reactive 来创建响应式数据
    • ref 的作用就是将一个原始数据类型转换成一个响应式数据,原始数据类型共有 7 个,分别 是:String、Number、BigInt、Boolean、Symbol、Undefined、Null
    • 当 ref 作为渲染上下文 (从 setup() 中返回的对象) 上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加(如以上代码中在 template 中可以直接使用 title,在 setup 函数中使用 title.value 来修改其值)
    • reactive 的作用就是将一个对象转换成一个响应式对象
    • toRefs 的作用是将一个响应式对象转化为一个普通对象,把其中每一个属性转化为响应式数据
    • 为什么需要 toRefs ?
      reactive 转化的响应式对象在销毁或展开(如解构赋值)的时候,响应式特征就会消失。为了在展开的同时保持其属性的响应式特征,我们可以使用 toRefs 。

说说你对 SPA 单页面的理解,它的优缺点分别是什么?

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

  • 优点:
    用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
    基于上面一点,SPA 相对对服务器压力小;
    前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

  • 缺点:
    初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一> 加载,部分页面按需加载;
    前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所> 有的页面切换需要自己建立堆栈管理;
    SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

使用过 Vue SSR 吗?说说 SSR?

  • Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。

  • 即:SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。

谈谈你对webpack的理解?

是一个对资源进行模块化和打包的工具,处理每个模块的 import 和 export
追问:资源是指什么?
回答:Js,css,png图片等
追问:如果有个二进制文件,它是资源么?webpack怎么使它模块化?
回答:是。需要有一个对应的loader来处理(我是想到了vue-loader等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Komorebi゛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值