Vue面试题总结


一:Vue的优缺点

1):优点

1、数据驱动视图,对真实 dom 进行抽象出 virtual dom(本质就是一个 js 对象),并配合 diff 算法、响应式和观察者、异步队列等手段以最小代价更新 dom,渲染页面

2、组件化,组件用单文件的形式进行代码的组织编写,使得我们可以在一个文件里编写 html\css(scoped 属性配置 css 隔离)\js 并且配合 Vue-loader 之后,支持更强大的预处理器等功能

3、强大且丰富的 API 提供一系列的 api 能满足业务开发中各类需求

4、由于采用虚拟 dom,让 Vue ssr 先天就足

5、生命周期钩子函数,选项式的代码组织方式,写熟了还是蛮顺畅的,但仍然有优化空间(Vue3 composition-api)

6、生态好,社区活跃

2):缺点

1、由于底层基于 Object.defineProperty 实现响应式,而这个 api 本身不支持 IE8及以下浏览器

2、csr 的先天不足,首屏性能问题(白屏)

3、由于百度等搜索引擎爬虫无法爬取 js 中的内容,故 spa 先天就对 seo 优化心有余力不足(谷歌的 puppeteer 就挺牛逼的,实现预渲染底层也是用到了这个工具)

二:vue 指令和用法

1):v-model 双向数据绑定:

  • 定义:用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作;
    • v-for 循环;基于源数据多次渲染元素或模板
    • v-if v-show 显示与隐藏;
    • v-bind 绑定一个 value 属性;
    • v-on 指令给当前元素绑定 input 事件;
    • v-on 事件;v-once: 只绑定一次;

2):v-show 和 v-if 指令的共同点和不同点?

  • 共同点:都能控制元素的显示和隐藏;

  • 不同点:实现本质方法不同,v-show 本质就是通过控制 css 中的 display 设置为 none,控制隐藏,只会编译一次;v-if 是动态的向 DOM 树内添加或者删除 DOM 元素,若初始值为false,就会编译了。而且 v-if 不停的销毁和创建比较消耗性能

    总结:如果要频繁切换某节点,使用 v-show(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用 v-if(初始渲染开销较小,切换开销比较大)

3):keep-alive

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

4):如何获取 dom?

  • 定义:ref=”domName”

    this.$refs.domName

5):vue-loader 是什么?使用它的用途有哪些?

  • 定义:vue-loader的一个加载器,将 template/js/style 转换成 js 模块
  • 用途:js 可以写 es6、style 样式可以 scss 或 less、template 可以加 jade 等

6):key作用

  • 定义:key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点。
  • 作用主要是为了高效的更新虚拟 DOM。

7):axios 及安装?

  • 定义:请求后台资源的模块。

    npm install axios -save
  • js 中使用 import 进来,然后. get 或. post。返回在.then 函数中如果成功,失败则是在.catch 函数中。

8):vue.cli 项目中 src 目录每个文件夹和文件的用法

  1. assets 文件夹是放静态资源;
  2. components 是放组件;
  3. router 是定义路由相关的配置;
  4. app.vue 是一个应用主组件;
  5. main.js 是入口文件。

9):v-if 和 v-for 的优先级

  • 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,所以,不推荐 v-if 和 v-for 同时使用。
  • 如果 v-if 和 v-for 一起用的话,vue 中的的会自动提示 v-if 应该放到外层去。

三:vue中的方法

1):computed、watch的使用场景,methods的区别

  • computed:当一个属性受多个属性影响的时候就需要用到 computed(是自动监听依赖值的变化,简化模板内的复杂运算)

    例子:购物车商品结算的时候

  • watch:当一条数据影响多条数据的时候就需要用watch(为了监听某个响应数据的变化)

    例子:搜索数据

  • methods:是一个方法,它可以接受参数,而computed 不能,computed 是可以缓存的,methods 不会。computed 可以依赖其他 computed,甚至是其他组件的 data

2):vue 中怎么重置 data

  • 定义:使用Object.assign(),vm.$data可以获取当前状态下的data,vm.$options.data(this)可以获取到组件初始化状态下的data

    Object.assign(this.$data, this.$options.data(this))
    // 注意加this,不然取不到data() { a: this.methodA } 中的this.methodA

3):v-on 监听多个方法?

  • 可以监听

    <button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来</button>
    <button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来</button>
    <!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号-->
    <button @click="onEnter(),onLeave ()">点我onEnter onLeave </button>
    onEnter () {
      console.log('mouse enter')
    },
    onLeave () {
      console.log('mouse leave')
    }

4):$nextTick 的使用

  • 定义:当你修改了 data 的值然后马上获取这个 dom 元素的值,是不能获取到更新后的值,则需要:$nextTick 这个回调,让修改后的 data 值渲染更新到 dom 元素之后在获取,才能成功

    new Vue({
     el:' #app',
     data: {
       list: [ ]
    },
    mounted: function(){
     _this.$nextTick(() => {
       this.get()
    },
    methods: {
     get: function () {
       this.$http. get('/api/article'). then(function (res) {
       this.list = res.data.data.list
       // ref list引用了u1元素,我想把第一个li颜色变为红色
       this.$refs.list.getElementsByTagName('li' )[0].style.color = 'red'
    })

5):vue 组件中 data 为什么必须是一个函数

  • 定义:因为 JavaScript 的特性所导致,在 component 中,data 必须以函数的形式存在,不可以是对象。组件data 写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的 data,私有的数据空间,不会造成混乱,而写成对象形式,就共有同一个data,改一个就全改了

6):渐进式框架的理解

  • 定义:主张最少;可以根据不同的需求选择不同的层级;

7):Vue 中双向数据绑定是如何实现的?

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

  • 核心:关于 VUE 双向数据绑定,其核心是Object.defineProperty()方法。劫持各个属性settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

8):理解 Vue 的响应式系统

  • 任何一个 Vue Component 都有一个与之对应的 Watcher 实例,Vue 的 data 上的属性会被添加 getter 和 setter 属性,当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此data 的组件去调用他们的 render 函数进行更新

9):单页面应用和多页面应用区别及优缺点

  • 定义:单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于 pc 端。

  • 定义:多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新

  1. 优点:用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点 spa 对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)
  2. 缺点:不利于 seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多

10):assets 和 static 的区别

  • 相同点:assets 和 static 两个都是存放静态资源文件。

  • 不同点:assets存入静态资源,打包时会放置到asstes中,而压缩后的静态资源最终也static中跟着index.html上传服务器

11):vue 常用的修饰符

  • .stop:等同于js的event.stopPropagetion(),防止事件冒泡

  • .prevent:等同于js的evnet.preventDefault(),防止执行预设的行为(如果事件可取消,则取消事件,而不停止事件的进一步传播)

  • .capture:与事件冒泡的方向相反,事件捕获由外到内

  • .self:只会触发自己范围内的事件,不包含子元素

  • .once:只会触发一次

四:Vue 组件间通信

  1. props/$emit(父传子/子传父)

  2. $emit/$on 监听了自定义事件 data-a和data-b,因为有时不确定何时会触发事件,一般会在 mounted 或created 钩子中来监听

  3. vuex

  4. $attrs/$listeners

  5. provide/inject

  6. $parent/$children 与 ref

1):vue 的两个核心点

  • 数据驱动:ViewModel,保证数据和视图的一致性。

  • 组件系统:应用类UI可以看作是由组件书构成的。

2):vue和jQuery的区别

  • jQuery是使用选择器()选取 DOM 对象,对其进行赋值、取值、事件绑定等操作,其实和原生的 HTML 的区别只在于可以更方便的选取和操作 DOM 对象,而数据和界面是在一起的。比如需要获取 label 标签的内容:(“lable”).val(), 它还是依赖 DOM 元素的值。
  • Vue则是通过 Vue 对象将数据和 View 完全分离开来了。对数据进行操作不再需要引用相应的DOM 对象,可以说数据和 View 是分离的,他们通过 Vue 对象这个 vm 实现相互的绑定。这就是传说中的 MVVM

3):引进组件的步骤

  1. 在 template 中引入组件;
  2. 在 script 的第一行用 import 引入路径;
  3. 用 component 中写上组件名称

4):delete 和 Vue.delete 删除数组的区别

  • delete:只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
  • Vue.delete:直接删除了数组 改变了数组的键值。

5):SPA 首屏加载慢如何解决

  • 定义:安装动态懒加载所需插件;使用 CDN 资源

6):Vue-router 跳转和 location.href 有什么区别

  • 使用 location.href=’/url’来跳转,简单方便,但是刷新了页面;

  • 使用 history.pushState(‘/url’),无刷新页面,静态跳转;

    引进 router,然后使用 router.push(‘/url’) 来跳转,使用了 diff 算法,实现了按需加载,减少了 dom 的消耗。其实使用 router 跳转和使用 history.pushState() 没什么差别的,因为 vue-router 就是用了history.pushState(),尤其是在 history 模式下

7):route 和 router 的区别是什么

  • route:是“路由信息对象”,包括 path, params, hash, query, fullPath, matched, name等路由信息参数。
  • router:是“路由实例对象”,包括了路由的跳转方法(push、replace),钩子函数等。

8):Vue slot

  • 简单来说,假如父组件需要在子组件内放一些 DOM,那么这些 DOM 是显示、不显示、在哪个地方显示、如何显示,就是 slot 分发负责的活。

9):vue 项目是打包了一个 js 文件,一个 css 文件,还是有多个文件

  • 定义:根据vue-cli 脚手架规范,一个js文件,一个css文件。

10):router-link电脑上有用,在安卓上没反应解决

  • 定义:Vue 路由在 Android 机上有问题,babel 问题,安装 babel polypill 插件解决。

11):Vue2中注册在router-link上事件无效解决

  • 定义:使用@click.navtive。router-link会组织click事件,native指直接监听一个原生事件。

12):RouterLink在IE和Firefox中不起作用(路由不跳转)的问题

  • 方法一:只用a标签,不适用button标签;
  • 方法二:使用button标签和Router.navigate方法

13):axios的特点有哪些

  • 从浏览器中创建XMLHttpRequests;
  • node.js 创建http请求;
  • 支持Promise API;
  • 拦截请求和响应;
  • 转换请求数据和响应数据;
  • 取消请求;
  • 自动换成JSON;
  • axios中发送字段的参数是data跟params两个,两者的区别在于params是跟请求地址一起发送,data的作为一个请求进行发送 params一般适用于get请求,data一般使用post请求

14):请说下封装 vue 组件的过程?

  1. 建立组件的模板,先把架子搭起来,写样式,考虑好组件的基本逻辑。(os:思考 1 小时,码码 10 分钟,程序猿的准则。)
  2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。(父传子)
  3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。(传入的方法等)
  4. 封装完毕了,直接调用即可

15):params 和 query 的区别

  • 用法:query要用path来引入;params要用name来引入。接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。
  • url 地址显示:query 更加类似于我们 ajax 中 get 传参,params 则类似于 post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
  • 注意点:query刷新不会丢失query里面的数据,params刷新会丢失params里面的数据

16):vue初始化页面闪动问题

  • 使用 vue 开发时,在 vue 初始化之前,由于 div 是不归 vue 管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于 的字样(在css加入以👇)

    [v-colok]{
        display: none;
    }
  • 如果没有彻底解决问题,则在根元素加上

    style="display: none;" :style="{display:'block'}"

17):vue 更新数组时触发视图更新的方法

  • push();pop();shift();unshift();splice(); sort();reverse()

五:vue 首屏加载优化

  1. 把不常改变的库放到 index.html 中,通过 cdn 引入

  2. 然后找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加以下代码

    externals{
    'vue':'Vue',
    'vue-router':'VueRouter',
    'element-ui':'ELEMENT'
    }

六:vue 常用的 UI 组件库

  • Mint UI,element,VUX、iView、Bootstrap-Vue、Ant Design Vue、AT-UI、Vant、cube-ui、Muse-UI

七:Vue的生命周期

  • beforeCreate、created、beforeMount、mounted、beforeUpdate、update、beforeDestory、destroyed(创建、挂载、更新、卸载)

    beforeCreate 组件实例被创建之初,组件的属性生效之前
    created 组件实例已经完全创建,属性也绑定,但真实dom还没有生成,$el还不可用
    beforeMount 在挂载开始之前被调用;相关的render函数首次被调用
    mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子
    beforeUpdate 组件数据更新之前调用,发生在虚拟dom打补丁之前
    update 组件数据更新之后
    activited keep-alive专属,组件被激活时调用
    deadactivated keep-alive专属,组件被销毁时调用
    beforeDestory 组件销毁前调用
    destoryed 组件销毁后调用
    • 挂载中可以操作DOM、创建中不能操作DOM;常用挂载或者创建生命周期就行了。

八:虚拟DOM和DIFF算法

  • 将DOM抽象为虚拟DOM,然后通过新旧虚拟DOM 这两个对象的产生一(DIFF算法),最终只把变化的的部分,重新渲染,提高渲染效率的过程;
  • diff是通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染。

九:vue2和vue3原理

  1. vue2和vue3双向数据绑定原理发生了变化
  2. vue2的双向数据绑定是立勇ES5的一个API Object.definePropert()对数据进行劫持 集合 发订阅模式的方式来实现的
  3. vue3中使用ES6的ProxyAPI对数据代理
  4. 相对于vue2.x,使用proxy的优势如下
  5. defineProperty只能监听某个属性,不能对全对象监听
  6. 可以省去for in、闭包等内容来提高效率(直接绑定整个对象即可)
  7. 默认进行懒观察(lazy observation)
  8. 在2.x版本里,不管数据多大,都会在一开始就为起床也观察者,当数据很大时,这可能会在页面载入是造成的性能压力。3.0版本,只会对【被用于渲染初始可见部分的数据】创建观察者,而且3.x的观察者更高效
  9. vue3更精准的变更通知
  10. 比例来说:2.x版本中,使用Vue.set来给对象新增一个属性是,这个对象的所有watcher都会运行;3.x版本中,只有依赖那个属性的watcher才会重新运行
  11. vue3新加入TypeScript以及PWA的支持

十:vue-router的动态路由,获取动态参数

  • 可以通过query,param两种方式。query通过url传参,刷新页面还在,params刷新页面不在了
  1. params的类型:

    • 配置路由格式:/router/:id
    • 传递的方式:在path后面跟上对应的值
    • 传递后形成的路径:/router/123
  2. query的类类型

    • 配置路由格式:/router,也就是普通配置
    • 传递的方式:对象中使用query的key作为传递方式
    • 传递后形成的路径:/route?id=123

十一:vue中如何定义一个全局变量

  1. 只读的全局变量

    import Vue from 'vue ';
    1et MyComm = new Vue({
    methods: {
    deleteCookie: function (cname) {
    1et d = new Date();
    let expires = "expires=" + d.toGMTString();
    document. cookie = cname + "=;" + expires;
    }
    })
    export default MyComm;
    1.2) 引用
    import MyComm from " . / components/ common/ comm" ;
    MyComm. . deleteCookie(' ms_ username ')
  2. 只读的全局变量

    new Vue({
        router,
        data: function(){
            return {
                URL: 'http://localhost:8080',
            }
        },
        render: h => h(App)
    }).$mount('#app');

十二:Vue路由两种模式的区别、钩子函数、动态路由

  1. 两种模式:hash模式;history路由模式
  2. 钩子函数
    • 全局前置守卫 router.beforeEach
    • 全局解析守卫 router.beforeResolve
    • 全局后置钩子 router.afterEach
    • 路由独享的守卫 beforeEnter
    • 组件内的守卫 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
  3. 动态路由
    • 前端把路由写好,登录的时候根据用户的角色权限来动态展示路由,(前端控制路由)
    • 后台接口提供当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由)

十三:生命周期钩子的一些使用方法

  1. beforecreate:可以在加个loading事件,在加载实例是触发基于源数据多次渲染元素或模板

  2. created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用

  3. mounted:挂载元素,获取到dom节点

  4. updated:如果对数据统一处理,在这里写上相应函数

  5. beforeDestroy:可以一个确认停止事件的确认框

  6. nextTick:更新数据后立即操作dom


文章作者: Ponzio
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ponzio !
  目录