前端面试之Vue专题
创始人
2024-04-02 10:14:14
0

目录

前言

MVVM模式

Vue的响应式原理

路由守卫


前言

网上有许多前端八股文,但是缺少便于理解的说明和案例,需要自行查阅资料。这篇文章我就按照面试的高频题来记录自己的理解和实操。

MVVM模式

一、三者含义

M是Model,数据模型;V是View,视图;VM是ViewModel,视图模型。

二、三者关系

VM是M和V的桥梁,可以和M、V进行双向数据传输。

1、M与VM之间,可以通过axios发送数据和接收数据。

2、V与VM之间,可以通过ES5的Object.defineProperty或ES6的Proxy方法实现数据的双向绑定。

Vue的响应式原理

一、场景

理解Vue的响应式原理能够帮助理解MVVM的运作方式

二、原理

Vue是通过Object.defineProperty()来劫持各个属性的setter和getter,结合发布者-订阅者模式,在数据变动时发布消息给订阅者,触发相应的监听回调,从而实现数据的双向绑定。

三、理解

首先我们得搞懂双向绑定具体是怎么回事。我们说A和B双向绑定了,那么A改变,B也跟着改变;B改变,A也跟着改变。这里面涉及修改(set)和获取(get)两个重要的操作(你可能会想到增加和删除这两个操作,后面再说)。而恰好ES5提供的Object.defineProperty方法可以做到。

1、Object.defineProperty的基本使用

首先我们来了解一下Object.defineProperty的基本用法。假设我们有对象A和对象B,我们希望通过A就可以调用B的某个属性,比如age。

let A = {age: 10
};let B = {};// 参数含义:给person对象,添加“age”属性,后面的{}是对“age”属性的配置
Object.defineProperty(B, "age", {// 4个常用属性:属性的值、是否能枚举、是否能修改、是否能删除// value: 18,// enumerable: true,    // 代表age可被枚举// writeable: true,     // 代表age可被修改// configurable: true,  // 代表age可被删除// 这函数就是getter,当“B.age”属性被获取时调用get(){console.log("获取: " + A.age);return A.age;},// 这函数就是setter,当“B.age”属性被修改时调用set(value){console.log("修改:" + A.age + " 被改成 " + value);A.age = value;}
});

你会发现,修改B.age,A.age也会相应地变;修改A.age,B.age也会相应地变。不同的是,只有修改B.age才能触发setter和getter,也就是说通过B才能实现对A的age属性的劫持。

但通常来说,对象有很多个属性,于是就用Object.keys方法遍历一次对象A的属性,让A的所有属性都被绑定到B上。

let A = {name: "hillbox",    // String型age: 10,            // Number型isGirl: true        // Boolean型
};let B = {};Object.keys(A).forEach(function (key) {Object.defineProperty(B, key, {get() {console.log("获取: " + A[key]);// 这里用[]而不是.是因为key是变量而不是字符串return A[key];},set(value) {console.log("修改:" + A[key] + " 被改成 " + value);A[key] = value;}})
});

打印A对象、B对象,如下:

 这里我们操作A对象的属性,就会修改B对象的属性,反之亦然。同样地,只有操作A的属性,才会触发getter和setter,依然是通过A才能实现对B的数据劫持。

这一小节希望读者已经知道Object.defineProperty如何使用了吧~

2、双向绑定

上面的例子,我们总需要一个现成的对象A,再将所有属性绑到另一个对象B上,这样就可以通过对象B触发setter和getter来劫持A的属性了。但是这样有些麻烦,能不能在对象A的每个属性上直接触发setter和getter,省去对象B这个“中介”呢?我有想过直接把绑定好的对象B赋值给对象A。

A = B;

 结果在操作person的属性时,报了栈溢出的错误。 

这是因为在获取属性的时候getter被触发,而return语句中的A[key]又会继续触发getter,无限循环调用,出不来了。那肯定得想出个解决办法。

Vue是使用Observer类来解决的。字面意思也能看出它扮演观察者的角色,和前面的B有相同的作用,但是并不会引起栈溢出错误。 

let A = {name: "hillbox",    // String型age: 10,            // Number型isGirl: true        // Boolean型
};// 创建person对象对应的“观察者”实例对象
const obs = new Observer(A);
A = obs;// Observer类
function Observer(obj){// 对象的所有属性const keys = Object.keys(obj);// 遍历每个属性keys.forEach((key) => {// this代表当前Observer实例Object.defineProperty(this, key, {get() {console.log("获取: " + obj[key]);return obj[key];},set(value) {console.log("修改:" + obj[key] + " 被改成 " + value);obj[key] = value;}})});
}

 打印A,如下: 

就很奇怪,为什么对象B不行,而Observer类的实例对象obs就可以呢。

且听下回分解。

路由守卫

一、场景

我们希望路由跳转时会触发相应的事件,比如登录权限验证。

二、分类

全局守卫、独享守卫、组件守卫

1、全局守卫:

场景:为网站的所有路由配置守卫

分类:全局前置守卫、全局解析守卫、全局后置守卫

// main.js 入口文件
import router from './router'; // 引入路由// 1、全局前置守卫,进入路由之前调用
router.beforeEach((to, from, next) => { // to是将要进入的路由,from是将要离开的路由next();
});// 2、全局解析守卫,在beforeRouteEnter调用之后调用
router.beforeResolve((to, from, next) => {next();
});// 3、全局后置守卫,进入路由之后调用
router.afterEach((to, from) => {console.log('afterEach 全局后置钩子');
});

2、独享守卫

场景:单独为某个路由配置守卫。

const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => { // 调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖}}]
})

3、组件守卫

场景:相当于给组件添加生命周期钩子

分类:路由进入前、路由更新前、路由离开前

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

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...