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面试题集结号 公众号:捡田螺 ...
随机推荐
- java实现下载网络图片
package com.gylhaut.picture;import java.io.*;import java.net.MalformedURLException;import java.net.U ...
- Golang 语言特性
1. 函数 与c 语言不同,go 语言中,函数的参数和返回值都由栈来存储. 传值:函数调用时会复制参数,被调用方和调用方持有两份不相关的两份数据 传引用:函数调用时会传递参数指针,被调用方和调用方持有 ...
- 官宣 .NET 7 Preview 2
今天,我们很高兴发布 .NET 7 预览版 2..NET 7 的第二个预览版包括对 RegEx 源生成器的增强.将 NativeAOT 从实验状态转移到运行时的进展,以及对"dotnet n ...
- ARM中断与架构知识 精简知识点
目录 一.ARM系统的异常与中断 二.CPU模式与寄存器 1.ARM CPU模式 2.ARM CPU state,两种指令集 3.ARM CPU寄存器: 引申介绍一下存储空间中的数据存放 4.ARM三 ...
- LCT板子
粘板子: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; c ...
- ElasticSearch7.3学习(十五)----中文分词器(IK Analyzer)及自定义词库
1. 中文分词器 1.1 默认分词器 先来看看ElasticSearch中默认的standard 分词器,对英文比较友好,但是对于中文来说就是按照字符拆分,不是那么友好. GET /_analyze ...
- 学习廖雪峰的Git教程1
我是在Ubuntu上学习的,所以配置之类的进行的很快. 一.创建版本库 mkdir learngit cd learngit git init 用git init变成git可以管理的库 二.git a ...
- Docker提交镜像-数据卷-可视化
在熟悉完Docker的安装及基本命令使用之后,我们开始学习下Docker的进阶操作:包括但不限于新建Docker镜像,数据卷的挂载,以及Docker的可视化等. Docker提交镜像 启动镜像 我们先 ...
- 文档类型声明<!DOCTYPE html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- python 迭代器和生成器基础知识
1.迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法--字符串.列表.元组.字典.集合都是可迭代的--可以被for循环的都是可迭代的 2. 迭代器有的好处是可以节省内存 3.生 ...