微信小程序> Vue中常见的面试题/知识点整理

Vue中常见的面试题/知识点整理

浏览量:898 时间: 来源:m0_45043105

看看面试题,只是为了查漏补缺,看看自己那些方面还不懂。切记不要以为背了面试题,就万事大吉了,最好是理解背后的原理,这样面试的时候才能侃侃而谈。不然,稍微有水平的面试官一看就能看出,是否有真才实学还是刚好背中了这道面试题。
(都是一些基础的vue面试题,大神不用浪费时间往下看)
一、对于MVVM的理解?
MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View代表ui组件,也就是视图层,它负责将数据模型转化成ui展现出来。
ViewModel就监听模型数据的改变和控制视图行为,处理用户交互,简单理解就是一个同步ViewModel的对象,是连接ModelView的桥梁。ViewModel之间并没有直接联系,而是通过ViewModel进行交互,ModelViewModel 之间的交互式双向的 ,因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View上。
ViewModel通过双向数据绑定把View层和Model层连接了起来,而ViewModel之间的同步工作完全是自动的,无需人为干涉,因此开发者只需要关注逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。
二、Vue的生命周期
beforeCreate(创建前)  实例在内存中被创建出来,还没有初始化好data和methods属性。
created (创建后):实例已经在内存中创建,已经初始化好data和method,此时还没有开始编译模板。
beforeMount (载入前)在挂载开始之前被调用。相关的render函数首次被调用。已经完成了编译模板,把data里面的数据和模板生产html。但是此时还没有挂载html到页面上。
mounted (载入后)挂载完成之后调用,完成模板中的html渲染到html页面中,此过程中进行ajax交互。
beforeUpdate (更新前)  状态更新之前执行函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为还没有开始重新渲染DOM节点。
updated (更新后)此时data中的状态值和界面上显示的数据都已经完成了跟新,界面已经被重新渲染好了!
beforeDestory (销毁前) 在实例销毁之前调用。实例仍完全可用。
destroyed (销毁后)实例销毁后调用,Vue实例指示的所有东西都会解绑,所有的事件监听器都会被移除,所有的子实例也都会被销毁。组件已经被完全销毁,此时组建中所有data、methods、以及过滤器,指令等,都已经不可用了
1.什么是vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
2.vue生命周期的作用是什么?
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
3.vue生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
4.第一次页面加载会触发哪几个钩子?
beforeCreate, created, beforeMount, mounted 。
5.DOM 渲染在 哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了。
三、 Vue实现数据双向绑定的原理:
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —视图更新;视图交互变化(input)—数据model变更双向绑定效果。
js实现简单的双向绑定

body    div id="app"    input type="text" id="txt"    p id="show"/p/div/bodyscript type="text/javascript"    var obj = {}    Object.defineProperty(obj, 'txt', {        get: function () {            return obj        },        set: function (newValue) {            document.getElementById('txt').value = newValue            document.getElementById('show').innerHTML = newValue        }    })    document.addEventListener('keyup', function (e) {        obj.txt = e.target.value    })/script

1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)
五、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 依赖的页面。”
六、Vue与Angular以及React的区别?
(版本在不断更新,以下的区别有可能不是很正确。我工作中只用到vue,对angular和react不怎么熟)
1.与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。

不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。

2.与React的区别
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
七、vue路由的钩子函数
总体来讲vue里面提供了三大类钩子
1、全局钩子
2、某个路由独享的钩子
3、组件内钩子
三种路由钩子中都涉及到了三个参数,
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
(一).全局守卫(全局路由钩子)

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... }) router.beforeEach((to, from, next) = { // ... next()})

每个守卫方法接受三个参数:

to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数
注意:使用全局路由钩子, 一定要调用next()!!!
(二).路由独享的守卫(路由内钩子)
你可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({ routes: [  {   path: '/foo',   component: Foo,   beforeEnter: (to, from, next) = {    // ...   }  } ]})

(三). 组件内的守卫(组件内钩子)
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave

const Foo = { template: `...`, beforeRouteEnter (to, from, next) {  // 在渲染该组件的对应路由被 confirm 前调用  // 不!能!获取组件实例 `this`  // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate (to, from, next) {  // 在当前路由改变,但是该组件被复用时调用  // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,  // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。  // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) {  // 导航离开该组件的对应路由时调用  // 可以访问组件实例 `this` }}

二. 路由钩子在实际开发中的应用场景
1.beforeEach的使用
使用场景: 一般用在跳转前需要做校验的地方,如:进入首页前做登录校验,如果已登录则跳转首页,否则跳转登录页。

//路由跳转前做判断router.beforeEach((to, from, next) = {  let hasLogin = Cookies.get('hasLogin'); //从cookies中获取是否已登陆过的信息  if(hasLogin){    next()  }else{    if(to.path == '/login'){      next()    }else{      next({        replace:true,        name:'login',      })    }  }})

2 beforeRouteLeave的使用
(一) 清除当前组件中的定时器
当一个组件中有一个定时器时, 在路由进行切换的时候, 可使用beforeRouteLeave将定时器进行清楚, 以免占用内存:

beforeRouteLeave (to, from, next) { window.clearInterval(this.timer) //清楚定时器 next()}

(二) 当页面中有未关闭的窗口, 或未保存的内容时, 阻止页面跳转
如果页面内有重要的信息需要用户保存后才能进行跳转, 或者有弹出框的情况. 应该阻止用户跳转

beforeRouteLeave (to, from, next) { //判断是否弹出框的状态和保存信息与否 if (this.dialogVisibility === true) {  this.dialogVisibility = false //关闭弹出框  next(false) //回到当前页面, 阻止页面跳转 }else if(this.saveMessage === false) {  alert('请保存信息后退出!') //弹出警告  next(false) //回到当前页面, 阻止页面跳转 }else {  next() //否则允许跳转 }}

(三) 保存相关内容到本地或vuex中
当用户需要关闭页面时, 可以将公用的信息保存到本地或Vuex中

beforeRouteLeave (to, from, next) {  localStorage.setItem(name, content); //保存到localStorage中  next()}

八、vuex是什么?怎么使用?哪种功能场景使用它?
Vuex是vue框架中状态管理。

应用场景有:单页应用中,组件之间的数据状态。
应用实例:
1、购物车功能;
2、下单页面有选择优惠券按钮,点击进入优惠券页面,选择后返回到下单页,数据会绑定回来,显示已选择的优惠券;
3、登录状态等等
工作流程:
1、数据从state中渲染到页面;

2、在页面通过dispatch来触发action;

3、action通过调用commit,来触发mutation;

4、mutation来更改数据,数据变更之后会触发dep对象的notify,通知所有Watcher对象去修改对应视图(vue的双向数据绑定原理)。
五大核心:
State
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
getters
类似vue的计算属性,主要用来过滤一些数据。

用法  vuex中:

 getters: {    filteredList: state = {      return state.list.filter(item = item  5)    }  }

组件中:

 computed: {      list() {        return this.$store.getters.filteredList;      }    }

mutation
提交更改数据的方法,同步!必须是同步函数
使用vuex修改state时,有两种方式:
1)可以直接使用 this.store.state.=xxx;2this.store.state.变量 = xxx;2)this.store.dispatch(actionType, payload)或者 this.$store.commit(commitType, payload)
action
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

const store = new Vuex.Store({ //store实例      state: {         count: 0             },      mutations: {                         increment (state) {          state.count++         }          },      actions: {          increment (context) {          context.commit('increment')   } }})

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

const moduleA = {  state: { ... },  mutations: { ... },  actions: { ... },  getters: { ... }}const moduleB = {  state: { ... },  mutations: { ... },  actions: { ... }}const store = new Vuex.Store({  modules: {    a: moduleA,    b: moduleB  }})store.state.a // - moduleA 的状态store.state.b // - moduleB 的状态

九、vue-cli如何新增自定义指令?
1.创建局部指令

var app = new Vue({    el: '#app',    data: {        },    // 创建指令(可以多个)    directives: {        // 指令名称        dir1: {            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);    
            
            

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎