3道常见的vue面试题,你都会了吗?
最近流传各大厂纷纷裁员,导致很多人“被迫”毕业,显然很多人还是想留级,无奈出现在名单中,只能感叹命运不公,不过拿了N+1,也算是很欣慰。
又得去面试了,接下来一起来巩固下vue的3道面试题吧!
computed 实现原理
computed 计算属性,有两种定义方式,一种是方法,另一种是 get,set 属性。并且 computed 监听的对象必须是已经在 data 定义的属性
Vue 在创建 computed 属性时候,会循环所有计算属性,每一个计算属性会创建一个 watch,并且在通过 defineProperty 监听,在 get 中,计算属性工作是做依赖收集,在 set 中,计算属性重要工作是重新执行计算方法
computed 是懒执行,也就是说第一次初始化之后,不会执行计算,下一次变更执行重新计算是在 set 中
computed 收集时机和 data 一样,是在组件挂载前,但是其收集对象是自己属性对应的 watch,而 data 本身所有数据对应一个 watch
具体可以查看 computed 的实现源码,这里移除服务端渲染相关逻辑
function initComputed(vm: Component, computed: Object) {
const watchers = (vm._computedWatchers = Object.create(null));
for (const key in computed) {
const userDef = computed[key];
const getter = typeof userDef === "function" ? userDef : userDef.get;
if (process.env.NODE_ENV !== "production" && getter == null) {
warn(`Getter is missing for computed property "${key}".`, vm);
}
// 计算属性独享watcher
watchers[key] = new Watcher(vm, getter || noop, noop, computedWatcherOptions);
// 在实例化Watcher后,开始对计算属性进行响应式处理
if (!(key in vm)) {
defineComputed(vm, key, userDef);
} else if (process.env.NODE_ENV !== "production") {
if (key in vm.$data) {
warn(`The computed property "${key}" is already defined in data.`, vm);
} else if (vm.$options.props && key in vm.$options.props) {
warn(`The computed property "${key}" is already defined as a prop.`, vm);
}
}
}
}
接下来看 defineComputed 源码
if (typeof userDef === "function") {
sharedPropertyDefinition.get = createComputedGetter(key);
sharedPropertyDefinition.set = noop;
} else {
sharedPropertyDefinition.get = userDef.get ? createComputedGetter(key) : noop;
sharedPropertyDefinition.set = userDef.set || noop;
}
Object.defineProperty(target, key, sharedPropertyDefinition);
接下来看 createComputedGetter 函数,获取计算属性对应的 watcher,如果 dirty 是 true,则计算值,并收集依赖
function createComputedGetter(key) {
return function () {
// 获取到相应 key 的 computed-watcher
var watcher = this._computedWatchers[key];
// 如果 computed 依赖的数据变化,dirty 会变成true,从而重新计算,然后更新缓存值 watcher.value
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
watcher.depend();
}
return watcher.value;
};
}
接下来,在 Watcher 类中找到 evaluate,执行 get 方法,并设置 dirty 为 false
evaluate () {
this.value = this.get()
this.dirty = false
}
get() 方法的定义如下,在这里执行计算过程,并返回。
Watcher.prototype.get = function () {
// 改变 Dep.target
pushTarget();
// getter 就是 watcher 回调
var value = this.getter.call(this.vm, this.vm);
// 恢复前一个 watcher
popTarget();
return value;
};
Dep.target = null;
var targetStack = [];
function pushTarget(_target) {
if (Dep.target) {
targetStack.push(Dep.target);
}
Dep.target = _target;
}
function popTarget() {
Dep.target = targetStack.pop();
}
看完了 watcher.evaluate() 接下来看 depend() 方法定义
Watcher.prototype.depend = function () {
var i = this.deps.length;
while (i--) {
dep.addSub(Dep.target);
}
};
这里看出 watcher 的 deps 存储的就是 Dep.target 的数组,没错,就是依赖属性的收集,整个过程就到此完成。
vue-loader 的作用
vue-loader 是 Webpack 的 loader 模块,它使我们可以用 .vue 文件格式编写单文件组件。
单文件组件文件有三个部分,即模板(template)、脚本(script)和样式(style)。
vue-loader 模块允许 webpack 使用单独的加载器模块(例如 SASS 或 SCSS 加载器)提取和处理每个部分。该设置使我们可以使用 .vue 文件无缝编写程序。
vue-loader 模块还允许把静态资源视为模块依赖性,并允许使用 webpack 加载器进行处理。而且还允许在开发过程中进行热重装。
Vue 插件的功能
插件通常用来为 Vue 添加全局功能。有如下用途
- 添加全局方法或者 property。如:vue-custom-element
- 添加全局资源:指令/过滤器/过渡等。如 vue-touch
- 通过全局混入来添加一些组件选项。如 vue-router
- 添加 Vue 实例方法,通过把它们添加到
Vue.prototype上实现。 - 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
如何自定义 Vue 插件
Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或 property
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 注入组件选项
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
写在最后
如果文中内容对你有帮助, 记得三连~ 如文中有错误,也欢迎大家指正修改!
更多前端面经,尽在 www.1024nav.com
禁止转发
3道常见的vue面试题,你都会了吗?的更多相关文章
- 常见的vue面试题
001.v-show与v-if的区别v-show:操作的是元素的display属性 v-if:操作的是元素的创建和插入相比较而言v-show的性能要高 002.methods.computed.wat ...
- 几百道常见Java初中级面试题
注: 有的面试题是我面试的时候遇到的,有的是偶然看见的,还有的是朋友提供的, 稍作整理,以供参考.大部分的应该都是这些了,包含了基础,以及相对深入一点点的东西. JAVA面试题集 基础知识: ...
- 七道常见的Redis面试题分享(含个人解答)
绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.这里以面试题的形式对 Redis 常见问题做 ...
- 2019前端面试系列——Vue面试题
Vue 双向绑定原理 mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...
- 一些常见的Java面试题 & 面试感悟
< 前言 > 近期在面试,深感这个行业的浮躁,一些菜不辣基的弱鸡开出的工资待遇要求,超过了我.不知道他们是怎么拿到那么高的工资的,难道是他在公司有亲戚朋友吗?有后台吗?是行业热钱真的过多了 ...
- 100多道经典的JAVA面试题及答案解析
面向对象编程(OOP) Java是一个支持并发.基于类和面向对象的计算机编程语言.下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码 ...
- 松哥整理了 15 道 Spring Boot 高频面试题,看完当面霸
什么是面霸?就是在面试中,神挡杀神佛挡杀佛,见招拆招,面到面试官自惭形秽自叹不如!松哥希望本文能成为你面霸路上的垫脚石! 做 Java 开发,没有人敢小觑 Spring Boot 的重要性,现在出去面 ...
- 15 道 Spring Boot 高频面试题,看完直接当面霸【入门实用】
前言 本文转自松哥(网名:江南一点雨)的一篇实用入门文章,写的挺好的,希望对各位有所帮助. 什么是面霸?就是在面试中,神挡杀神佛挡杀佛,见招拆招,面到面试官自惭形秽自叹不如!松哥希望本文能成为你面霸路 ...
- 100道MySQL数据库经典面试题解析(收藏版)
前言 100道MySQL数据库经典面试题解析,已经上传github啦 https://github.com/whx123/JavaHome/tree/master/Java面试题集结号 公众号:捡田螺 ...
随机推荐
- FreeBSD 利用IPFW实现限制局域网使用QQ
QQ服务器分为三类: 1.UDP 8000端口类7个:速度最快,服务器最多.QQ上线会向这7个服务器发送UDP数据包,选择回复速度最快的一个作为连接服务器.这7个服务器名字均以sz-sz7开头,域后缀 ...
- spring——AOP(静态代理、动态代理、AOP)
一.代理模式 代理模式的分类: 静态代理 动态代理 从租房子开始讲起:中介与房东有同一的目标在于租房 1.静态代理 静态代理角色分析: 抽象角色:一般使用接口或者抽象类来实现(这里为租房接口) pub ...
- Mybatis结果集ResultMap映射
基本使用: 解决属性名和数据库字段名不一致的问题 <resultMap id="user" type="com.guan.bean.UserBean"&g ...
- Python3输出九九乘法表
for i in range(1,10): for j in range(1,i+1): print('{}x{}={}\t'.format(i, j, i*j), end='') #format格式 ...
- RabbitMQ Go客户端教程1——HelloWorld
本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,共分为六篇,本文是第一篇--HelloWorld. 这些教程涵盖了使用RabbitMQ创建消 ...
- [Lua游戏AI开发指南] 笔记零 - 框架搭建
一.图书详情 <Lua游戏AI开发指南>,原作名: Learning Game AI Programming with Lua. 豆瓣:https://book.douban.com/su ...
- JDK8新特性关于Stream流
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: 1 2 3 ...
- Ajax的核心的对象是什么?
Ajax的核心对象是XMLXMLHttpRequest 对象. XMLHttpRequest提供不重新加载页面的情况下更新网页,在页面加载后在客户端向服务器请求数据,在页面加载后在服务器端接受数据,在 ...
- 调用高德地图web api 规划路线
实现地图输出,出发地与目的地路线,效果如下 具体代码如下 <!doctype html> <html> <head> <meta charset=" ...
- fsdfd
static int kWeiOfVal(int val, int k) { int n = 1; int temVal = val; int result; while (1) { temVal = ...