前端面试之Vue专题

news2024/11/24 0:24:13

目录

前言

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.ageA.age也会相应地变;修改A.ageB.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`
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

非项目活动的时间怎么跟踪?

会计、审计、合规和专业服务企业通常需要跟踪花费在项目和非项目上的时间以进行报告。员工可以使用8Manage工时表这样的工具来获取与项目和非项目任务相关的工作时间,并记录管理时间。 非项目时间类别确定在项目工作之外发生的不同类型的活动。你可以在工时表解决方…

【网络篇】第六篇——网络套接字编程(二)(UDP详解)

基于UDP协议的套接字程序 服务端 服务端创建套接字 服务的绑定 字符串IP VS 整数IP 运行服务器 客户端 客户端创建套接字 客户端绑定 启动客户端 本地测试 INADDR_ANY 简易的回声服务器 网络测试 基于UDP协议的套接字程序 服务端 服务端创建套接字 我们把服务…

重学Android基础系列篇(三):架构动态编程技术原理

前言 本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握java和android,本期就来说说这些~ [非商业用途,如有侵权,请告知我,我会删除] DD一下: And…

基于形状的匹配提纲

关键:形状,其实就是canny找出来的线条集合 1,canny线条 2,模板的线条(基于canny) 3,高斯金字塔,加速高斯法 4,没有旋转和尺度时,匹配一个有得分的结果&am…

Linux-vim使用

目录 基本vim的基本操作: 命令模式: 光标定位: $:光标定位到行右: ^:光标定位到左: shiftgG:光标定位到底部 gg:回到顶部 nshiftg表示跳转光标到第n行 文本复制相关…

输入学生的信息学号、姓名、语文成绩、数学成绩、英语成绩,计算总分、并按总分成绩排序,再写到另一个txt文件中(python)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 题目: 代码: 1.提前写入标题栏(学号、姓名、语文、数学、英语、总分) 2.再写入学生的信息 3.读取score2.txt文件 4.…

机器学习西瓜书学习记录-第五章 神经网络

第5章 神经网络 5.1神经元模型 神经网络中最基本的成分是神经元模型。 “M-P神经元模型”,又称“阈值逻辑单元” 在模型中,神经元接收到来自n个其他神经元传递过来的输入信号,这些输入信号通过带权重的连接进行传递,神经元接收到…

分分钟让你学会栈和队列

数据结构——栈和队列 🏖️专题:数据结构 🙈作者:暴躁小程序猿 ⛺简介:双非本科大二小菜鸟一枚,希望我的博客可以对大家有所帮助 文章目录数据结构——栈和队列前言一、什么是栈?二、栈的相关概…

计算机毕设(附源码)JAVA-SSM蓟县农家乐网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

算法竞赛进阶指南 搜索 0x26 广搜变形

双端队列BFS 在最基本的广度优先搜索中,每次沿着分支的扩展都记为“一步”,我们通过逐层搜索,解决了求从起始状态到每个状态的最少步数的问题。这其实等价于在一张边权均为1的图上执行广度优先遍历,求出每个点相对于起点的最短距…

程序员的数学好难学?一切从基础开始!

数学知识对编程很有用,但是很多写给程序员的数学书都比较难。我们为什么不从基础的数学知识开始学习呢? 程序员的数学基础 Python实战 1.本书的重点不在于如何解题,而在于帮助读者在计算机世界里如何利用数学解决算法问题,让程序…

WinForm应用实战开发指南 - 教你如何实现表头的全选操作?

WinForms分页控件,在很多场合都需要用到,由于整合较多的功能操作,使用起来效果更好,界面统一性也比较一致。其中的勾选操作,在有些场合下,也是比较有用的,因此提供该功能的整合。 PS&#xff1…

基于改进神经网络的风电功率预测(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑…

【K8S系列】Kubernetes 之kubectl 常用命令汇总

目录 一、kubetcl简单介绍 二、命令介绍 详细介绍: 三、部分命令详细介绍 3.1 create 3.2 get 3.3 describe 3.4 rolling-update 3.5 exec 3.6 log kubectl 是 Kubernetes 自带的客户端,可以用它来直接操作 Kubernetes 集群。 日常在使用 Kuber…

Swift 周报 第十六期

前言 本期是 Swift 编辑组自主整理周报的第七期,每个模块已初步成型。各位读者如果有好的提议,欢迎在文末留言。 欢迎投稿或推荐内容。目前计划每两周周一发布,欢迎志同道合的朋友一起加入周报整理。 当你来到双水村以外的大世界&#xff…

操作系统实验二死锁避免之银行家算法的模拟

文章目录 死锁 (1)定义 (2)死锁产生的原因 (3)死锁产生的必要条件 (4)死锁的处理策略 银行家算法 (1)核心思想 (2)数据结构 &#x…

2.2 Pycharm 的使用

文章目录1. PyCharm 安装2. Python 项目3. 外貌设置4. 配色方案5. 字体大小6. 自动换行7. 汉化8. 翻译插件9. 添加多个解释器10. Pycharm 常用快捷键11. 自定义文件模板内容12. 前端代码运行浏览器13. 关闭 with open 提示14. 双击shift查找15. 导出配置导入配置1. PyCharm 安装…

Gwas实战分析3_群体结构增加

1.sh plink 格式转化 plink1.map/plink1.ped ------plink2.bim/fam/bed plink --file 1001genomes_snps_only_ACGTN1 --make-bed --out plink2 2.sh 群体结构分析 时间过久: for K in 2 3 4 5 6 7 8 9 10; do admixture --cv plink2.bed K∣teeadmixtrueK | tee…

HTML小游戏4 —— 简易版英雄联盟(附完整源码)

💂 网站推荐:【神级源码资源网】【摸鱼小游戏】🤟 风趣幽默的前端学习课程:👉28个案例趣学前端💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】💬 免费且实用的计算机相关知…

基于C#实现的在线聊天室的桌面系统软件

资源下载地址:https://download.csdn.net/download/sheziqiong/86863237 资源下载地址:https://download.csdn.net/download/sheziqiong/86863237 目录 个人聊天室软件 1 需求分析与概要设计 1 项目说明 1 1.1. 项目目标: 1 1.2. 软硬件环境…