vue常见面试问题

一.vue中MVVM的理解?

MVVM是Model-view-ViewModel的简写 ​ M--- model 模型==数据==变量 data数据 ​ v--- view 视图`==页面==用户可以看见的界面 模板 ​ vm---viewModel 视图模型==用来关联数据与视图之间的桥梁 vue实例

通过vue类创建的对象叫做实例化对象,这个对象就是MVVM模式中VM层,模型通过它可以将数据绑定在页面上,视图可以通过它将数据映射到模型上。
​
优点:1.低耦合:视图可以独立于Model变化和修改
      2.可重用性:把一些视图逻辑放在一个视图模型中,让很多视图重用这段视图逻辑
      3.前后端分离:开发人员专注于业务逻辑(ViewModel)和数据开发,设计人员专注于页面设计

mvc

封装与业务无关的重复代码,形成框架,是模型model)--视图(view)--控制器(controller)的缩写

模型:数据的储存和处理,在传递给视图层相应或者展示

视图:前端的数据展示

控制器:对数据的接收和触发事件的接收和传递

MVC思想:一种将数据层与视图层进行分离的设计思想

MVVM思想;一个重要特性,双向绑定,数据修改,vm监测到变化,通知V层进行修改,反之相同;MVC和MVVM都是一种设计思想,

MVC中的控制器变成了MVVM中的视图模型VM,

MVVM主要解决了MVC中大量的Dom操作使页面渲染性能降低,加载速度变慢,影响用户体验。

二.为什说vue是一个渐进式的javascript框架,渐进式是什么意思?、

vue允许将一个网页分割成可复用的组件,每个组件都包含自己的HTML。CSS、javascript可以用来渲染网页中相应的地方。对于vue的使用可大可小,它都会有相应的方式来整合到项目中,所以说是一个渐进式的框架。 ​ 渐进式:先完成最基本的功能 开发应用,但是如果想开发复杂功能,那么就可以引入各种vue插件来完成(vue是一个自底向上逐层开发的一个框架)

三.vue生命周期

实例创建 实例创建之前-----beforeCreate 数据的观测与事件的初始化 属性的创建 还没有进行

实例创建之后-----created 在此时vue实例已经创建完毕 所以 数据的观测 属性 方法等内容都已经创建完毕(el属性还没有挂载)

模板渲染

模板渲染之前-----beforeMount 在页面挂载前调用的 所以在此阶段页面还没有进行渲染与模板的编译 程序在此时会把数据绑定到页面上但是页面并没有显示

模板渲染之后-----mounted 页面已经渲染出来了 html的内容会在dom中进行加载展示

数据更新

数据更新之前-----beforeUpdate 在此时数据会不停的在dom中进行修改

数据更新之后-----updated 把修改之后的dom内容已经在页面成功的展示了

激活前----keep-alive专属,组件被激活时调用 当组件被切回来时,再去缓存里找这个组件,触发activated钩子函数 激活后---keep-alive专属,组件被销毁是时调用 当组件被换掉时,会被缓存到内存中,触发deactivated钩子函数

实例销毁

实例销毁之前-----beforeDestory 此时vue实例还能用

实例销毁之后-----destoryed 什么都没有了 vue实例等内容都没了

四.vue子组件和父组件执行顺序

加载渲染过程 beforeCreate(父)->created(父)->beforeMount(父)-> beforeCreate(子)->created(子)->beforeMount(子)->mounted(子)->mounted(父) 更新过程 beforeUpdate(父)->beforeUpdate(子)->update(子)->update(父) 销毁过程 父--子--子--父

五.vue组件传值

4.总结组件传值

  • 正向传值:就是把数据从父组件给子组件

    • 通常使用props (但是除了props以外还有 )

    • vue3中setup第一个形参props也可以 第二个形参的attrs也可以

    • 同时还可以使用defineProps也能完成

    • 还能使用provide和inject

  • 逆向传值:就是把数据从子组件传递给父组件

    • 通常我们使用$emit自定义事件来完成 但是除了这个以外

    • 还可以使用 vue3中的setup第二个形参context的第二个属性emit

    • 还可以使用defineEmits

    • 还可以一使用ref来完成 但是在vue3中ref来实现的时候需要配合defineexpose

  • 同胞传值:有共同父组件的组件之间相互传递数据

    • 最常用的就是eventBus中央事件总线$emit传递数据,$on接收数据 ( 但是除了他以外)

    • 还可以使用状态提升这种方式 就是把数据提升到要传值的共同父组件身上

  • 跨层级传值:

    • provide&inject

    • vuex状态管理工具

六.vue双向绑定原理 Object.defineProperty

在vue2.0中基于数据劫持--数据代理发布者订阅者模式完成的

数据劫持:数据拦截 就是对data中的数据在初始化的时候监听起来(Object.defineProperty 来进行监听/代理) 当数据改变setter之后 vm就会知道 在视图改变getter 他就会通知模型你要修改了 模 型改变了也会通知视图改变

发布者订阅者模式:就是一个一对多的关系 发布者就是数据提供者 订阅者就是页面展示的 一个发布者可以对应无数个订阅者 但是发布者改 变了 所有订阅者也会改变

2.0的响应式基于Object.defineProperty中的set和get方法实现兼容主流浏览器和ie9以上的ie浏览器,能够监听数据对象的变化,但是监听不到对象属性的增删、数组元素和长度的变化,同时会在vue初始化的时候把所有的Observer(观察者)都建立好,才能观察到数据对象属性的变化。

3.0的响应式采用了ES2015的Proxy来代替Object.defineProperty,可以做到监听对象属性的增删和数组元素和长度的修改,同时还实现了惰性的监听(不会在初始化的时候创建所有的Observer,而是会在用到的时候才去监听)但是,虽然主流的浏览器都支持Proxy,ie系列却还是不兼容,所以针对ie11,vue3.0决定做单独的适配,暴露出来的api一样,但是底层实现还是Object.defineProperty

八.$nextTick原理及应

** 等待dom加载完毕后立即执行的一个操作用**

原理:
1.首先修改数据,这是同步任务。同一事件循环的所有的同步任务都在主线程上执行,形成一个执行栈,此时还未涉及DOM。
​
2.Vue开启一个异步队列,并缓冲在此事件循环中发生的所有数据变化。
​
3.同步任务执行完毕,开始执行异步队列的任务,更新DOM

什么时候用

为了在数据变化之后等待 Vue 完成更新 DOM 可以在数据变化之后立即使用Vue.nextTick(callback)。这样回调函数在 DOM 更新完成后就会调用。

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

watch总结

vue3中的watch作用和vue2是一样的都是对数据进行监听当数据改变的时候watch就会知道从而执行一个函数

在vue3中watch他在监听基本类型和复杂类型的时候语法有所不同

在监听基本类型的时候watch的第一个参数就是你要监听的内容 第二个参数就是监听内容改变之后触发的函数

在监听负载类型的时候 vue3watch默认是开启deep的 如果直接监听复杂数据 可能会出现 数据改变了 但是监听函数中的newval和oldval相同的问题 解决方式就是在监听的时候把第一个参数变成一个函数return 我们要监听的内容 即可解决

但是在监听数据的时候 如果监听的数据的属性也是复杂类型那么默认就不行了 我们必须在watch上设置第三个参数 是一个对象 写入deep为true开启深度监听

计算属性与事件监听区别?

计算属性 : 计算属性是依赖data的数据 当data的数据改变之后计算属性会重新计算返回一个新的结果 watch:watch是监听data的数据 当data的数据改变之后 watch会调用一个回调函数完成一些特定的逻辑

计算属性是同步的 watch是异步的

计算属性(computed)属性检测(watch)
首次运行首次不运行
默认深度依赖默认浅度观测
适合做筛选,不可异步适合做执行异步或开销较大的操作

vue2.0计算属性是依赖于数据的。当数据发生变化时,计算属性会重新计算返回一个新的结果

vue3.0计算属性computed是用对数据进行逻辑处理操作,实现数据包装。计算属性通常依赖于当前vue对象中的普通属性

当依赖的依赖的普通属性发生变化的时候,计算属性也会发生变化。

十:过滤器和自定义指令

自定义指令:在现有内置指令不够用的时候 我们可以自己定义指令来进行使用

自定义指令的钩子函数

bind 指令绑定到元素之上的时候执行 但是只执行一次

unbind 指令被移除的时候执行 只执行一次

update 所有组件节点更新的时候执行调用

componentUpdate 指令所在节点以及所有的子节点都更新完成的时候调用

inserted 绑定指令的元素在页面展示的时候调用

全局自定义指令 --- directive

局部自定义指令 --- directives

过滤器: 在不改变原始数据的情况下格式化展示内容

  • vue1有内置过滤器和自定义过滤器

  • vue2取消了内置过滤器

  • vue3取消了自定义过滤器

在vue3中可以把数据当成函数的实参传递给一个函数,即使用函数模拟vue2中的过滤器

自定义过滤器

全局过滤器--filter

在所有vue实例组件中都可以使用

局部过滤器--filters

仅仅只能在指定的实例组件中使用

vue路由的实现

两种模式hash和history

hash

是vue路由的默认路由模式 如果你不指定 那么就是hash模式

url带#号 上线之后刷新不会丢失 浏览器兼容性好

history

url不带#号 上线之后刷新会丢失(需要让你们后端服务器人员给你配置服务器的重定向) 浏览器兼容性一般

总结路由传参/动态路由匹配

路由传参或者是动态路由匹配 他是vue-router 给我们提供的一种 把数据从一个路由页面传递到另外一个路由页面的技术

他有传参两种方式

第一种params 这种方式在传递参数的时候共3步 1在接收的路由页面规则中配置接收参数 2发送 我是使用name作为跳转地址 使用params来设置发送参数 3接收 能想起来就说想不起来就不说 this.$route.params.xxxx

第二种方式 query 他在传递数据的时候共两部 发送和接收 和params方式基本相同 唯独在发送数据的时候 他不但可以使用name作为跳转地址 还可以使用path 在接收的时候 语法也略有不同 他使用this.$route.query.xxxx

query方式与params方式传参区别

1.url展示形态

params方式 传递参数的时候相对安全一些 因为不显示传递的数据key

query方式 在传递的时候会显示数据key和val 相对来说没有parmas安全

2.刷新丢失

parmas方式 刷新会丢失 (上线之后)

query方式 刷新不会丢失

3.语法区别

$router与$route的区别

$router代表的是 路由对象 他所涉及的范围是全部项目页面

$route代表 当前路由页面对象

扩展----路由懒加载 白屏问题

在没有使用路由懒加载的时候 第一次加载会把所有的路由页面全部加载完 在显示页面 有的时候 用户的设备网络不好的时候 导致渲染时间过长 用户就会在第一次进入我们项目的时候 有白屏问题(用户体验不好)

异步组件方式

  component: (resolve) => require(['你引用组件页面的路径'], resolve)

import导入方式

路由钩子/路由守卫/导航守卫/路由卫士

在路由跳转的特定时期自动触发的一些函数 (这些钩子函数通常是在页面跳转的时候 对项目中的用户权限进行设置的)

全局:所有页面在跳转的时候都会触发

全局前置守卫---beforeEach()

在所有路由跳转之前 触发的钩子函数(此时路由还没有跳转完成)

全局后置守卫--- afterEach(()

所有路由跳转之后 触发的钩子函数 (此时已经进入到了跳转之后的新页面)

路由独享:指定页面在跳转时触发

路由独享---beforeEnter

只会对一个路由规则生效(路由独享写在那个规则之上 就对哪一个生效

组件内:仅仅对某些组件在路由跳转时生效

进入组件时候---beforeRouteEnter

离开组件的时候---beforeRouteLeave

vuex

vue中的统一状态(数据)管理工具

五大属性

1.state ----- 数据源 存放数据的 this.$store.state.xxx

2.module---- 模块 使用vuex的模块把内容进行拆分 this.$store.state.模块名.xxxx

3.-mutations---修改数据(state)的 需要在组件中使用commit()来进行调用

mutations的payload

在我们使用commit()时第一个参数是你要调用的修改动作名

第二个参数是你要给mutations传递的数据

4.actions---异步触发器 在vuex中进行异步操作的触发

要触发actions使用dispatch

5.getters---vuex的计算属性

vue的计算属性是computed 对data的数据进行依赖 处理之后返回新 的计算之后的结果

vuex的getters也是计算属性 只是他和上面的computed最大的区别就是 他处理的数据可以在任何组件直接使用 而vue的computed 处理的数据只能在当前组件使用

vuex的闭环操作

dispath触发actions进行异步触发 把请求来的数据 通过commit交给mutations修改state 在页面读取展示

动态组件  

多个组件 使用同一个挂载点 并且动态切换

1.需要有多个组件

2.设置挂载点

3.动态切换 修改挂载点上绑定的变量即可

keep-alive 用来保存组件切换的时候页面状态内容 使用keep-alive包裹的组件 不会随着页面的切换 而数据丢失 因为当前组件在切换的时候会被缓存起来 那么这样一来 在组件切换的时候能减低性能上的损耗

属性

include 你要缓存谁

exclude 你不想缓存谁

两个同时写 excloud的优先级大于incloude

钩子函数

activated进入被kepp-alive管理的组件时候触发

deactivated离开被kepp-alive管理的组件时候触发

这两个钩子应该写在被keep-alive管理的组件中 与data等属性同级

vue中常见出现的问题原因及解决办法

1.v-if与v-for能同时使用吗

v-ifv-for 不推荐同时使用v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,影响速度

如果必须要使用的话 变成一个嵌套关系

解决方式

1.使用computed处理数据在便利

2.使用v-show替代v-if

2.屏幕闪烁

当用户的设备和网络比较慢的时候可能就会在页面中吧{{}}全部展现出来 当网络恢复正常之后 有突然间显示ok

使用{{}}模板语法的话就会出现这个问题

解决方式

1.使用v-text (全部在页面中使用v-text指令很麻烦)

2.使用v-cloak指令 等待vue实例渲染完成之后在进行(这个指令是防止页面加载时出现 vuejs 的变量名而设计)

3.屏幕白屏

第一次加载会把所有的路由页面全部加载完 在显示页面 有的时候 用户的设备网络不好的时候 导致渲染时间过长 用户就会在第一次进入我们项目的时候 有白屏问题(用户体验不好)

解决方式

路由懒加载

4.vuex数据刷新丢失?

监听页面刷新 如果刷新 那么就把vuex的数据存储到本地存储中 然后当页面在此加载得的时候 把本地存储存的原始vuex的数据那出来 替换当前的state数据

判断是否有store这个本地存储的数据

如果有,那么把vuex的数据替换,把当前的state和上次刷新存储的state合并起来

在页面监听绑定一个beforeunload(页面刷新事件)

当页面刷新的时候使用本地存储存一个store的数据,把vuex数据全部取出来,转成字符串存起来

5.在vue中,数据改变视图不变?

$set() 就是在程序运行的时候给对象或者数组添加新属性并且让试图改变

语法:

This.$set("你要给谁添加","你要添加的key","你要添加的val")

6.在路由或者动态组件中 页面用户填写的数据可能会随着页面的切换 而丢失,如何保存?

keep-alive 用来保存组件切换的时候页面状态内容

路由:包裹路由出口

动态组件:包裹挂载点

2个属性:include 缓存 exclude 不缓存

2个钩子函数 activated进入被kepp-alive管理的组件时候触发

deactivated离开被kepp-alive管理的组件时候触发

写在被keep-alive管理的组件中 与data等属性同级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值