2021vue面试题_Vue面试

(37) 2024-09-04 18:01:01

vue重置data

Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象 this.$data获取当前状态下的data this.$options.data()获取该组件初始状态下的data Object.assign(this.$data,this.$options.data()) 

vue原理

vue 双向数据绑定是通过数据劫持结合发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变 

js的双向数据绑定

<div id="app"> <input type="text" id="ipt"> <h3 id="txt"></h3> </div> <script> //模拟数据模块 var msg="hello world"; //建立对象 var obj={ 
   }; Object.defineProperty(obj,'value',{ 
    //设置get、set访问器 get(){ 
    return this._value; }, set(val){ 
    this._value=val; ipt.value=val; txt.innerText=val; } }); obj.value=msg; //监听文本框输入 ipt.addEventListener("input",function(){ 
    obj.value=this.value; console.log(obj.value); }) </script> 

动态路由

1、将路由分为静态路由(staticRouters)、动态路由 2、静态路由初始化时正常加载 3、用户登陆后,获取相关动态路由数据, 4、然后利用vue:addRoute追加到vue实例中即可。 

路由解耦

1、只有动态路由才能用路由解耦 export default { 
    methods: { 
    getParamsId() { 
    return this.$route.params.id } } } 2、在定义路由的时候通过/:属性的方式来定义传递参数的属性 3、需要在定义路由的时候设置属性props:true const router = new VueRouter({ 
    routes: [{ 
    path: '/user/:id', component: User, props: true }] }) 4、在进行路由跳转的时候通过/值得方式进行传递数据 5、在需要接收参数的组件中通过props进行接收即可 export default { 
    props: ['id'], methods: { 
    getParamsId() { 
    return this.id } } } 

eventBus缺点

1,出现很多个组件传递时,没法找都在哪里定义 2,生命周期的问题(EventBus事件未在实例销毁的时候,注销监听事件,导致触发上一次监听事件,遗留数据也是上一次事件中的) 

$nextTick优点

常用的场景是在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到dom 

vue中nextTick()原理

由于Vue DOM更新是异步执行的,即修改数据时,视图不会立即更新,只要监听数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更,在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。 然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。 等同一数据循环中的所有数据变化完成之后,再统一进行视图更新。 为了确保得到更新后的DOM,所以设置了 Vue.nextTick()方法。 nextTick主要使用了宏任务和微任务 Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0)代替。 

vue中11个生命周期

beforeCreate:vue 实例还没有被完全创建出来,此时 data,methods 等内部没有初始化,无法获取响应数据。 created:vue 实例已经初始化了,可以在这里调用数据,不过还没渲染到页面上 beforeMount:vue 已经将模板字符串编译成内存虚拟DOM,模板已经编译完成,已经完成渲染树,还没有渲染到页面上 mounted:注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick: beforeUpdate:内存中的数据已经改变,页面上的还没更新 updated:页面上数据和内存中的一致 activated:被 keep-alive 缓存的组件激活时调用。 deactivated:被 keep-alive 缓存的组件停用时调用。 beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。 destroyed:实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。 

vuex

VueX 是一个专门为 Vue.js 应用设计的状态管理架构,统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念,state, getters, mutations, actions, modules。 state => 基本数据 getters => 从基本数据派生的数据 mutations => 提交更改数据的方法,同步! actions => 像一个装饰器,包裹mutations,使之可以异步。 modules => 模块化Vuex 辅助函数:mapState、mapGetters、mapMutations、mapActions createStore 模块化:namespece,this.store.state.模块名称.属性 其中state和getters用来保存状态;mutations和actions用来改变状态;监听状态用的是Vue组件中的computed属性;module是用来组织整个应用的状态管理代码,使状态划分模块,更易于管理;辅助函数用来在监听状态时候简化代码,createStore则用来创建状态管理对象。 mutations和actions有区别,mutations不应该用于异步修改状态,因为这样做的话,Vuex是无法知道修改state.count的时机的,因为它是在异步回调里面指定的,因此Vuex无法在调试工具中打印出我们实际改变state的操作。 而actions中可以异步更新状态。 getters和state的关系类似于Vue组件data属性和computed属性的关系,getters根据state或者其他getters计算出另一个变量的值,当其依赖的数据变化时候,它也会实时更新。 

vue中组件通信

一、props / $emit (最常用的组建通信方式) 二、$children / $parent 三、provide/ inject 四、ref / refs 五、eventBus 六、Vuex 七、$attrs与 $listeners 八、localStorage / sessionStorage 

vue组件data用箭头函数

可以使用箭头函数,但是需要注意this指向。 如果使用箭头函数,data函数中的this不会指向vue实例,如果需要访问vue实例,可以通过data函数的参数来实现。 data: vm => ({ 
    a: vm.myProp }) 

vue父子组件挂载顺序

加载渲染过程 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created ->子 beforeMount -> 子 mounted -> 父 mounted 更新过程 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated 销毁过程 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed 

route和router的区别

route是路由信息对象,每一个路由都会有一个route对象,是一个局部的对象,里面主要包含路由的一些基本信息,比如name、meta、path、hash、query、params、fullPath、matched、redirectedFrom…
2021vue面试题_Vue面试 (https://mushiming.com/)  第1张
router是VueRouter的实例,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性

  1. $router.go()
  2. $router.push()
  3. $router.replace()

Query和params的区别

this.$router.push({ 
   path:"地址",query:{ 
   id:"123"}}); 这是传递参数 this.$route.query.id; 这是接受参数 this.$router.push({ 
   name:"地址",params:{ 
   id:"123"}}); 这是传递参数 this.$route.params.id; 这是接受参数 两者中query在刷新页面的时候参数不会消失 但params在刷新页面的时候参数会消失 可以考虑本地存储解决此问题 query传过来的参数会显示到地址栏中 而params传过来的参数不会显示到地址栏中 直白的来说 query相当于get请求,而params相当于post请求 

v-if和v-show的区别

行为不同:v-if指令在满足条件时候才会渲染DOM,v-show一开始就渲染DOM,满足条件时候才设置CSS的display属性让元素显示出来。 应用场景不同:一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。 

v-for和v-if同时使用有问题

永远不要把 v-if 和 v-for 同时用在同一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断) Vue3修改了v-if和v-for的优先级,v-if没有权限访问v-for的变量,这个需要注意。 

虚拟dom的实现原理与优缺点

虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象 状态变更时,记录新树和旧树的差异,最后把差异更新到真正的dom中. 虚拟DOM的作用:使用原生js或者jquery写页面的时候会发现操作DOM是一件非常麻烦的事情,往往是DOM标签和js逻辑同时写在js文件里,数据交互时不时还要写很多的input隐藏域,如果没有好的代码规范的话会显得代码非常冗余混乱,耦合性高并且难以维护。 另外一方面在浏览器里一遍又一遍的渲染DOM是非常非常消耗性能的,常常会出现页面卡死的情况;所以尽量减少对DOM的操作成为了优化前端性能的必要手段,vdom就是将DOM的对比放在了js层,通过对比不同之处来选择新渲染DOM节点,从而提高渲染效率。 
优点: 保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限 无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率 跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等 缺点: 无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优 

keep-alive实现原理

什么是keep-alive: keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 keep-alive是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件中。 作用 在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性 原理: 在 created钩子函数调用时将需要缓存的 VNode 节点保存在 this.cache 中/在 render(页面渲染) 时,如果 VNode 的 name 符合缓存条件(可以用 include 以及 exclude 控制),则会从 this.cache 中取出之前缓存的 VNode实例进行渲染。 

computed和watch的区别

应用场景不同

computed用在根据data属性或者其他computed计算得到一个新值的情况,computed的值一般被用在渲染中。 watch用在监听数据变化,然后做一些有副作用的操作的场景。 执行过程不同 在依赖的data属性变化后,computed并不会重新计算新的值,而是等到访问的时候再判断,如果依赖的data有改动则重新计算并返回结果,如果依赖的data没有改动,就不计算,直接返回当前结果。 依赖的数据变化后就会执行watch的回调。 

vue-router原理以及两种模式区别

前端路由有两种模式,HTML5和hash,这两种模式本质是不同的底层浏览器技术,但是上层Vue Router做了统一化的封装,因此在我们开发组件和配置路由时候使用这两种模式的区别并不大。默认是hash模式。 这两种模式有几个主要区别 1. HTML5模式的路由没有"#"字符,而是在域名后直接写路径,更加优雅 2. 由于#后面的字符不会发给服务器,因此hash路由SEO比较差 3. HTML5需要服务器在访问不同的路径时候都能fallback到index.html,因此相对麻烦

前端路由的原理关键有21. 可以修改url,但不会引起刷新,从而在不刷新的页面的情况下跳转路由。 2. 监听url改变,根据url渲染对应组件。 hash模式和history模式的原理都是基于这两点。hash是通过浏览器提供的location API修改url,通过onhashchange方法监听hash改变;history通过浏览器提供的history.pushState或者history.replacestate修改url,通过popState事件监听url改变。 

Vue如何给一个对象添加新的属性

Vue.set(object, propertyName, value)
vm.$set((object, propertyName, value)

vue的compile过程

Vue在实例化组件时候会生成虚拟DOM,Vue先判断是否有render函数,如果有的话调用render生成虚拟DOM;如果没有render函数,则获取template选项,template选项可以是选择器、模版字符串、dom元素,Vue根据template选项进行模板编译;如果没有template,则获取el以及其子内容作为模版。

模板编译有三个步骤

  1. 将模板解析为AST。(Abstract Syntax Tree,抽象语法树)。
  2. 遍历AST标记静态节点。
  3. 使用AST生成渲染函数。
THE END

发表回复