vue、webpack、bable

vue

设计思想

  • vue专注于视图层面,便于与第三方库或既有项目整合,是一种渐进式的框架
  • vue是一种基于mvvm设计模式的一种思想
  • 基于组件化开发、提高代码复用率,提高代码维护
  • 声明式编码,无需直接操作dom,提高开发效率
  • vue的核心思想是数据驱动,组件化以及虚拟dom
  • 渐进式框架:只做自己该做的事情,不去做很多职责之外的事情,提供很多的操作,但是主张很少的引入。

mvvm设计思想

MVVM 是Model-View-ModelView的缩写,是一种脱胎于 MVC 模式的设计模式。

  • Model 代表数据层,负责存放业务相关的数据;
  • View 代表视图层,负责在页面上展示数据;
  • ViewModel 是的作用是同步 View 和 Model 之间的关联,其实现同步关联的核心是DOM Listeners和 Data Bindings两个工具。
  • DOMListeners 工具用于监听 View 中 DOM 的变化,并会选择性的传给 Model;
  • Data Bindings 工具用于监听 Model 数据变化,并将其更新给 View。

核心的几个点

响应式的数据绑定
组件化开发
Virtual DOM

单向绑定和双向绑定

Vue中有2种数据绑定的方式:

  • 单向绑定(v-bind):数据只能从data流向页面。
  • 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。

备注:

  • 双向绑定一般都应用在表单类元素上(如:input、select等)
  • v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。

Object.defineProperty

Object.defineProperty(person,'age',{
	// value:18,
	// enumerable:true, //控制属性是否可以枚举,默认值是false
	// writable:true, //控制属性是否可以被修改,默认值是false
	// configurable:true //控制属性是否可以被删除,默认值是false
	//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
	get(){
		console.log('有人读取age属性了')
		return number
	},
	//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
	set(value){
		console.log('有人修改了age属性,且值是',value)
		number = value
	}
})

computed /watch的区别

computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;

watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

运用场景:

  • 当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
  • 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

computed /methods的区别

  • computed 基于依赖进行缓存的,只有依赖发生改变是才会执行该函数
  • method总会执行该函数

v-show和v-if

  • 作用: 都是控制元素隐藏和显示的
  • 区别:
    • v-show: 控制的元素无论是true还是false,都被渲染出来了,通过display:none控制元素隐藏
    • v-if: 控制的元素是true,进行渲染,如果是false不渲染,根本在dom树结构中不显示
  • 应用:
    • v-show: 适合使用在切换频繁显示/隐藏的元素上
    • v-if: 适合使用在切换不频繁,且元素内容很多,渲染一次性能消耗很大的元素上

原理

  • v-if是动态的向DOM树内添加或者删除DOM元素; 当 v-if 指令对应的 value 为 false 的时候会预先创建一个注释节点在该位置,然后在 value 发生变化时,命中更新的逻辑,对新旧dom树进行 patch,从而完成使用 v-if 指令元素的动态显示隐藏。
  • v-show是通过设置DOM元素的display样式属性控制显隐使用了 v-if 的时候,如果值为 false ,那么页面将不会有这个 html 标签生成。
  • v-show 则是不管值为 true 还是 false ,html 元素都会存在,只是 CSS 中的 display 显示或隐藏

vuex

webpack

1. 讲讲webpack,作用是啥?

  • 模块打包。
    可以将不同模块的文件打包整合在一起,并且保证它们之间的引用正确,执行有序。利用打包我们就可以在开发的时候根据我们自己的业务自由划分文件模块,保证项目结构的清晰和可读性。

  • 编译兼容。
    通过webpack的Loader机制,不仅仅可以帮助我们对代码做polyfill,还可以编译转换诸如.less, .vue, .jsx这类在浏览器无法识别的格式文件,让我们在开发的时候可以使用新特性和新语法做开发,提高开发效率。

  • 能力扩展。
    通过webpack的Plugin机制,我们在实现模块化打包和编译兼容的基础上,可以进一步实现诸如按需加载,代码压缩等一系列功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。

webpack基本概念

在了解 Webpack 原理前,需要掌握以下几个核心概念,以方便后面的理解:

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
  • Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
  • Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。

三种哈希:

  • hash:跟整个项目的构建相关,构建生成的文件hash值都是一样的,只要项目里有文件更改,整个项目构建的hash值都会更改。

  • chunkhash:根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的hash值。

  • contenthash:由文件内容产生的hash值,内容不同产生的contenthash值也不一样

webpack构建流程

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

  1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
  2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  3. 确定入口:根据配置中的 entry 找出所有的入口文件;
  4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块 依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
  5. 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

2. webpack打包原理

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

5. 分割?多入口 =》merge

6. 抽离CSS、=》MiniCssExtractPlugin.loader,

7. 抽离公共代码=》 为啥抽离,第三方和公共模块 =》 splitChunks

9. 聊了下 babel,babel-ployfill,babel-runtime (为啥需要babel,babel-ployfill又干了啥?,babel-runtime知道嘛?)

3.有哪些常见的Loader?他们是解决什么问题的?

  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
  • url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一
  • source-map-loader:加载额外的 Source Map 文件,以方便断点调试
  • image-loader:加载并且压缩图片文件
  • babel-loader:把 ES6 转换成 ES5
  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
  • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
  • eslint-loader:通过 ESLint 检查 JavaScript 代码

4.有哪些常见的Plugin?他们是解决什么问题的?

define-plugin:定义环境变量
commons-chunk-plugin:提取公共代码
uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码
htmlwebpackplugin:

  • 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
  • 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口

5.Loader和Plugin的不同?

不同的作用

  • Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
  • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

不同的用法

  • Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
  • Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

是否写过Loader和Plugin?描述一下编写loader或plugin的思路?

  • Loader像一个"翻译官"把读到的源文件内容转义成新的文件内容,并且每个Loader通过链式操作,将源文件一步步翻译成想要的样子。

  • 编写Loader时要遵循单一原则,每个Loader只做一种"转义"工作。 每个Loader的拿到的是源文件内容(source),可以通过返回值的方式将处理后的内容输出,也可以调用this.callback()方法,将内容返回给webpack。 还可以通过 this.async()生成一个callback函数,再用这个callback将处理后的内容输出出去。 此外webpack还为开发者准备了开发loader的工具函数集——loader-utils。

  • 相对于Loader而言,Plugin的编写就灵活了许多。 webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

如何在vue项目中实现按需加载?

通过import()语句来控制加载时机,webpack内置了对于import()的解析,会将import()中引入的模块作为一个新的入口在生成一个chunk。 当代码执行到import()语句时,会去加载Chunk对应生成的文件。import()会返回一个Promise对象,所以为了让浏览器支持,需要事先注入Promise polyfill

webpack的热更新是如何做到的?说明其原理?

webpack的热更新又称热替换(Hot Module Replacement),缩写为HMR。 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。

首先要知道server端和client端都做了处理工作

  • 第一步,在 webpack 的 watch 模式下,文件系统中某一个文件发生修改,webpack 监听到文件变化,根据配置文件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。

  • 第二步是 webpack-dev-server 和 webpack 之间的接口交互,而在这一步,主要是 dev-server 的中间件 webpack-dev-middleware 和 webpack 之间的交互,webpack-dev-middleware 调用 webpack 暴露的 API对代码变化进行监控,并且告诉 webpack,将代码打包到内存中。

  • 第三步是 webpack-dev-server 对文件变化的一个监控,这一步不同于第一步,并不是监控代码变化重新打包。当我们在配置文件中配置了devServer.watchContentBase 为 true 的时候,Server 会监听这些配置文件夹中静态文件的变化,变化后会通知浏览器端对应用进行 live reload。注意,这儿是浏览器刷新,和 HMR 是两个概念。

  • 第四步也是 webpack-dev-server 代码的工作,该步骤主要是通过 sockjs(webpack-dev-server 的依赖)在浏览器端和服务端之间建立一个 websocket 长连接,将 webpack 编译打包的各个阶段的状态信息告知浏览器端,同时也包括第三步中 Server 监听静态文件变化的信息。浏览器端根据这些 socket 消息进行不同的操作。当然服务端传递的最主要信息还是新模块的 hash 值,后面的步骤根据这一 hash 值来进行模块热替换。

  • webpack-dev-server/client 端并不能够请求更新的代码,也不会执行热更模块操作,而把这些工作又交回给了 webpack,webpack/hot/dev-server 的工作就是根据 webpack-dev-server/client 传给它的信息以及 dev-server 的配置决定是刷新浏览器呢还是进行模块热更新。当然如果仅仅是刷新浏览器,也就没有后面那些步骤了。

  • HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上一步传递给他的新模块的 hash 值,它通过 JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回一个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。这就是上图中 7、8、9 步骤。

  • 而第 10 步是决定 HMR 成功与否的关键步骤,在该步骤中,HotModulePlugin 将会对新旧模块进行对比,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。

  • 最后一步,当 HMR 失败后,回退到 live reload 操作,也就是进行浏览器刷新来获取最新打包代码。

模块化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值