精华内容
下载资源
问答
  • 常见vue面试题
    2022-03-13 19:23:48

    一、vue父子组件之间的传值:

    简单来说,子组件通过props方法接受父组件传来的值,子组件通过$emit方法来向父组件发送数据

    二、vue生命周期函数:

    Vue的生命周期
    	从开始创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载等一系列过程
    	beforeCreate 创建前
    	created    创建后
    	beforeMount   挂载之前
    	mounted   挂载完成
    	beforeUpdate	数据更新之前
    	updated   更新之后
    	beforeDestroy   销毁前
    	destroyed   销毁后

    三、vue自定义指令:

    1.创建局部指令
    vue app = new Vue({
    	el:'#app',
    	data:{}
    	创建指令(可以多个)
    	directives:{
    		//指令名称
    		dirl:{
    			inserted(el){
    				//指令中第一个参数是当前使用指令的DOM	
    				console.log(el)
    				console.log(arguments)
    				对DOM进行操作
    				el.style.width = '200px',;
    				el.style.height = '200px';
    				el.style.background='#000';
    			}
    		}
    	}
    })
    2.全局指令
    Vue.directive('dir2',{
    	inserted(el){
    		console.log(el)
    	}
    })
    
    3.指令的使用
    <div id='app>
    	<div v-dir1></div>
    	<div v-dir2></div>
    </div>

     四、MVVM定义:

    MVVM是Model-View-ViewModel的简写。即模型-视图-视图模型。【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。总结:在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信

    五、vue中methods和computed有什么区别?应用场景如何?

    1.methods:方法,函数,绑定事件调用;不会使用缓存
    2.computed: 计算属性   本质是方法,使用时可以像属性一样使用,
    当操作的值没有发生改变时,会使用缓存,当值发生改变,才会改变;提高速度

    六、什么是js的冒泡?Vue中如何阻止冒泡事件?

    js冒泡概念:当父元素内多级子元素绑定了同一个事件
    ,js会依次从内往外或者从外往内(?)执行每个元素的该事件,从而引发冒泡
        
        js解决冒泡:event.stopPropagation()
        vue解决冒泡: 事件.stop,例如:@click.stop="" ,@mouseover.stop=""

     七、什么是js的回调地狱?为什么会引发回调地狱?如何解决回调地狱问题

    js的回调地狱:根据外层ajax请求的结果,将结果作为参数继续发起ajax请求
         --->引起回调地狱
        getA().then(res=>{
            getB(res.data.a).then(res=>{
    	    getC(res.data.b).then(res=>{
                   //....回调地狱
                })	
    	})
        })
        
        Promise 对象就是为了解决这个问题而提出的。
        它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,改成链式调用。 
    
      getA().then(res=>{
    		return   getB(res.data.a)
    }).then(res=>{
    	//.....链式调用
    })

     八、说说你对前后端分离的开发模式的理解

    1.前端静态化
    前端有且仅有静态内容,再明确些,只有HTML/CSS/JS. 
    其内容来自于完全静态的资源而不需要任何后台技术进行动态化组装.
    前端内容的运行环境和引擎完全基于浏览器本身.
    
    2.后端数据化
    
    后端可以用任何语言,技术和平台实现,但它们必须遵循一个原则
         :只提供数据,不提供任何和界面表现有关的内容.
    
    3.平台无关化
    
    前端3大技术本身就是平台无关的,而后台连接部分的本质是实现合适的Restful接口和交互Json数据,就这2者而言,
    任何技术和平台都可以实现.
    
    4.构架分离化
    
    后端构架几乎可以基于任何语言和平台的任何解决方案,
    大型构架方面, RestTful Api可以考虑负载均衡;而数据,
    业务实现等可以考虑数据库优化和分布式 
    但总而言之,前后端的分离 也实现了 前后端构架的分离.

    九、 Vue 2 中给 data 中的对象属性添加一个新的属性时会发生什么?如何解决?

     视图并未刷新。这是因为在Vue实例创建时,新属性并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局 api s e t ( ) : ‘ t h i s . set():`this.set():‘this.set(this.obj, ‘new_property’, ‘new_value’)`

    十、sass是什么?如何在vue中安装和使用?

    1. 用npm安装加载程序( sass-loader、 css-loader等加载程序)。
    2. 在 webpack.config.js中配置sass加载程序。

    十一 、vue 的 nextTick 方法的实现原理:

    1. vue 用异步队列的方式来控制 DOM 更新和 nextTick 回调先后执行
    2. microtask 因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕

    十二 、Vue 组件 data 为什么必须是函数 ? 

    因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染。
    所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。

    十三、vue常用指令:

    v-model 多用于表单元素实现双向数据绑定(同angular中的ng-model)
    v-bind 动态绑定 作用: 及时对页面的数据进行更改
    v-on:click 给标签绑定函数,可以缩写为@,例如绑定一个点击函数 函数必须写在methods里面
    v-for 格式: v-for=“字段名 in(of) 数组json” 循环数组或json(同angular中的ng-repeat)
    v-show 显示内容 (同angular中的ng-show)
    v-hide 隐藏内容(同angular中的ng-hide)
    v-if 显示与隐藏 (dom元素的删除添加 同angular中的ng-if 默认值为false)
    v-else-if 必须和v-if连用
    v-else 必须和v-if连用 不能单独使用 否则报错 模板编译错误
    v-text 解析文本
    v-html 解析html标签
    v-bind:class 三种绑定方法 1、对象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、数组型 ‘[{red:“isred”},{blue:“isblue”}]’
    v-once 进入页面时 只渲染一次 不在进行渲染
    v-cloak 防止闪烁
    v-pre 把标签内部的元素原位输出

    十四、keep-alive是什么?

    如果需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。

    两个重要属性,include 缓存组件名称,exclude 不需要缓存的组件名称。

    十五、vuex的核心概念:

    1. state => 基本数据
    2. getters => 从基本数据派生的数据
    3. mutations => 修改数据,同步
    4. actions => 修改数据,异步 (Action 提交的是 mutation,而不是直接变更状态)
    5. modules => 模块化Vuex

    十六、 vuex是什么?怎么使用?哪种功能场景使用它?

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理器,采用集中式存储管理应用的所有组件的状态,主要是为了多页面、多组件之间的通信。
    Vuex有5个重要的属性,分别是 State、Getter、Mutation、Action、Module,由 view 层发起一个 Action 给 Mutation,在 Mutation 中修改状态,返回新的状态,通过 Getter暴露给 view层的组件或者页面,页面监测到状态改变于是更新页面。如果你的项目很简单,最好不要使用 Vuex,对于大型项目,Vuex 能够更好的帮助我们管理组件外部的状态,一般可以运用在购物车、登录状态、播放等场景中 

    十七、vue-router路由的两种模式:

    1. hash模式, 带#。如:http://localhost:8080/#/pageA。改变hash,浏览器本身不会有任何请求服务器动作的,但是页面状态和url已经关联起来了。
    2. history模式,不带#, 如:http://localhost:8080/ 正常的而路径,并没有#。基于HTML5的 pushState、replaceState实现

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

    1. 全局导航钩子:router.beforeEach(to,from,next)
    2. 组件内的钩子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)
    3. 单独路由独享组件 beforeEnter: (to, from, next)

    十九、route和router的区别:

    1. $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
    2. $router是“路由实例”对象包括了路由的跳转方法,钩子函数等

    二十、路由之间跳转的方式:

    1. 声明式(标签跳转)
    2. 编程式( js跳转)
    更多相关内容
  • 常见vue面试题

    2020-11-17 10:39:58
    3 常见的实现MVVM数据绑定的做法有哪些? 实现数据绑定的做法有大致如下几种: 发布者-订阅者模式(backbone.js) 脏值检查(angular.js) 数据劫持(vue.js) 1、发布者-订阅者模式: 一般通过sub, pub的方式实现...

    1 . MVC、MVP与MVVM模式

    MVC:

    MVC是应用最广泛的软件架构之一,一般MVC分为:

    Model( 模型 )Controller( 控制器 )View( 视图 )

    这主要是基于分层的目的,让彼此的职责分开。View 一般通过 Controller 来和 Model 进行联系。ControllerModelView 的协调者,ViewModel不直接联系。基本联系都是单向的。

    img

    1、View 传送指令到 Controller
    2、Controller 完成业务逻辑后,要求 Model 改变状态
    3、Model 将新的数据发送到 View,用户得到反馈

    MVP:

    MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。
    img

    1、各部分之间的通信,都是双向的。
    2、View 与 Model 不发生联系,都通过 Presenter 传递。
    3、View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

    MVVM

    MVVM 是把 MVCControllerMVPPresenter 改成了 ViewModel

    View 的变化会自动更新到 ViewModelViewModel 的变化也会自动同步到 View上显示。这种自动同步是因为 ViewModel 中的属性实现了 Observer,当属性变更时都能触发对应的操作。
    img

    img

    2 MVVM模式的优点以及与MVC模式的区别

    MVVM模式的优点:

    1、低耦合:视图(View)可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

    2、可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多 view 重用这段视图逻辑。

    3、独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

    4、可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

    MVVM 和 MVC 的区别:

    mvcmvvm 其实区别并不大。都是一种设计思想。

    主要区别

    • mvc 中 Controller演变成 mvvm 中的 viewModel,

    • mvvm 通过数据来显示视图层而不是节点操作。

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

    3 常见的实现MVVM数据绑定的做法有哪些?

    实现数据绑定的做法有大致如下几种:

    发布者-订阅者模式(backbone.js)
    脏值检查(angular.js)
    数据劫持(vue.js)

    1、发布者-订阅者模式:


    一般通过sub, pub的方式实现数据和视图的绑定监听,
    更新数据方式通常做法是 vm.set('property', value)

    这种方式现在毕竟太low了,我们更希望通过 vm.property = value这种方式更新数据,同时自动更新视图,于是有了下面两种方式。


    2、脏值检查:


    angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,

    最简单的方式就是通过 setInterval() 定时轮询检测数据变动,

    angular只有在指定的事件触发时进入脏值检测,大致如下:

    1、DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
    
    2、XHR响应事件 ( $http )
    
    3、浏览器Location变更事件 ( $location )
    
    4、Timer事件( $timeout , $interval )
    
    5、执行 $digest() 或 $apply()
    

    3、数据劫持:


    vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,

    通过Object.defineProperty()来劫持各个属性的settergetter

    在数据变动时发布消息给订阅者,触发相应的监听回调。

    4 Object.defineProperty()方法的作用是什么?

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

    语法:

    Object.defineProperty(obj, prop, descriptor)
    

    参数说明:

    obj:必需。目标对象 
    prop:必需。需定义或修改的属性的名字
    descriptor:必需。目标属性所拥有的特性
    

    返回值:

    传入函数的对象。即第一个参数obj
    

    针对属性,我们可以给这个属性设置一些特性,比如是否只读不可以写;是否可以被for…in或Object.keys()遍历。

    给对象的属性添加特性描述,目前提供两种形式:数据描述和存取器描述。

    5 vue.js的两个核心是什么?

    1、数据驱动,也叫双向数据绑定。

    Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProperty和存储器属性: getter和setter(所以只兼容IE9及以上版本),可称为基于依赖收集的观测机制。核心是VM,即ViewModel,保证数据和视图的一致性。

    2、组件系统。

    .vue组件的核心选项:

    1、模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。
    2、初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。
    3、接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。
    4、方法(methods):对数据的改动操作一般都在组件的方法内进行。
    5、生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。
    6、私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。
    等等。

    6 请详细说下你对vue生命周期的理解?

    6.1 什么是vue生命周期?

    Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

    6.2 vue生命周期钩子函数都有哪些?分别是什么意思?
    • 组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作

    • 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

    • 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…

    • 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿

    • 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom

    • 经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等,组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以

    如果觉得上面的太长,也可以如下回答:

    ​ 总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

    ​ 创建前/后: 在beforeCreated阶段,vue实例的挂载元素el还没有。在created阶段,vue实例的数据对象data有了,el还没有.

    ​ 载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

    ​ 更新前/后:当data变化时,会触发beforeUpdate和updated方法。

    ​ 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

    6.3 vue生命周期的作用是什么?

    生命周期中有多个事件钩子,让我们在控制整个 vue 实例的过程时更容易形成好的逻辑

    6.4 第一次页面加载会触发哪几个钩子?

    第一次加载会触发 beforeCreate、created、beforeMount、mounted

    6.5 简述每个周期具体适合哪些场景?

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

    • beforecreate : 可以在这加个loading事件,在加载实例时触发

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

    • mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数

    • beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom

    6.6 created和mounted的区别?
    • created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。

    • mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

    6.7 vue获取数据在哪个周期函数?
    • 看实际情况,一般在 created(或beforeRouter) 里面就可以,如果涉及到需要页面加载完成之后的话就用 mounted。

    • 在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素

    • 而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点,(此时document.getelementById 即可生效了)

    7 说一下你对vue路由的理解吧

    7.1 什么是vue路由?

    “Vue路由就是指vue-router,其中router是指根据url分配到对应的处理程序,所以说路由就是用来解析URL以及调用对应的控制器并返回从视图对象中提取好的网页代码给web服务器,最终返回给客户端。

    7.2 vue路由的优点以及缺点是什么?
    • 优点:

      • 不需要每次都从服务器获取,渲染页面更快速
    • 缺点:

      • 不利于SEO
      • 使用浏览器前进、后退按键时重新发送请求,未合理利用缓存
      • 单页面无法记住之前滚动的位置
    7.3 请简单说一下vue路由的原理?

    Vue的路由实现:hash模式 和 history模式

    • hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;

    • 特点:

      • hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
      • hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
    • history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

    • 特点:

      • history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
    7.4 怎么定义 vue-router 的动态路由?如何获取动态路由传过来的值?
    • 定义动态路由:

      • 在 router 目录下的 index.js 文件中,对 path 属性加上 /:id。
    • 获取动态路由传过来的值:

      • 使用 router 对象的 params.id 获取
    //全局获取动态路由传递过来的值
    $route.params.id
    //局部或者是在方法内获取
    this.$route.params.id
    
    7.5 请描述vue-router路由守卫的作用?

    vue-router 的导航钩子,主要用来作用是拦截导航,让他完成跳转或取消。

    7.6 路由守卫使用的方式有几种?
    • 全局的

    • 单个路由独享的

    • 组件级的

    7.7 路由守卫的钩子函数都有哪些?分别是什么意思?
    • vue-router全局有三个守卫:

      • router.beforeEach 全局前置守卫 进入路由之前
      • router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
      • router.afterEach 全局后置钩子 进入路由之后
    • 组件内的守卫:

      • beforeRouteEnter
      • beforeRouteUpdata(2.2新增)
      • beforeRouteLeave
    7.8 路由守卫钩子函数里面的三个参数分别是什么?
    • to,from,next 这三个参数:

      • to和from是将要进入和将要离开的路由对象,路由对象指的是平时通过this.$route获取到的路由对象。
      • next:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)。
        • next() 进入该路由。
        • next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。
        • next 跳转新路由,当前的导航被中断,重新开始一个新的导航。
    • 我们可以这样跳转:next(‘path地址’)或者next({path:’’})或者next({name:’’})

    • 且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及你用在router-link或router.push的对象选项。

    7.9 路由守卫的解析流程?
    • 导航被触发
    • 在失活的组件里调用离开守卫
    • 调用全局的 beforeEach 守卫
    • 在重用的组件里调用 beforeRouteUpdate 守卫
    • 在路由配置里调用 beforEnter
    • 解析异步路由组件
    • 在被激活的组件里调用 beforeRouteEnter
    • 调用全局的 beforeResolve 守卫
    • 导航被确认
    • 调用全局的 afterEach 钩子
    • 触发 DOM 更新
    • 在创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数
    7.10 vue-router路由传参的方式一共有几种?他们是如何就收传递过来的参数?
    • 三种:

      • 分别是query,params,动态路由传参
    • 接收:

      • 通过query方式传递过来的参数一般是通过this.$route.query接收
      • 通过params方式传递过来的参数一般是通过this.$route.params接收
      • 通过动态路由传参方式传递过来的参数一般是通过this.$route.params接收
    7.11 query传参和params方式的区别是什么?
    • query使用path和name传参跳转都可以,而params只能使用name传参跳转。

    • 传参跳转页面时,query不需要再路由上配参数就能在新的页面获取到参数,params也可以不用配,但是params不在路由配参数的话,当用户刷新当前页面的时候,参数就会消失。

    • 也就是说使用params不在路由配参数跳转,只有第一次进入页面参数有效,刷新页面参数就会消失。

    7.12 什么是路由懒加载?以及路由懒加载是如何实现的?
    • 按需加载
    • 当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
    • 结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

    8 说一下你对vuex的理解?

    8.1 什么是vuex?
    • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    • 我的个人理解是vuex其实就是一个管理数据的工具,通过vuex我们可以解决组件之间数据共享的问题,后期也方便我们管理以及维护

    8.2 vuex的优点和缺点是什么?
    • 优点:

      • 解决了非父子组件的消息传递(将数据存放在state中)
      • 减少了AJAX请求次数,有些情景可以直接从内存中的state获取
      • 数据方便管理以及维护
    • 缺点:

      • 小型项目使用的话,vuex会显得有点繁琐冗余
      • 刷新浏览器,vuex中的state会重新变为初始状态,我们如何要解决这个问题就可能需要用本地存储或者vuex的一个插件
    8.3 一般什么情况下使用 vuex?
    • 官方说的是在大型项目中推荐使用vuex,但是我个人的理解是当页面的组件比较多,业务比较复杂时,数据难以维护,这个时候我一般会使用vuex
    8.4 vuex的原理是什么?
    • 每个Vuex应用的本质是store(仓库),包含应用中大部分的状态。

    • state, getters,mutations,actions,module

    8.5 请你说一下vuex的用法?
    • 安装vuex

    • 在src目录下创建store文件夹,在该文件夹内创建index.js

    • 在store文件夹内的index.js文件内引入vuex

    • 然后在引入vue

    • 调用Vue.use()方法注册vuex

    • 对vuex进行实例化

    • 进行实例化之后通过export default导出

    • 在main.js文件内引入store文件夹内的index.js文件

    • 挂载到new Vue实例上面

    • 初始化vuex的状态和属性

    8.6 你在项目中哪些地方用到了vuex?
    • 登录模块,购物车模块,订单模块,商品模块。。。。
    8.7 vuex的运行机制什么?
    • 在vue组件里面,通过dispatch来触发actions提交修改数据的操作。

    • 然后再通过actions的commit来触发mutations来修改数据。

    • mutations接收到commit的请求,就会自动通过Mutate来修改state(数据中心里面的数据状态)里面的数据。

    最后由store触发每一个调用它的组件的更新

    8.8 vuex都有哪些属性?
    • State、Getter、Mutation 、Action、Module 五种
      • state => 基本数据
      • getters => 从基本数据派生的数据
      • mutations => 提交更改数据的方法,同步!
      • actions => 像一个装饰器,包裹mutations,使之可以异步。
      • modules => 模块化Vuex
    8.9 你是如何获取state的值,如何调用gettes里面定义的方法?如何调用mutations的方法?如何调用actions的方法?
    • state的值获取的方式有两种:
      • 第一种是组件里面进行获取 this.$store.state.状态
      • 第二种是在vuex内部进行获取
        • 函数参数里面会有一个state参数,通过这个state参数我们可以直接拿到state的值
        • getters的方法在组件内调用的话是通过this.$store.getters来进行获取,而getters的作用一般是用来获取state的值
        • mutations的方法在组件内调用时一般是通过this.$store.commit()来进行调用,而mutations的作用一般是用来改变state里面状态,只不过通过同步的方式去改变
        • actions的方法在组件内调用的话是通过this.$store.dispatch()来进行调用,而actions的作用一般是用来异步的改变状态,actions也支持promise
    8.10 vuex里面module属性的作用是什么?
    • module属性相当于是vuex里面的模块化方法,module属性可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
    • 比如:购物车模块,订单模块,商品模块…每个模块都有自己的数据,建立多个模块文件来保存各自对应模块的数据,最后,在module属性里面进行合并
    8.11 不使用vuex会带来什么问题?
    • 可维护性会下降,想修改数据要维护三个地方;
    • 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
    • 增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背
    8.12 Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
    • 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
    • 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。
    8.13 Vuex中如何异步修改状态?

    actions去异步的改变state的状态,mutations是同步改变状态,调用actions内定义的方法,需要通过this. s t o r e . d i s p a t c h ( ) , m u t a t i o n s 方 法 是 通 过 t h i s . store.dispatch(),mutations方法是通过this. store.dispatch(),mutationsthis.store.commit()来进行调用,而在actions要调用mutations的方法,通过commit来进行调用

    8.14 Vuex中actions和mutations的区别?
    • Action 提交的是 mutation,而不是直接变更状态。
    • Action 可以包含任意异步操作
    • mutations只能是同步操作
    8.15 页面刷新后vuex的state数据丢失怎么解决?

    localStorage 或者就是sessionStorage ,或者借用辅助插vuex-persistedstate

    8.16 vuex怎么知道state是通过mutation修改还是外部直接修改的?

    通过$watch监听mutation的commit函数中_committing是否为true

    9 请你说一下你对vue组件通信的理解?

    vue组件的通信是为了解决组件之间数据传递的问题,分为

    • 父子组件之间的通信

    • 非父子组件的通信

    10 父组件如何与子组件怎么通信?

    • 父组件将数据绑定在子组件上
    • 子组件通过props属性来进行接收,props的接收方式有两种,分别是数组的方式接收,以及对象的方式接收,他们两个的不同是对象接收的方式可以设置默认值以及传递过来的类型

    11 子组件如何与父组件进行通信?

    • 在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了

    12 非父子组件之间如何进行通信?

    • 非父子组件之间通信我们可以使用vuex或者event bus,而这个event bus我们把它称之为中央时间总线,vue中央事件总线这种方法适用于任何情况的父子组件通信,同级别组件通信,相当于组件通信间的万金油。但是碰到多人合作时,代码的维护性较低,代码可读性低(这个缺点可以忽略)。

    15 除了组件之间的这种通信方式以外,还是什么方式可以让组件的数据进行共享?

    ​ 路由,vuex,本地存储

    16 props接收父组件发送过来的数据有几种形式?

    • 两种,一种是数组,另外一种是对象

    17 非父子组件之间通信的原理是什么?

    • 非父子组件之间通信我们一般使用event bus,中央时间总线来进行解决,而中央事件总线的鱼哪里是通过vue实例化之后的对象调用bus.emit来进行数据的发送,通过bus.$on来进行接收

    18 请描述vue的优点是什么?缺点是什么?

    • vue的优点:
      • 简单易用
      • 灵活渐进式
      • 轻量高效
        • 压索之后20KB大小
        • 虚拟DOM
      • MVVM
        • 数据驱动视图
        • 常规的操作方式都是DOM
        • 普通的javascript数据
      • 组件化
        • 组件化优点
          • 提高开发效率
          • 方便重复使用
          • 简化调试步骤
          • 提升整个项目的可维护性
          • 便于协同开发
    • vue的缺点:
      • VUE不支持IE8

    19 请你描述一下vue中让元素隐藏的方式有几种?区别是什么?

    • v-show v-if
      • 共同点:
        • v-ifv-show 都是动态显示DOM元素。
      • 区别
        • 编译过程: v-if 是 真正 的 条件渲染,因为它会确保在切换过程中条件块内的事件监听器子组件适当地被销毁重建v-show 的元素始终会被渲染并保留在 DOM 中v-show 只是简单地切换元素的 CSS 属性display
        • 编译条件: v-if 是惰性的:如果在初始渲染时条件为假,则什么也不做。直到条件第一次变为真时,才会开始渲染条件块。v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换
        • 性能消耗:v-if有更高的切换消耗。v-show有更高的初始渲染消耗`。
        • 应用场景: v-if适合运行时条件很少改变时使用。v-show适合频繁切换

    20 你在vue中怎么样让你写的css样式只在你当前写的组件中显示?

    21 请你说一下keep-alive?你在哪些地方用过它?

    • keep-alive:主要用于保留组件状态避免重新渲染
    • 比如: 有一个列表页面和一个 详情页面,那么用户就会经常执行打开详情=>返回列表=>打开详情这样的话 列表 和 详情 都是一个频率很高的页面,那么就可以对列表组件使用``进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

    22 请你说一下在vue中如何获取dom元素?

    ref

    23 请你说一下vue中常用的指令有哪些?

    `v-bind,v-if,v-show,v-model等等

    24 请你说一下为什么使用key?

    • key值:用于 管理可复用的元素。因为Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue 变得非常快,但是这样也不总是符合实际需求。

    25 说一下你对axios的理解?

    • 什么是axios?

    • axios一般什么时候用?

    • 使用场景?

    • 使用的时候遇到过什么问题?

    26 说一下axios如何解决跨域?

    vue使用反向代理

    27 请描述v-model是什么?以及他的作用?以及他的原理是什么?

    • v-model就是vue的双向绑定的指令,能将页面上控件输入的值同步更新到相关绑定的data属性,也会在更新data绑定属性时候,更新页面上输入控件的值
    • v-model主要提供了两个功能,view层输入值影响data的属性值,data属性值发生改变会更新view层的数值变化

    28 请描述computed,watch和methods的区别?以及他们的使用场景?

    computed是计算属性,有缓存性,当属性发生变化的时候才会执行,watch是监听,没有缓存,依赖于data,当data发生变化的时候才会执行,methods是方法,没有缓存,只要调用就会执行
    `

    29 请你描述一下你对$nextTick的理解?

    • nextTick是vue里面提供的一个方法,当dom更新循环结束之后执行延迟回调,在修改数据之后可以使用 nextTick,那么我们可以在回调中获取更新后的dom,我们写项目的时候,当时点击按钮要获取一个元素的内容,但是发现了第二次点击的时候才回去到了,后台在网上查了一下,发现是vue异步更新队列的问题,后来是通过$nextTick解决的

    30 说一下你对渐进式框架的理解?

    • 就是主张最少,可以只用一部分功能,而不必使用全部,而且可以跟其他框架结合使用,

      没有多做职责之外的事

    31 说一下你对vue数据双向绑定的理解?

    • 就是利用了Object.defineProperty()这个方法重新定义了对象获取属性get和设置属性set来操作实现的

    32 说一下vue单页面和多页面的区别?

    • 单页面就是组件之间来回跳转,跳转速度快,不需要请求数据 缺点:首屏加载慢,跳转快
    • 多页面就是页面之间来回跳转,跳转速度慢,每次跳转都需要向后台请求数据 缺点:首屏加载快,跳转速度慢

    33 请你说一下什么是vue的过滤器?你在项目中哪些地方使用过过滤器?

    你可以在一个组件的选项中定义本地的过滤器:

    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }
    

    或者在创建 Vue 实例之前全局定义过滤器:

    Vue.filter('capitalize', function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    })
    
    new Vue({
      // ...
    })
    

    34 请你说一下你对vue指令的理解?以及他的使用场景? 并描述你在项目中那些地方使用过vue自定义指令?

    自定义指令:使用Vue.directive(id,definition)注册全局自定义指令,使用组件的directives选项注册局部自定义指令。
    钩子函数:
    bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

    update:第一次是紧跟在 bind 之后调用,获得的参数是绑定的初始值,之后被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

    componentUpdated:被绑定元素所在模板完成一次更新周期时调用。

    unbind:只调用一次, 指令与元素解绑时调用。
    钩子函数的参数:(el, binding, vnode, oldVnode)

    35 请你说一下vue的核心是什么?

    • vue的核心是:数据驱动,组件化开发
      • 数据驱动:
        • mvvm模式
      • 组件化开发:
      • 就是内聚性和藕合度(高内聚,低藕合)

    36 请你说一下vue和jquery的区别?

    • jquery是直接操作DOM的而vue是操作数据的

    • vue做到了数据和视图完全分离,他首先把值和JS对象进行绑定,然后在修改JS对象的值,vue框架就会自动把DOM的值进行更新,对数据进行操作不在需要引用相应的DOM对象,他们通过Vue对象实现数据和视图的相互绑定

    • jquery则是先使用选择器($)来选取Dom对象,然后对Dom对象进行操作(如赋值丶取值丶事件绑定等)

    37 请你说一下你在vue打包项目的时候有没有出现什么问题?你是如何解决的?

    打包后文件无法读取
    在config.js中设置module.exports = {
    publicPath: ‘./’,
    }

    38 请你描述一下react和vue的区别是什么?

    1、react严格上针对的是mvc模式的view层,vue则是mvvm模式。
    2、操作dom的方式不同,vue使用的是指令操作dom,react是通过js进行操作。
    3、数据绑定不同,vue实现的是双向绑定,react的数据流动是单向的。
    4、react中state是不能直接改变的,需要使用setState改变。vue中的state不是必须的,数据主要是由data属性在vue对象中管理的。

    39 请你说一下如何优化vue首屏加载的速度?

    图片懒加载,路由懒加载等等

    40 请你说一下你对slot的理解?

    插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制

    41 请你描述一下封装vue组件的过程?

    就是将重复使用的代码放在组件中,通过传参或插槽的形式实现复用

    42 如果说你在开发项目的时候,后台的接口还没有写完,请问这个时候你一般会怎么做

    模拟数据进行功能的编写

    43 vue如何封装通用组件?

    就是将重复使用的代码放在组件中,通过传参或插槽的形式实现复用

    44 vue常用的ui组件库有哪些?

    element-ui vant

    45 vue常用的修饰符一共有哪些?

    .stop,.once,.prevent等等

    46 请你说一下ajax和axios的区别是什么?

    ajax是原生的异步方法,axios是封装后的方法,比ajax更加简便,同时可以避免地狱回掉问题

    47 vue组件如何适配移动端?

    rem,vw\vh

    48 说一下在vue中如何使用背景图片?

    正常的CSS中的方法

    49 如何解决禁用表单后移动端样式不统一问题?

    input:disabled{
    color:xxx;
    opacity:1;
    //text-fill-color文本填充颜色,只兼容webkit内核
    -webkit-text-fill-color:xxx;
    -webkit-opacity:1;
    font-size:16px;
    }

    50 请你说一下数据双向绑定的原理是什么?

    使用v-model来实现
    Vue 实现 双向数据绑定 主要采用:数据劫持结合“发布-订阅”模式的方式,通过Object.defineProperty()的 set 和 get,在数据变动时发布消息给订阅者触发监听。

    51 什么是请求拦截,什么响应拦截? 拦截点分别是那几个?

    当客户端向服务器发送数据的时候就是请求,当服务器向客户端发送数据就是响应,那么请求拦截和响应拦截分别是在发送数据前进行拦截还有是在接受数据没有渲染到页面时候进行拦截,拦截点2个。

    展开全文
  • Vue常见面试题及网友回答,收集来自阿里云社区,包括v-model, key, methods,错误处理,参数传递,父子组件,定时器,vue声明周期等问题
  • 经典面试题: 2021Vue经典面试题总结(含答案).pdf
  • vue常见面试题

    2022-05-17 16:16:43
    2、VUE中为什么data是一个函数 - 组件的data写成一个函数,数据以函数返回值形式定义 - 每复用一次组件,就会返回一分新的data,让各个组件实例维护各自的数据。 3、Vue组件通讯有哪些方式? - props 和 emit。父...

    1、MVVM与MVC最大的区别
    - 实现了View和Model的自动同步,当Model的属性改变时,该属性对应的View层显示会自动改变
    - 简化了业务与界面的依赖,解决了数据频繁更新的问题,不用使用选择器操作DOM元素

    2、VUE中为什么data是一个函数
    - 组件的data写成一个函数,数据以函数返回值形式定义
    - 每复用一次组件,就会返回一分新的data,让各个组件实例维护各自的数据。

    3、Vue组件通讯有哪些方式?
    - props 和 e m i t 。 父 组 件 向 子 组 件 传 递 数 据 是 通 过 p r o p s 传 递 的 , 子 组 件 传 递 给 父 组 件 是 通 过 emit。父组件向子组件传递数据是通过props传递的,子组件传递给父组件是通过 emitpropsemit触发事件来做到的。
    - $parent 和 $children 获取单签组件的父组件和当前组件的子组件。
    - $refs 获取组件实例
    - vuex 状态管理(实现不同组件之前的数据共享)

    4、Vue的生命周期方法有哪些?
    - beforeCreate 初始化实例前(在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。)
    - created 实例创建完成之后被调用
    - beforeMount 挂载开始之前被调用(相关的 render 函数首次被调用)
    - mounted 挂载之后 (在当前阶段真实的DOM挂载完毕,数据完成双向绑定,可以访问DOM节点)
    - beforeUpdate 数据更新前调用 (不会触发重新渲染过程)
    - updated 更新完成之后
    - beforeDestory 实例销毁之前调用
    - destroyed 实例销毁之后调用 (Vue实例指示的东西都会解绑,所有事件监听移除)
    - activated keep-alive专属,组件被激活时调用
    - deactivated keep-alive专属,组件被销毁是调用

    5、在哪个生命周期内调用异步请求?
    可以在钩子函数 created、beforeMount、mounted 中进行异步请求,
    因为在这三个钩子函数中,data已经创建,可以将服务器端返回的数据进行赋值。

    5、Vue 的单项数据流
    - 数据总是从父组件传递到子组件,子组件没有权利修改从父组件传过来的数据,只能请求父组件对原始数据进行修改。

    6、computed 和 watch 的区别和运用的场景。
    - computed 是计算属性,依赖其他属性计算值,并且computed的值具有缓存性,当计算值发生变化时才会返回内容。
    - watch 监听到值得变化就会调用。

    7、Vue 2.0 响应式数据的原理
    - 整体思路是 数据挟持 + 观察者模式
    (1)、Object.defineProperty 数据挟持
    (2)、使用getter手机依赖,setter通知watcher派发更新
    (2)、watcher发布订阅模式

    8、vue-router 路由函数钩子及生命周期
    - 全局守卫、路由守卫、组件守卫
    - 生命周期:
    (1)、全局守卫 & 路由守卫–> beforeEach、beforeReslove、afterEach、beforeEnter
    (2)、组件内路由守卫–> beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
    9、Vuex
    - vuex可以实现不同组件之间的状态共享
    - vuex可以实现组件内数据的持久化
    - vuex的核心概念
    (1)、state:设置初始值
    (2)、getter:允许组件从state中获取数据
    (3)、Mutation:修改state中状态的方法,且必须是同步函数
    (4)、Action:用于提交mutation,可以包含任何异步请求
    (5)、Model
    - vuex流程
    在vue组件里面,通过dispatch来触发actions提交修改数据的操作,
    然后通过actions的commit触发mutations来修改数据,mutations接收到commit的请求,就会
    自动通过mutate来修改state,最后由store触发每一个调用它的组件的更新。

    10、Vue 的性能优化
    - 不需要响应式的数据不要放在 data 中
    - v-if 和 v-show 区分使用场景
    - computed 和 watch 区分场景使用
    - v-for 遍历必须加 key,key最好是id值,且避免同时使用 v-if
    - 大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
    - 图片懒加载
    - 路由懒加载

    11、Vue 修饰符有哪些?
    - .stop 阻止事件继续传播
    - .prevent 阻止标签默认行为

    12、v-model 的修饰符
    - .lazy 通过这个修饰符,转变为在 change 事件再同步
    - .number 自动将用户输入值转化为数值类型
    - .trim 自动过滤用户输入的收尾空格
    13、Vue 模板编译原理
    Vue 的编译过程就是将 template 转化为 render 函数的过程,分为以下三步:
    第一步是将 模板字符串转换成 element ASTs(解析器)
    第二步是对 AST 进行静态节点标记,主要用来做虚拟 DOM 的渲染优化(优化器)
    第三步是 使用element ASTs 生成 render 函数代码字符串(代码生成器)

    14、双向绑定的原理是什么?
    - 数据层(Model):应用的数据及业务逻辑
    - 视图层(View):应用的展示效果,各类 UI 组件
    - 业务逻辑层(ViewModel):框架封装的核心,它负责将数据与视图关联起来

    15、vue的理解
    - vue是一套构建用户界面的渐进式的MVVM框架
    - vue的核心是关注视图层
    - vue的核心思想是数据驱动和组件化

    16、vue首屏加载慢的原因,解决方案,怎么解决白屏问题
    - 首屏加载慢原因:第一次加载页面有很多组件数据需要渲染
    - 解决方案:
    (1)路由懒加载
    (2)UI组件按需加载
    (3)gzip按需加载
    - 解决白屏:
    (1)使用v-text渲染数据
    (2)使用{{}}语法渲染数据,同时使用v-cloak指令

    17、说说你对spa单页面的理解
    - spa仅在web页面初始化的时候加载html、js、css
    - 页面一旦加载完成就不会因为用户的操作而进行页面的重新加载和渲染
    - 页面的变化是利用路由机制实现html内容的变换,避免页面的重新加载

    18、SPA首屏加载速度慢的怎么解决?
    - 加载慢的原因
    1、网络延时问题
    2、资源文件体积是否过大
    3、资源是否重复发送请求去加载了
    4、加载脚本的时候,渲染内容堵塞了
    - 常见的几种SPA首屏优化方式
    1、减小入口文件积
    2、静态资源本地缓存
    3、UI框架按需加载
    4、图片资源的压缩
    5、组件重复打包
    6、开启GZip压缩
    7、使用SSR

    19、为什么vue采用异步渲染
    - vue是组件级更新,当前组件里的数据变了,它就会去更新这个组件。
    当数据更改一次组件就要重新渲染一次,性能不高,为了防止数据一更新就更新组件,所以做了个异步更新渲染。
    -(核心的方法就是nextTick)

    20、Vue 的异步更新机制是如何实现的?
    - Vue 的异步更新机制的核心是利用了浏览器的异步任务队列来实现的,首选微任务队列,宏任务队列次之。

    21、第一次页面加载会触发哪几个钩子?
    - 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

    展开全文
  • vue常见面试题

    2021-01-07 04:40:30
    vue面试题汇集 vue面试题汇总二 vue面试总结三 vue面试题汇总四 vue面试题汇总五 vue面试题汇总六 axios是什么?怎么使用?描述使用它来实现登录功能的流程 1.axios是基于promise使用浏览器好node.js的一个http客服...
  • vue面试题_vue常见面试题和答案[文].pdf
  • vue面试题

    Vue 的优点
    说说你对 SPA 单页面的理解,它的优缺点分别是什么?
    SPA 首屏加载速度慢的怎么解决?
    Vue 初始化过程中(new Vue(options))都做了什么?
    对MVVM的理解?
    Vue 数据双向绑定原理
    Vue 的响应式原理
    Vue3.x 响应式数据原理
    Vue3.0 里为什么要用 Proxy API 替代 defineProperty API?
    Proxy 与 Object.defineProperty 优劣对比
    vue 中组件的 data 为什么是一个函数?而 new Vue 实例里,data 可以直接是一个对象
    vue 中 data 的属性可以和 methods 中方法同名吗,为什么?
    vue 中 created 与 mounted 区别
    Vue 中 computed 与 method 的区别
    虚拟 DOM 中 key 的作用
    用 index 作为 key 可能会引发的问题
    Vue 中 watch 用法详解
    vue 中对 mixins 的理解和使用
    vue 中的插槽
    为什么 vue 采用异步渲染
    Vue 的异步更新机制是如何实现的?
    KaTeX parse error: Expected 'EOF', got '#' at position 27: …解</a> <a href="#̲jump22">Vue 中常用…set(obj, key, val) 做了什么?
    说说 vue 的生命周期的理解
    第一次页面加载会触发哪几个钩子?
    Vue 组件通信有哪些方式
    router和route的区别
    vue-router 有几种钩子函数?
    vue-router 路由跳转方式
    vue-router 路由传参
    keep-alive 了解吗
    Vuex 是什么?怎么使用?
    什么情况下使用 Vuex?
    Vuex 和单纯的全局对象有什么区别?
    为什么 Vuex 的 mutation 中不能做异步操作?
    axios 是什么,其特点和常用语法
    对 SSR 有了解吗,它主要解决什么问题?
    Vue 项目前端开发环境请求服务器接口跨域问题
    做过哪些 Vue 的性能优化?
    Vue 3.0 所采用的 Composition Api 与 Vue 2.x 使用的 Options Api 有什么区别?

    Vue 的优点

    轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
    简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
    双向数据绑定:保留了 angular 的特点,在数据操作方面更为简单;
    组件化:保留了 react 的优点,实现了 html 的封装和重用,在构建单页面应用方面有着独特的优势;
    视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
    虚拟 DOM:dom 操作是非常耗费性能的, 不再使用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种方式;
    运行速度更快:相比较于 react 而言,同样是操作虚拟 dom ,就性能而言, vue 存在很大的优势。
    说说你对SPA单页面的理解,它的优缺点分别是什么?
    是什么

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

    用户体验好,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
    减少了不必要的跳转和重复渲染,这样相对减轻了服务器的压力
    前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理
    缺点

    初次加载耗时多
    不能使用浏览器的前进后退功能,由于单页应用在一个页面中显示所有的内容,所以,无法前进后退
    不利于搜索引擎检索:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。
    SPA首屏加载速度慢的怎么解决?
    首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容;

    加载慢的原因

    网络延时问题
    资源文件体积是否过大
    资源是否重复发送请求去加载了
    加载脚本的时候,渲染内容堵塞了
    常见的几种SPA首屏优化方式

    减小入口文件积
    静态资源本地缓存
    UI框架按需加载
    图片资源的压缩
    组件重复打包
    开启GZip压缩
    使用SSR
    想要具体了解可以点击SPA(单页应用)首屏加载速度慢的解决详解

    Vue初始化过程中(new Vue(options))都做了什么?
    处理组件配置项;初始化根组件时进行了选项合并操作,将全局配置合并到根组件的局部配置上;初始化每个子组件时做了一些性能优化,将组件配置对象上的一些深层次属性放到 vm.$options 选项中,以提高代码的执行效率;
    初始化组件实例的关系属性,比如 p a r e n t 、 parent、parent、children、r o o t 、 root、root、refs 等
    处理自定义事件
    调用 beforeCreate 钩子函数
    初始化组件的 inject 配置项,得到 ret[key] = val 形式的配置对象,然后对该配置对象进行响应式处理,并代理每个 key 到 vm 实例上
    数据响应式,处理 props、methods、data、computed、watch 等选项
    解析组件配置项上的 provide 对象,将其挂载到 vm._provided 属性上
    调用 created 钩子函数
    如果发现配置项上有 el 选项,则自动调用 $mount 方法,也就是说有了 el 选项,就不需要再手动调用 $mount 方法,反之,没提供 el 选项则必须调用 $mount
    接下来则进入挂载阶段

    // core/instance/init.js
    export function initMixin (Vue: Class<Component>) {
      Vue.prototype._init = function (options?: Object) {
          const vm: Component = this
          vm._uid = uid++
          
          // 如果是Vue的实例,则不需要被observe
          vm._isVue = true
          
          if (options && options._isComponent) {
            // optimize internal component instantiation
            // since dynamic options merging is pretty slow, and none of the
            // internal component options needs special treatment.
            initInternalComponent(vm, options)
          } else {
            vm.$options = mergeOptions(
              resolveConstructorOptions(vm.constructor),
              options || {},
              vm
            )
          }
          
          if (process.env.NODE_ENV !== 'production') {
            initProxy(vm)
          } else {
            vm._renderProxy = vm
          }
    
          vm._self = vm
    
          initLifecycle(vm)
          initEvents(vm)
          callHook(vm, 'beforeCreate')
          initInjections(vm) // resolve injections before data/props
    
          initState(vm)
          initProvide(vm) // resolve provide after data/props
          callHook(vm, 'created')
          
          if (vm.$options.el) {
            vm.$mount(vm.$options.el)
          }
      }
    }
    
    

    对MVVM的理解?
    MVVM 由 Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来;ViewModel 是一个同步View 和 Model的对象。

    在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。

    ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

    Vue 数据双向绑定原理
    Vue数据双向绑定原理
    实现mvvm的数据双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来给各个属性添加setter,getter并劫持监听,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点:
    1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
    2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
    3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
    在这里插入图片描述

    Vue的响应式原理
    什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。
    Object.defineProperty 为对象中的每一个属性,设置 get 和 set 方法,每个声明的属性,都会有一个 专属的依赖收集器 subs,当页面使用到 某个属性时,触发 ObjectdefineProperty - get函数,页面的 watcher 就会被 放到 属性的依赖收集器 subs 中,在 数据变化时,通知更新;
    当数据改变的时候,会触发Object.defineProperty - set函数,数据会遍历自己的 依赖收集器 subs,逐个通知 watcher,视图开始更新;

    Vue3.x响应式数据原理
    Vue3.x改用Proxy替代Object.defineProperty。
    因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。
    Proxy只会代理对象的第一层,Vue3是怎样处理这个问题的呢?
    判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。
    监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

    Vue3.0 里为什么要用 Proxy API替代 defineProperty API?
    1.defineProperty API 的局限性最大原因是它只能针对单例属性做监听。
    Vue2.x中的响应式实现正是基于defineProperty中的descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因。
    2.Proxy API的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作, 这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。
    Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
    3.响应式是惰性的。
    在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。
    在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗。

    Proxy 与 Object.defineProperty 优劣对比
    1.Proxy 可以直接监听对象而非属性;
    2.Proxy 可以直接监听数组的变化;
    3.Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
    4.Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
    5.Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
    6.Object.defineProperty 的优势如下:
    兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

    vue中组件的data为什么是一个函数?而new Vue 实例里,data 可以直接是一个对象
    我们知道,Vue组件其实就是一个Vue实例。

    JS中的实例是通过构造函数来创建的,每个构造函数可以new出很多个实例,那么每个实例都会继承原型上的方法或属性。

    Vue的data数据其实是Vue原型上的属性,数据存在于内存当中。Vue为了保证每个实例上的data数据的独立性,规定了必须使用函数,而不是对象。

    因为使用对象的话,每个实例(组件)上使用的data数据是相互影响的,这当然就不是我们想要的了。对象是对于内存地址的引用,直接定义个对象的话组件之间都会使用这个对象,这样会造成组件之间数据相互影响。

    使用函数后,使用的是data()函数,data()函数中的this指向的是当前实例本身,就不会相互影响了。

    而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。

    vue中data的属性可以和methods中方法同名吗,为什么?
    可以同名,methods的方法名会被data的属性覆盖;调试台也会出现报错信息,但是不影响执行;
    原因:源码定义的initState函数内部执行的顺序:props>methods>data>computed>watch

    //initState部分源码
    export function initState (vm: Component) {
      vm._watchers = []
      const opts = vm.$options
      if (opts.props) initProps(vm, opts.props)
      if (opts.methods) initMethods(vm, opts.methods)
      if (opts.data) {
        initData(vm)
      } else {
        observe(vm._data = {}, true /* asRootData */)
      }
      if (opts.computed) initComputed(vm, opts.computed)
      if (opts.watch && opts.watch !== nativeWatch) {
        initWatch(vm, opts.watch)
      }   
    }
    
    

    vue中data的属性可以和methods中方法同名吗,为什么?
    可以同名,methods的方法名会被data的属性覆盖;调试台也会出现报错信息,但是不影响执行;
    原因:源码定义的initState函数内部执行的顺序:props>methods>data>computed>watch

    //initState部分源码
    export function initState (vm: Component) {
      vm._watchers = []
      const opts = vm.$options
      if (opts.props) initProps(vm, opts.props)
      if (opts.methods) initMethods(vm, opts.methods)
      if (opts.data) {
        initData(vm)
      } else {
        observe(vm._data = {}, true /* asRootData */)
      }
      if (opts.computed) initComputed(vm, opts.computed)
      if (opts.watch && opts.watch !== nativeWatch) {
        initWatch(vm, opts.watch)
      }   
    }
    

    vue中created与mounted区别
    在created阶段,实例已经被初始化,但是还没有挂载至el上,所以我们无法获取到对应的节点,但是此时我们是可以获取到vue中data与methods中的数据的;
    在mounted阶段,vue的template成功挂载在$el中,此时一个完整的页面已经能够显示在浏览器中,所以在这个阶段,可以调用节点了;

    //以下为测试vue部分生命函数,便于理解
    beforeCreate(){  //创建前
        console.log('beforecreate:',document.getElementById('first'))//null
        console.log('data:',this.text);//undefined
        this.sayHello();//error:not a function
    },
    created(){  //创建后
        console.log('create:',document.getElementById('first'))//null
        console.log('data:',this.text);//this.text
        this.sayHello();//this.sayHello()
    },
    beforeMount(){ //挂载前
        console.log('beforeMount:',document.getElementById('first'))//null
        console.log('data:',this.text);//this.text
        this.sayHello();//this.sayHello()
    },
    mounted(){  //挂载后
        console.log('mounted:',document.getElementById('first'))//<p></p>
        console.log('data:',this.text);//this.text
        this.sayHello();//this.sayHello()
    }
    
    

    Vue中computed与method的区别
    相同点:
    如果作为模板的数据显示,二者能实现响应的功能,唯一不同的是methods定义的方法需要执行
    不同点:
    1.computed 会基于响应数据缓存,methods不会缓存;
    2.diff之前先看data里的数据是否发生变化,如果没有变化computed的方法不会执行,但methods里的方法会执行
    3.computed是属性调用,而methods是函数调用
    虚拟DOM中key的作用

    简单的说:key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用。
    复杂的说:当状态中的数据发生了变化时,react会根据【新数据】生成【新的虚拟DOM】,随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:

    旧虚拟DOM中找到了与新虚拟DOM相同的key

    1.若虚拟DOM中的内容没有变,直接使用之前的真是DOM

    旧虚拟DOM中未找到与新虚拟DOM相同的key

    1.根据数据创建新的真实DOM,随后渲染到页面

    用index作为key可能会引发的问题

    • 若对数据进行:逆序添加/逆序删除等破坏顺序的操作,会产生没有必要的真实DOM更新,界面效果虽然没有问题,但是数据过多的话,会效率过低;
    • 如果结构中还包含输入类的DOM,会产生错误DOM更新,界面有问题;
    • 注意!如果不存在对数据的逆序操作,仅用于渲染表用于展示,使用index作为key是没有问题的

    Vue中watch用法详解
    在vue中,使用watch来监听数据的变化;
    1.监听的数据后面可以写成对象形式,包含handler方法,immediate和deep。
    2.immediate表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。
    3.当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

    watch: {
        name: {
          handler(newName, oldName) {
          
          },
          deep: true,
          immediate: true
        }
      } 
    
    

    vue中对mixins的理解和使用

    mixins是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。
    而mixins引入组件之后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。
    可点击vue中对mixins的理解和使用的介绍作为参考

    vue中的插槽
    在这里插入图片描述

    为什么vue采用异步渲染
    vue是组件级更新,当前组件里的数据变了,它就会去更新这个组件。当数据更改一次组件就要重新渲染一次,性能不高,为了防止数据一更新就更新组件,所以做了个异步更新渲染。(核心的方法就是nextTick)

    源码实现原理:
    当数据变化后会调用notify方法,将watcher遍历,调用update方法通知watcher进行更新,这时候watcher并不会立即去执行,在update中会调用queueWatcher方法将watcher放到了一个队列里,在queueWatcher会根据watcher的进行去重,多个属性依赖一个watcher,如果队列中没有该watcher就会将该watcher添加到队列中,然后通过nextTick异步执行flushSchedulerQueue方法刷新watcher队列。flushSchedulerQueue中开始会触发一个before的方法,其实就是beforeUpdate,然后watcher.run() 才开始真正执行watcher,执行完页面就渲染完成啦,更新完成后会调用updated钩子。

    在这里插入图片描述

    Vue 的异步更新机制是如何实现的?

    Vue 的异步更新机制的核心是利用了浏览器的异步任务队列来实现的,首选微任务队列,宏任务队列次之。

    当响应式数据更新后,会调用 dep.notify 方法,通知 dep 中收集的 watcher 去执行 update 方法,watcher.update 将 watcher 自己放入一个 watcher 队列(全局的 queue 数组)。

    然后通过 nextTick 方法将一个刷新 watcher 队列的方法(flushSchedulerQueue)放入一个全局的 callbacks 数组中。

    如果此时浏览器的异步任务队列中没有一个叫 flushCallbacks 的函数,则执行 timerFunc 函数,将 flushCallbacks 函数放入异步任务队列。如果异步任务队列中已经存在 flushCallbacks 函数,等待其执行完成以后再放入下一个 flushCallbacks 函数。

    flushCallbacks 函数负责执行 callbacks 数组中的所有 flushSchedulerQueue 函数。

    flushSchedulerQueue 函数负责刷新 watcher 队列,即执行 queue 数组中每一个 watcher 的 run 方法,从而进入更新阶段,比如执行组件更新函数或者执行用户 watch 的回调函数。

    $nextTick的理解
    用法:
    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
    为什么?
    Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。
    所以为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。
    使用场景
    在你更新完数据后,需要及时操作渲染好的 DOM时

    Vue中常用的一些指令
    1.v-model指令:用于表单输入,实现表单控件和数据的双向绑定。
    2.v-on:简写为@,基础事件绑定
    3.v-bind:简写为:,动态绑定一些元素的属性,类型可以是:字符串、对象或数组。
    4.v-if指令:取值为true/false,控制元素是否需要被渲染
    5.v-else指令:和v-if指令搭配使用,没有对应的值。当v-if的值false,v-else才会被渲染出来。
    6.v-show指令:指令的取值为true/false,分别对应着显示/隐藏。
    7.v-for指令:遍历data中存放的数组数据,实现列表的渲染。
    8.v-once: 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新

    vue的自定义指令
    Vue除了核心功能默认内置的指令 ,Vue 也允许注册自定义指令。
    自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。

    添加自定义指令的两种方式:

    • 全局指令: 通过 Vue.directive() 函数注册一个全局的指令。
    • 局部指令:通过组件的 directives 属性,对该组件添加一个局部的指令。

    你有写过自定义指令吗?自定义指令的应用场景有哪些?
    Vue除了核心功能默认内置的指令 ,Vue 也允许注册自定义指令。
    自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。

    写一个自定义指令的两种方式:

    1.全局指令: 通过 Vue.directive() 函数注册一个全局的指令。
    2.局部指令:通过组件的 directives 属性,对该组件添加一个局部的指令。
    创建全局指令:
    需要传入指令名称以及一个包含指令钩子函数的对象,该对象的键即钩子函数的函数名,值即函数体,钩子函数可以有多个。

    Vue.directive("focus", {
        inserted: function(el){
             el.focus();
         }
     })
    

    创建局部指令:
    通过在Vue实例中添加 directives 对象数据注册局部自定义指令。

    directives: {
           focus: {
                inserted: function(el){
                    el.focus();
                }
            }
       }
    

    下面我们就具体讲一下怎么在实战中运用自定义指令:

    需求:有些网站图片的加载做得非常优雅,在图片未完成加载前,用随机的背景色占位,图片加载完成后才直接渲染出来。用自定义指令可以非常方便的实现这个功能。

    <div id="app" v-image = "item " v-for="item in imageList"></div>
    <script>
    Vue.directive("image", {
        inserted: function(el,binding){
             var color = Math.floor(Math,random()*1000000)
             el.style.backgroundColor = "#" + color
             var img = new Image()
             img.src = binding.vaule
             img.onload = function(){ 
               el.style.backgroundImage =  “url(+ binding.vaule + ")"
             }
         }
     })
     new Vue({
            el: "#app",
            data: {
                imageList: [
                    {
                        url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-p10-plus.jpg"
                    },
                    {
                        url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-watch2-pro-banner.jpg"
                    },
                    {
                        url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/en/mkt/homepage/section4/home-s4-matebook-x.jpg"
                    }
                ]
            }
        })
     </script>
    

    ####自定义指令的钩子函数
    一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    钩子函数参数(即 el、binding、vnode 和 oldVnode)

    • el:指令所绑定的元素,可以用来直接操作 DOM。
    • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值。
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。
    • arg:传给指令的参数。
    • modifiers:一个包含修饰符的对象。
    • vnode:Vue 编译生成的虚拟节点。
    • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
      ####应用场景
    • 防抖
    • 图片懒加载
    • 一键复制功能

    v-show和v-if指令的共同点和不同点
    相同点:
    v-show和v-if都能控制元素的显示和隐藏。
    不同点:
    1.实现本质方法不同:v-show本质就是通过设置css中的display设置为none;控制隐藏v-if是动态的向DOM树内添加或者删除DOM元素;
    2.v-show都会编译,初始值为false,只是将display设为none,但它也编译了;v-if初始值为false,就不会编译了
    总结:v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,如果要频繁切换某节点时,故v-show性能更好一点。

    为什么避免v-if和v-for一起使用
    vue2.x版本中,当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级;
    vue3.x版本中,当 v-if 与 v-for 一起使用时,v-if 具有比 v-for 更高的优先级。
    官网明确指出:避免 v-if 和 v-for 一起使用,永远不要在一个元素上同时使用 v-if 和 v-for。

    可以先对数据在计算数据中进行过滤,然后再进行遍历渲染;
    操作和实现起来都没有什么问题,页面也会正常展示。但是会带来不必要的性能消耗;

    Vue.set 改变数组和对象中的属性
    在一个组件实例中,只有在data里初始化的数据才是响应的,Vue不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的,所以数据改变了但是不会在页面渲染;
    解决办法:
    使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上
    vue为什么在 HTML 中监听事件?
    你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 或 @ 有几个好处:

    • 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
    • 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
    • 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

    vm.$set(obj, key, val) 做了什么?
    由于 Vue 无法探测对象新增属性或者通过索引为数组新增一个元素,所以这才有了 vm.s e t , 它 是 V u e . s e t 的 别 名 。 v m . set,它是 Vue.set 的别名。 vm.set,它是Vue.set的别名。vm.set 用于向响应式对象添加一个新的 property,并确保这个新的 property 同样是响应式的,并触发视图更新。

    • 为对象添加一个新的响应式数据:调用 defineReactive 方法为对象增加响应式数据,然后执行 dep.notify 进行依赖通知,更新视图
    • 为数组添加一个新的响应式数据:通过 splice 方法实现

    说说vue的生命周期的理解
    生命周期通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
    beforecreate (初始化界面前)
    created (初始化界面后)
    beforemount (渲染界面前)
    mounted (渲染界面后)
    beforeUpdate (更新数据前)
    updated (更新数据后)
    beforedestory (卸载组件前)
    destroyed (卸载组件后)
    注意:面试官想听到的不只是你说出了以上八个钩子名称,而是每个阶段做了什么?可以收藏下图!

    在这里插入图片描述

    第一次页面加载会触发哪几个钩子?
    第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
    Vue组件通信有哪些方式
    1.父传子:props
    父组件通过 props 向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed

    2.父传子孙:provide 和 inject
    父组件定义provide方法return需要分享给子孙组件的属性,子孙组件使用 inject 选项来接收指定的我们想要添加在这个实例上的 属性;

    3.子传父:通过事件形式
    子组件通过 $emit()给父组件发送消息,父组件通过v-on绑定事件接收数据。

    4.父子、兄弟、跨级:eventBus.js
    这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来(e m i t ) 触 发 事 件 和 ( emit)触发事件和(emit)触发事件和(on)监听事件,巧妙而轻量地实现了任何组件间的通信。

    5.通信插件:PubSub.js

    6.vuex
    vuex 是 vue 的状态管理器,存储的数据是响应式的。只需要把共享的值放到vuex中,其他需要的组件直接获取使用即可;

    router和route的区别
    router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。。。经常用的跳转链接就可以用this.$router.push,和router-link跳转一样。

    route相当于当前正在跳转的路由对象。。可以从里面获取name,path,params,query等
    vue-router有几种钩子函数?
    1.全局路由
    全局导航钩子主要有两种钩子:前置守卫(beforeEach)、后置钩子(afterEach)
    2. 路由独享的钩子
    单个路由独享的导航钩子,它是在路由配置上直接进行定义的

    routes: [
             {
                path: '/file',
                component: File,
                beforeEnter: (to, from ,next) => { 
                 //do something
                }
             }
            ]
    

    3.组件内的导航钩子
    组件内的导航钩子主要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的。
    ps:详细知识点可以点击路由导航守卫查看;
    vue-router路由跳转方式
    声明式(标签跳转)

      <router-link :to="{name:'home'}"></router-link>
      <router-link :to="{path:'/home'}"></router-link>
    

    编程式( js跳转)

    this.$router.push('/home')
    this.$router.push({name:'home'})
    this.$router.push({path:'/home'})
    

    vue-router路由传参
    router中路由配置

     {
       path: 'homeDetails/:id',//params传参
       name:'homeDetails'
       component: () =>import ('@/views/home/homeDetails.vue'),
       //子路由的绝对路径
      },
    
     {
     path: 'homeDetails/',//query传参
     name:'homeDetails'
     component: () =>import ('@/views/home/homeDetails.vue'),
     //子路由的绝对路径
    },
    

    父组件home点击传参

    // params传参
    <router-link to="/homeDetails/12345"></router-link>
    <router-link to="{name:'homeDetails',params:{id:12345}"></router-link>//切记之呢个用name,不能用path
    
    //query传参
    <router-link to="/homeDetails?id=12345"></router-link>
    <router-link to="{path:'/homeDetails',query:{id:12345}"></router-link>
    <router-link to="{name:'homeDetails',query:{id:12345}"></router-link>
    

    子组件homeDetails接受参数

    // 子组件使用this.$route.params.id来接收路由参数
    <template>
     <div><span>我是从父组件传递过来的id:</span>{{this.$route.params.id}}</div>
      //或
     <div><span>我是从父组件传递过来的id:</span>{{id}}</div>
    </template>
    <script>
     export default{
       data(){
        id:''
       },
       mounted(){
        this.id = this.$route.params.id  //12345
        this.id = this.$route.query.id  //12345
       }
     } 
    </script>
    
    

    keep-alive了解吗
    < keep-alive >是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

    < keep-alive > 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
    Vuex是什么?怎么使用?
    Vuex是实现组件全局状态(数据)管理的一种机制,可以方便实现组件数据之间的共享;Vuex集中管理共享的数据,易于开发和后期维护;能够高效的实现组件之间的数据共享,提高开发效率;存储在Vuex的数据是响应式的,能够实时保持页面和数据的同步;
    Vuex重要核心属性包括:state,mutations,action,getters,modules.

    state
    Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

    mutations
    mutations定义的方法动态修改Vuex 的 store 中的状态或数据。

    action
    actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

    getters
    类似vue的计算属性,主要用来过滤一些数据。

    modules
    项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

    什么情况下使用 Vuex?
    如果应用够简单,最好不要使用 Vuex,一个简单的 store 模式即可;
    需要构建一个中大型单页应用时,使用Vuex能更好地在组件外部管理状态;
    Vuex和单纯的全局对象有什么区别?
    Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

    为什么 Vuex 的 mutation 中不能做异步操作?
    每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

    axios 是什么,其特点和常用语法
    是什么?

    1.Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,
    2.react/vue 官方都推荐使用 axios 发 ajax 请求
    特点:

    1.基于 promise 的异步 ajax 请求库,支持promise所有的API
    2.浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests
    3.支持请求/响应拦截器
    4.支持请求取消
    5.可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
    6.批量发送多个请求
    安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源7.策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
    常用语法:
    axios(config): 通用/最本质的发任意类型请求的方式
    axios(url[, config]): 可以只指定 url 发 get 请求
    axios.request(config): 等同于 axios(config)
    axios.get(url[, config]): 发 get 请求
    axios.delete(url[, config]): 发 delete 请求
    axios.post(url[, data, config]): 发 post 请求
    axios.put(url[, data, config]): 发 put 请求
    axios.defaults.xxx: 请求的默认全局配置
    axios.interceptors.request.use(): 添加请求拦截器
    axios.interceptors.response.use(): 添加响应拦截器
    axios.create([config]): 创建一个新的 axios(它没有下面的功能)
    axios.Cancel(): 用于创建取消请求的错误对象
    axios.CancelToken(): 用于创建取消请求的 token 对象
    axios.isCancel(): 是否是一个取消请求的错误
    axios.all(promises): 用于批量执行多个异步请求
    axios.spread(): 用来指定接收所有成功数据的回调函数的方法

    对SSR有了解吗,它主要解决什么问题?
    Server-Side Rendering 我们称其为SSR,意为服务端渲染指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的过程;

    解决了以下两个问题:

    • seo:搜索引擎优先爬取页面HTML结构,使用ssr时,服务端已经生成了和业务想关联的HTML,有利于seo

    • 首屏呈现渲染:用户无需等待页面所有js加载完成就可以看到页面视图(压力来到了服务器,所以需要权衡哪些用服务端渲染,哪些交给客户端)
      缺点

    • 复杂度:整个项目的复杂度

    • 性能会受到影响

    • 服务器负载变大,相对于前后端分离务器只需要提供静态资源来说,服务器负载更大,所以要慎重使用

    Vue 项目前端开发环境请求服务器接口跨域问题
    Vue项目前端开发环境请求服务器接口跨域问题
    对于vue-cli 2.x版本在config文件夹配置服务器代理;
    对于vue-cli 3.x版本前端配置服务器代理在vue.config.js中设置服务器代理;如下图:
    在这里插入图片描述

    target对应的属性值为你准备向后端服务器发送请求的主机+端口,含义为:相当于把前端发送请求的主机+端口自动替换成挂载的主机和端口,这样前后端的主机端口都一一就不会存在跨域问题;
    ws:表示WebSocket协议;
    changeOrigin:true;表示是否改变原域名;这个一定要选择为true;
    这样发送请求的时候就不会出现跨域问题了。

    做过哪些Vue的性能优化?
    编码阶段

    • 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
    • v-if和v-for不能连用
    • 如果需要使用v-for给每项元素绑定事件时使用事件代理
    • SPA 页面采用keep-alive缓存组件
    • 在更多的情况下,使用v-if替代v-show
    • key保证唯一
    • 使用路由懒加载、异步组件
    • 防抖、节流
    • 第三方模块按需导入
    • 长列表滚动到可视区域动态加载
    • 图片懒加载
    • SEO优化

    服务端渲染SSR

    • 预渲染
    • 打包优化

    压缩代码

    • Tree Shaking/Scope Hoisting
    • 使用cdn加载第三方模块
    • 多线程打包happypack
    • splitChunks抽离公共文件
    • sourceMap优化

    Vue 3.0 所采用的 Composition Api 与 Vue 2.x使用的Options Api 有什么区别?
    Options Api

    包含一个描述组件选项(data、methods、props等)的对象 options;
    API开发复杂组件,同一个功能逻辑的代码被拆分到不同选项 ;
    使用mixin重用公用代码,也有问题:命名冲突,数据来源不清晰;
    

    Composition Api

    vue3 新增的一组 api,它是基于函数的 api,可以更灵活的组织组件的逻辑。
    解决options api在大型项目中,options api不好拆分和重用的问题。
    
    展开全文
  • const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: "/user/:id", component: User }, ], });
  • vue常见面试题.pdf

    2021-12-14 17:32:52
    vue常见面试题.pdf
  • Vue 常见技术面试题

    2021-01-08 11:55:41
    Vue拦截器vuex状态管理vue生命周期、常见的生命周期函数用过哪些vue ui框架vue中的router和route的区别计算属性和侦听属性的区别vue里面delete跟vue.delete有什么区别?如果一个空白页面使用弹窗this,那么this会弹...
  • 2021年Vue常见面试题以及答案(面试必过)

    万次阅读 多人点赞 2020-12-15 14:39:41
    Vue数据双向绑定原理Vue的响应式原理vue中组件的data为什么是一个函数vue中created与mounted区别Vue中computed与method的区别Vue中watch用法详解Vue中常用的一些指令说说vue的生命周期 对MVVM的理解? MVVM 由 Model...
  • Vue常见面试题汇总

    2022-05-13 01:38:11
    import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //引入两个组件 import home from "./home.vue" import game from "./game.vue" //定义路由 const routes = [ { path: "/", ...
  • vue常见面试题 面试题.docx
  • vue常见面试题(附带答案) 超实用!!建议收藏2021.pdf
  • 常见vue面试题有哪些?vue是一套用于构建用户界面的渐进式JavaScript框架,也是初创项目的首选前端框架。很多企业在招聘前端工程师时都会考察其对vue的了解,接下来小编就给大家分享常见的vue面试题答疑。 awps2 1、...
  • 常见vue面试题

    千次阅读 2020-12-21 20:44:42
    就是用了懒加载后打完包直接运行那个index.html会报错,报文件引用错误其实是打包时候路径配置有点问 ,找到build下面的webpack.prod.conf.js 添加 publicPath:"./", 028、vue中的scoped 1. 在vue组件中,在...
  • 面试必备:VUE面试题(含答案)

    千次阅读 2022-07-08 14:29:57
    面试必备:VUE面试题(含答案)
  • 35道常见的前端vue面试题

    万次阅读 多人点赞 2021-03-06 00:04:32
    来源 | https://segmentfault.com/a/1190000021936876今天这篇文章给大家分享一些常见的前端vue面试题。有一定的参考价值,有需要的朋友可以参考一下...
  • 【面试题】2021最新Vue面试题汇总

    万次阅读 多人点赞 2020-10-28 16:25:59
    面试题(2020)Vue面试题汇总 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 1、对于MVVM的理解 MVVM 是 Model-View-ViewModel 的...
  • 常见vue面试题怎么答疑?vue是一套用于构建用户界面的渐进式JavaScript框架,也是初创项目的首选前端框架。很多企业在招聘前端工程师时都会考察其对vue的了解,接下来小编就给大家分享常见的vue面试题答疑。  1...
  • 一、vue常见面试题二、生命周期函数面试题三、vue路由面试题四、vuex常见面试题 一、vue常见面试题 1.vue优点? 答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb; 简单易学:国人开发,...
  • Vue常见面试题
  • Vue常见面试题

    2020-08-28 21:47:09
    vue如何监听数据变化   谈谈你对MVVM开发模式的理解 MVVM模式包括3部分 Model:即数据模型,data View:即视图,负责对数据的展示,template ViewModel(VM):负责监听Model、View中的数据变化,
  • vue面试题(1-56题)

    千次阅读 2022-06-19 21:13:56
    4、怎样理解 Vue 的单向数据流?5、computed 和 watch 的区别和运用的场景?6、直接给一个数组项赋值,Vue 能检测到变化吗?7、谈谈你对 Vue 生命周期的理解?8、Vue 的父组件和子组件生命周期钩子函数执行顺序?9、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,456
精华内容 4,182
关键字:

常见vue面试题