vue前端面试题 [ 1 ]

目录

1.双向数据绑定的原理

2.使用 Object.defindproperty() 来劫持数据有什么缺点

3.computed和watch的区别 

4.computed和methods

5. v-if 和 v-show的区别

6.为什么vue中的data是函数

8. 单页面应用和多页面应用的区别

9. vue data中的属性发生改变,视图中的数据会立即同步执行发生渲染吗? 

10. assets和static的区别 

11.delete和vue.delete删除数组的区别

12. 对SSR的理解

13. vue项目优化的方法 

14. mixin和mixins

15. created和mounted的区别

16. keep-alive的生命周期

17.组件传值

18. 路由加载 

19. 如何监听hash的变化

20. $route和$router的区别 

21. 如何定义动态路由,如何获取传过来的参数 

 22. vue-router 和 loaction.href的区别

 23.params 和 query的区别

24. vuex和localStorage的区别

25. 为什么不推荐使用下标作为key 

26.vue-router实现的原理 

27.vue中的插槽

28.sync的作用

29.vue中scoped

30.vue中的自定义指令

31.vue中的watch的deep和immediate

32.父子组件之间生命周期加载顺序

33.vue的两个核心 

34.MVC、MVP、MVVM的区别 

35. qs的 stringify 和 JSON 的 stringify 的区别

36. vue中从a界面跳转到b界面经历的生命周期

37. vue中常用修饰符

38. vue的动态路由

39. vue中的diff算法

40. vue的v-model原理

41. vue中hash和history的区别

42. vuex在刷新界面的时候数据会丢失的处理方法

43. vue的首屏优化

44. 为什么使用MVVM,MVVM是什么?


1.双向数据绑定的原理

        (1)vue采用数据劫持结合发布者-订阅者模式的方式,通过Object.defindproperty()劫持各个数据的setter、getter,在数据发生变化时会发送消息给订阅者,触发相应的监听回调

         (2) Object.defineProperty方法接受三个参数:

    1.obj:要在其上定义属性的对象。

    2.prop:要定义或修改的属性的名称。

    3.descriptor:将被定义或修改属性的描述符。

2.使用 Object.defindproperty() 来劫持数据有什么缺点

        (1)对于数组或者对象而言,修改其属性是该方法无法拦截的,不能触发组件渲染。只不过vue内部通过重写函数的方法来解决这一缺陷。在vue3.0中采用了proxy()方法对对象进行代理,该方法能完美监听到数据的任何改变。但是有唯一的缺陷就是兼容性、因为proxy是ES6的语法。

3.computed和watch的区别 

        (1)computed:1. 支持缓存,只有所依赖的数据发生改变时才会触发

                                     2.不支持异步,computed有异步得到的数据无法监听

                                     3.默认走缓存,数据依赖是data中的值或者父组件传来的值

        (2)watch:1. 不支持缓存(数据发生变化就会触发)

                              2. 支持异步

                              3. 传入的参数有2个,第一个是新的值、第二个是旧的值

                              4. 监听的数据是基于data声明或者父组件传过来的值

4.computed和methods

        (1)computed:只有基于它们的依赖发生改变才会触发计算属性

        (2)methods:调用时总会执行

5. v-if 和 v-show的区别

        v-if 是动态的向DOM树增加和删除DOM元素,在切换的过程中有编译/卸载的过程并且具有更高的切换消耗,适用于一些不经常改变状态的场景。

        v-show是通过设置DOM元素的css样式控制显隐,对于切换时性能的消耗低于v-if,仅在初始时进行渲染,适用于切换频繁的场景

6.为什么vue中的data是函数

        (1)因为对象是引用类型,多个实例引用同一个对象时,只要有一个对其进行修改其他实例中的数据也会改变

        (2)在vue中,大多数都要复用组件,这样每个组件都会拥有自己的数据,组件间就不会相互干扰

8. 单页面应用和多页面应用的区别

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

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

9. vue data中的属性发生改变,视图中的数据会立即同步执行发生渲染吗? 

        (1)不会立即同步执行发生渲染。vue实现响应式并不是数据一发生变化DOM就会立即改变,而是会开启一个队列。vue修改DOM是异步操作。而相同的watcher被改变,只会被推入一次到队列中,这样可以减少计算和DOM的操作。在下一次的事件循环tick中vue会重新刷新队列

        (2)使用vue.nextTick()这个方法,在下次的DOM更新结束后执行延迟回调,修改数据后使用此方法可以获取到更新后的数据 

10. assets和static的区别 

        (1)两者都是项目中存放静态资源的文件

        (2)不同点:在项目打包时,使用npm run build assets文件将会被打包放置在static文件一起跟着index.html上传到服务器。而static文件则不会被打包,而是跟着一起上传(有利于提高打包效率)

11.delete和vue.delete删除数组的区别

        (1) delete是将被删除的元素变为 empty/undefined,其他元素的键值依然不变

        (2)vue.delete是直接将数组对象里的键值删除,改变了数组的键值

12. 对SSR的理解

        (1)SSR就是服务端渲染,是vue将在客户端的标签渲染成HTML界面放到服务端上去完成,完成后在将HTML界面返回给客户端

        (2)优点: 1. 更好的SEO    2. 首页加载更高效快速 

        (3)缺点: 1. 对开发不友好,服务器端渲染只支持beforeCreate和created两个钩子。

                             2. 更多的服务端负载 

13. vue项目优化的方法 

        (1)减少data中的数据 、避免v-if和v-for一起使用、尽量使用v-if代替v-show、对于SPA页面使用keep-alive进行组件缓存、路由懒加载、使用图片懒加载、防抖节流、第三方插件按需引入、雪碧图、压缩CSS样式和JS脚本、减少DOM的操作

        (2)使用cdn加载第三方模块

14. mixin和mixins

        (1)mixin 用于全局混入,会影响到每个组件实例,通常插件都是这样做初始化的。

        (2)mixins  是扩展组件的方式,通常各个组件内有相同的业务逻辑都可以抽离出来放在mixins里、但是mixins里的钩子函数会比组件里的钩子函数先执行

15. created和mounted的区别

         (1)created:是在渲染成html页面前使用,通常是要初始化一些数据,在渲染成视图

        (2)mounted:是在渲染成html页面后使用,通常是在界面渲染完成后需要对一些DOM进行操作

16. keep-alive的生命周期

        (1) keep-alive是vue对组件的一种缓存方式,在组件切换的时候保存组件的状态,避免多次渲染。使用keep-alive就会多出两个生命钩子deactivated、activated而beforeDestroy 和 destroyed这两个钩子就不会再被触发,因为没有真正意义上的销毁。当组件被换掉时,会被缓存到内存中、触发 deactivated 生命周期;当组件被切回来时,再去缓存里找这个组件、触发 activated钩子函数

        (2)keep-alive的三个属性:include、exclude、max(数字:最大缓存数)

17.组件传值

        (1)$emit \ $on (eventBus事件总线)

        (2)props \ $emit 

        (3)依赖注入(project \ inject)

        (4)ref \ $refs

        (5)$parent \ $children

        (6)$attr \ $listeners 

18. 路由加载 

        (1)非加载

import List from '@/components/list.vue'
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

         (2)使用箭头函数+import动态加载

const List = () => import('@/components/list.vue')
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

         (3)使用箭头函数+require动态加载

const router = new Router({
  routes: [
   {
     path: '/list',
     component: resolve => require(['@/components/list'], resolve)
   }
  ]
})

         (4)使用webpack的require.ensure技术,也可以实现按需加载。 这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

// r就是resolve
const List = r => require.ensure([], () => r(require('@/components/list')), 'list');
// 路由也是正常的写法  这种是官方推荐的写的 按模块划分懒加载 
const router = new Router({
  routes: [
  {
    path: '/list',
    component: List,
    name: 'list'
  }
 ]
}))

19. 如何监听hash的变化

        (1)监听$route的变化

// 监听,当路由发生变化的时候执行
watch: {
  $route: {
    handler: function(val, oldVal){
      console.log(val);
    },
    // 深度观察监听
    deep: true
  }
},

         (2)使用window.location.hash读取#值

20. $route和$router的区别 

        (1)$route是获取路由信息对象,包括path,params,hash,query,fullPath,matched,name 等路由信息参数

        (2)$router是路由的实例对象,包括子路由的跳转方式和生命钩子

21. 如何定义动态路由,如何获取传过来的参数 

        (1)params方式:

                        格式:/router/:id

                        传递方式:在path后面跟上特定的值

                        效果:/router/123

        (2)路由定义:

//在APP.vue中
<router-link :to="'/user/'+userId" replace>用户</router-link>    

//在index.js
{
   path: '/user/:userid',
   component: User,
},

        (3)路由跳转

// 方法1:
<router-link :to="{ name: 'users', params: { uname: wade }}">按钮</router-link

// 方法2:
this.$router.push({name:'users',params:{uname:wade}})

// 方法3:
this.$router.push('/user/' + wade)

        (4)获取参数:this.$route.params

        (1)query的方式

                        格式:/router

                        对象中使用query的key作为参数传递

                        结果:/router?name=123

        (2)路由定义

//方式1:直接在router-link 标签上以对象的形式
<router-link :to="{path:'/profile',query:{name:'why',age:28,height:188}}">档案</router-link>

// 方式2:写成按钮以点击事件形式
<button @click='profileClick'>我的</button>    

profileClick(){
  this.$router.push({
    path: "/profile",
    query: {
        name: "kobi",
        age: "28",
        height: 198
    }
  });
}

         (3)跳转方法

// 方法1:
<router-link :to="{ name: 'users', query: { uname: james }}">按钮</router-link>

// 方法2:
this.$router.push({ name: 'users', query:{ uname:james }})

// 方法3:
<router-link :to="{ path: '/user', query: { uname:james }}">按钮</router-link>

// 方法4:
this.$router.push({ path: '/user', query:{ uname:james }})

// 方法5:
this.$router.push('/user?uname=' + jsmes)

        (4)获取参数:this.$route.query

 22. vue-router 和 loaction.href的区别

        (1)使用后者进行跳转简单方便,但是会刷新界面

        (2)使用前者进行跳转不会刷新界面,会根据diff算法来按需加载减少DOM的操作

 23.params 和 query的区别

        (1)query需要path来引入,而params需要name来引入,不过两者查询参数的方式差不多

        (2)query类似AJAX的get传值会在url上显示、params类似AJAX的post传值不会在url上显示

        (3)query在刷新界面时参数不会丢失,而params会丢失 

24. vuex和localStorage的区别

        (1)vuex里的数据是存在内存中,localStorage的数据是以文本形式存在本地且只能存储字符串类型的需要用JSON.parse/JSON.stringify

        (2)vuex是vue.js提出来的一个可以管理项目状态的仓库,localStorage是本地存储在浏览器中

        (3)vuex中可以存储的数据大小比localStorage的大得多

        (4)vuex只要刷新界面数据就会丢失、而localStorage不会

25. 为什么不推荐使用下标作为key 

        (1)因为数组不管如何颠倒,下标始终是0.1.2.3这样排列下去。这样不仅会导致数据的错乱,也会导致vue多次复用旧的节点导致一些不必要的工作

26.vue-router实现的原理 

        概念:通过改变 URL,在不重新请求页面的情况下,更新页面视图。 

        路由模式有2种(hash和history):

                hash模式在url中含有#符号,但是仅有#符号前的内容会被包含在请求中#后的不论怎么写都不会返回404

                history模式中前端url地址必须和后端的一致否则返回404,history含有push和replace方法

27.vue中的插槽

        vue插槽有3种:默认插槽,具名插槽,作用域插槽  

28.sync的作用

        该修饰符的作用是可以使子组件向父组件传值 

29.vue中scoped

        scoped是阻止穿透(防止全局污染),在使用组件库时会有一个date对其相应的属性做唯一标识。要想修改其样式有2种方法:(1)可以重写一个style (2)使用/deep/、>>>、::deep三者中的一个

30.vue中的自定义指令

        vue中的自定义指令:全局指令(vue.directive)、局部指令(directive)

        其可以接受参数(id,定义对象),其中的钩子函数:

                1. bind:

                        在指令第一次绑定到元素时调用(在该环节中是获取不到父节点的,父节点是null)。在这里可以进行一次性的初始化设置。

                2. inserted:

                        被绑定元素插入父节点时调用(在该环节中是可以获取到父节点的)

                3. componentUpdated:

                        指令所在的组件以及子组件全部更新后调用

                4.unbind:

                        指令和元素解绑的时候调用一次

31.vue中的watch的deep和immediate

         deep:其值为 true/false,确认是否深度监听(深度监听可以监听对象属性和数组的变化)

         immediate:其值为 true/false,确认是否以当前的初始值执行 handler 函数。

         immediate 设为 true 后,则监听的这个属性会立即输出,也就是说一刷新页面就会在控制台输出,当然此时页面上的数据我们还没来得及手动让其发生变化,所以在控制台输出的newValue为我们在代码中默认设置的值,oldValue输出为“undefined”。

32.父子组件之间生命周期加载顺序

        界面渲染时:beforecreated(父) =》created(父) =》beforemounted(父)=》beforecreated(子)=》created(子)=》beforemounted(子)=》mounted(子)=》mounted(父)

        数据更新时:beforeUpdate(父)=》beforeUpdate(子)=》Update(子)=》Update(父)

        界面卸载时:同上

33.vue的两个核心 

        1.双向数据绑定 2.组件系统

34.MVC、MVP、MVVM的区别 

        MVC:模型层、视图层、控制层(1.V->C->M->V view接受指令 2.C->M->V control接受指令)。优点:耦合性低、重用性高、可维护性高。

        MVP:模型层、视图层、逻辑层(V和M之间不通信、通过P来传递、P将V、M完全分离)

                   与MVC的区别:V不直接使用M而是通过P来通信

                   优点:模型与视图分离,修改视图可不影响模型、更高效的使用模型

        MVVM:与MVC模式类似、目的是分离V和M。优点:低耦合、可重用性

      

35. qs的 stringify 和 JSON 的 stringify 的区别

        qs.stringify是将 对象序列化成url 的形式并以 & 进行拼接,qs.parse 是将url 解析成对象。当给qs.stringify传字符串时,得到的结果是空。给qs.parse传字符串时会解析成对象并以字符串作为键、值为空。

        JSON.stringify 将对象转成JSON格式、JSON.parse 将JSON格式的字符串转成对象

36. vue中从a界面跳转到b界面经历的生命周期

1、 B.created() 
2、 B.beforeMount()
3、 A.beforeDestroy()
4、 A.destroyed()
5、 B.mounted()

37. vue中常用修饰符

一、事件修饰符

  1、.stop:阻止事件冒泡

  2、.prevent:提交事件不再重新加载页面,可以用来阻止表单提交的默认行为

  3、.once:点击事件只会触发一次

  4、.native:使用时将被当成原生HTML标签看待

二、按键修饰符

  1、@keyup:键盘抬起

  2、@keydown:键盘按下

  3、按键码:在键盘修饰符后面添加.xxx,用于监听按了哪个键

  常用按键码:.enter,.tab,.delete,.esc,.up,.down,.space等。

三、表单修饰符

  1、.lazy:在表单输入时不会马上显示在页面,而是等输入完成失去焦点时才会显示;

  2、.trim:过滤表单输入时两边的空格;

  3、.number:限制输入数字或将输入的数据转为数字

38. vue的动态路由

        1. 在路由表中配置meta属性,扩展权限相关字段,在路由守卫导航里判断这个权限标识,实现路由的动态增加和跳转(在router.BeforeEach中使用router.addRoutes来增加对应的路由)

        2. 根据登录账号,返回用户角色权限

        3. 前端在根据角色,跟路由表中的meta.role中匹配

        4. 把匹配搭配的路由形成可访问的路由

39. vue中的diff算法

        vue中的diff算法是用来比较新旧虚拟DOM的差异的,并找出最小DOM的操作方式来更新DOM算法。这样做是为了减少不必要的DOM操作,减缓界面的渲染。

        diff算法就是虚拟DOM比对时用的,返回一个patch对象,这个对象的作用就是存储新旧两个节点不同的地方,最后用patch中记录的信息更新真实的DOM

        步骤如下:

        1. 当新旧节点是同一节点类型时,比较它们的属性,对根节点进行更新

        2. 新节点如果是文本节点,并且和旧节点不同,则直接替换旧节点

        3. 如新节点是注释节点,则根据是否相同进行相应的操作

        4. 当旧节点不存在,新节点存在时,执行插入操作。

        5. 当旧节点存在,新节点不存在时,执行删除操作。

        6. 当节点的key相同时可复用节点

        7. 对子节点进行递归比较

40. vue的v-model原理

        v-model本质上是语法糖,其实现原理包含两个步骤: 1. 通过v-bind绑定value属性。2. 通过v-on给当前元素绑定一个input事件

41. vue中hash和history的区别

        1. hash模式下url上有#号,history模式没有

        2. 在做回车刷新界面的时候hash会加载对应的界面,history会返回404

        3. hash模式支持旧版本的浏览器,history不支持,因为是H5新增的API

        4. hash不会重新加载界面,单页面应用必备

        5. history有历史记录,H5新增了pushstate和replacestate()去修改历史记录,并不会立刻发送请求(可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。history 模式下,前端的 URL必须和实际向后端发起请求的URL一致,否则会报404错误)

        6. history需要后台配置

42. vuex在刷新界面的时候数据会丢失的处理方法

        1. 把数据存储在浏览器本地缓存中

        2. 在刷新界面的时候重新请求接口

                监听浏览器的刷新事件,在刷新前把数据保存到sessionstorage里,刷新后请求数据,请求到了用vuex,如果没有那就用sessionstorage里的数据

43. vue的首屏优化

        1. 使用路由懒加载

        2. 非首屏组件使用异步组件

        3. 首屏不重要的组件异步加载

        4. 静态资源放CDN上

        5. 减少首屏上css,js等文件资源的大小

        6. 使用服务端渲染

        7. 尽量减少DOM的数量的层级

        8. 使用精灵图,做一些loading

        9. 开启Gzip压缩,图片懒加载

44. 为什么使用MVVM,MVVM是什么?

        MVVM(Model-View-ViewModel)是一种软件架构设计模式,它是一种简化用户界面的事件驱动编程方式。

        在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者。ViewModel是连接View和Model的中间件。

  • ViewModel能够观察到数据的变化,并对视图对应的内容进行更新。
  • ViewModel能够监听到视图的变化,并能够通知数据发生变化

        为什么要使用MVVM:

                 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候,View也可以不变。
                可复用:可以把一些视图逻辑放到一个ViewModel里面,让很多View重用这段视图逻辑。
                独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
                可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值