意林的小站

Be a cool girl ~


  • 首页

  • 分类

  • 归档

  • 标签

  • 项目

  • 关于

vuex.js源码学习 —— 初始化与实例方法

发表于 2020-03-20 | 分类于 Web , Vue

官方文档中对Vuex的描述如下:

Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex 和 Redux 都是对Flux架构的实现,不同的是 Redux 是不需要感知视图层的,一个单纯的独立的状态管理工具,只要你愿意完全可以在 Vue 项目中使用 Redux 进行状态管理。

我们知道一个store由state、getters、mutations、actions、modules几部分构成,它们之间的关系如下图所示:

今天这篇文章我们主要来看一下当接收到这些选项后,Vuex 是如何来处理它们的,最后看一下常用的实例方法commit和dispatch的实现过程。

我没有在文中大量的贴源代码,一定要将代码 clone 到本地对着看哦。

阅读全文 »

vue-router.js源码学习 —— 导航守卫

发表于 2020-03-16 | 分类于 Web , Vue

这篇文章接着上一篇vue-router.js源码学习 —— 路由匹配,也是 Vue Router 的核心部分,我们会重点来看一下导航解析的整个过程的实现,最后来过一下hash和history模式下是如何实现路由跳转的。

Vue Router 提供了 3 种路由跳转模式:hash、history和abstract。实现的代码位于文件夹history中,每种模式单独用一个类来实现,但都继承于History基类。abstract是给服务端渲染时使用的,从history/abstract.js文件中可以看到,AbstractHistory类内部自己维护了一个路由对象的栈,来模拟导航。我们今天主要看hash和history两种路由模式的实现。

阅读全文 »

vue-router.js源码学习 —— 路由匹配

发表于 2020-03-13 | 分类于 Web , Vue

在上一篇文章vue-router.js源码学习 —— 初识Vue Router我们大致看了 Vue Router 运行的主要流程,以及<router-link>和<router-view>的实现,几乎是把 Vue Router 的 API 都过了一遍。今天我们来看一下核心部分路由与组件匹配的实现。

matcher这一部分代码相对独立,不依赖其他部分,代码位于文件src/create-matcher.js中。我们先来缕清楚matcher被创建和使用的地方,这样再去分析会目标明确一些。

之前在讲VueRouter的构造函数时,曾遇到过创建matcher:

1
2
3
4
5
6
7
8
9
export default class VueRouter {
// ...
constructor (options: RouterOptions = {}) {
// ...
this.matcher = createMatcher(options.routes || [], this)
// ...
}
// ...
}

是在这里调用createMatcher函数创建了matcher对象,并传了两个参数:开发者传入的routes选项,和router本身。

阅读全文 »

vue-router.js源码学习 —— 初识Vue Router

发表于 2020-03-10 | 分类于 Web , Vue

在开发复杂的单页应用时一般都会使用到Vue Router,Vue Router 使得开发 Web 应用的体验和开发原生应用很像,原生应用的系统一般都会自带对页面栈管理的对象,可以方便地在页面之间跳转,却不用重新刷新页面。

今天这篇文章我们先来了解一下 Vue Router,会主要分析它的install函数,VueRouter类,以及<router-linker>和<router-view>的实现过程。内容有点多,文章稍长,不过把这些都搞明白后,熟练使用 Vue Router 应该没有问题。

准备工作

一边调试源码一边分析的效率会高很多,所以我们先看一下如何通过自己写的例子调试到源代码。

阅读全文 »

Vue.js源码学习 —— 初识编译器

发表于 2020-02-22 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

从今天这篇文章开始我们将分析 Vue 编译器部分的代码,这也是一个相对比较独立的模块。我们今天先通过编译器的入口函数一步一步找到它所以实现的地方,每到一步会说一下在这一步做的事情,这样对编译器的实现先建立一个整体印象。

我不会在文章中大量地粘贴源代码,您还是一定要将Vue工程clone到本地哦。

编译器的目录

项目中与编译器相关的有两部分,一部分是编译器的核心实现,代码位于文件夹compiler中。其中子文件夹中放置的内容如下:

  • codegen:生成render函数的代码。

  • directives:生成跨平台的指令的代码,包括:v-model、v-bind、v-on。

  • parser:解析模板字符串,生成 AST。

还有一部分是与平台特性相关的,每个平台的文件夹下也都有一个compiler文件夹,后面的分析我们都以web平台为主。文件夹platforms/web/compiler中的子文件夹的内容如下,下一节我们会看到这些功能是如何提供给编译器的核心实现部分的。

  • directives:生成与平台相关的指令的代码,包括:v-html、v-model、v-text。

  • modules:与平台相关的几个模块的特殊处理和代码生成,包括:v-bind:class、v-bind:style和对input[v-model]动态类型绑定的转换。

阅读全文 »

Vue.js源码学习 —— 各全局API的实现

发表于 2020-02-18 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

今天我们来看一下 Vue 为开发者提供的各全局API的实现,大部分其实我们都已经遇到了,有的也分析过了实现过程,这篇文章我将其放在一起,这样可以从总体上有一个感观印象。

为开发者提供的全局API都可以在文件夹core/global-api中找到,我们打开文件core/global-api/index.js看一下。这里对外提供了一个initGlobalAPI函数,初始化了所有的全局API,可以看到,全局API其实是放在Vue构造器本身上的。

Vue.config

与Vue.config相关的代码如下:

1
2
3
4
5
6
7
8
9
10
11
// config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== 'production') {
configDef.set = () => {
warn(
'Do not replace the Vue.config object, set individual fields instead.'
)
}
}
Object.defineProperty(Vue, 'config', configDef)
阅读全文 »

Vue.js源码学习 —— 事件机制

发表于 2020-02-15 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

今天我们来看一下 Vue 中的事件机制,代码位于文件core/instance/events.js中。其实 Vue 的事件机制就是实现了 EventBus,从官方提供的API也可以看出这一点:vm.$on、vm.$emit、vm.$off。EventBus有时也叫 事件总线,是对发布/订阅模式的实现。第一次听到这个词还挺新鲜的,仔细琢磨后发现其实跟 iOS 中的 NSNotification 是一样的,你可以发送一个事件给 EventBus,但并不需要关心谁会来处理这个事件,也不用关心有多少个人会来处理这个事件。同样地,你也可以监听 EventBus 中的某个事件,也不需要关心是谁发过来的,收到消息后处理就完事儿了。

我们完全可以将一个 Vue 实例只当作 EventBus 来使用,来看个例子,下面的代码放在一个html中即可测试:

阅读全文 »

Vue.js源码学习 —— v-model

发表于 2020-02-11 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

这篇文章我们主要分析一下v-model的背后都做了什么事情,然后我们再结合之前讲的响应系统总结一下,Vue 是如何来实现 MVVM 架构模式的。

关于指令

到目前为止我们看到项目中有两处是与 指令 有关的,我在文章Vue.js源码学习 —— patch中对此进行了介绍,推荐过去看一下,顺便也可以了解一下指令的这几个钩子函数是如何被触发的。

自定义指令

我们知道 Vue 是允许开发者自定义指令的,通过这种方式提供了一个可以让开发者直接操作真实DOM元素的途径。使用全局 API Vue.directive 注册全局指令,使用directives选项注册局部指令。实现一个指令的关键点就是提供如下几个钩子函数(均为可选的):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入到父节点时调用(仅保证父节点存在,但不一定已被插入文档)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

关于指令更多的介绍,以及对这些钩子函数的参数说明,可以查阅Vue官方文档。

阅读全文 »

Vue.js源码学习 —— 数据选项的初始化

发表于 2020-02-08 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

今天这篇文章会看一下Vue中数据选项的初始化,包括props、methods、data、computed、watch等选项,代码主要位于文件core/instance/state.js中。选项的初始化与响应系统有很大关系,所以建议先看一下本系列的前两篇文章,这样会对今天要看的代码有更好地理解。

我不会在文中大量地贴源代码,您一定要将Vue工程clone到本地哦。

initState

initState我们曾在Vue.prototype._init方法中看到过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
// ...
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')

// ...
}
}
阅读全文 »

Vue.js源码学习 —— 组件的更新

发表于 2020-02-04 | 分类于 Web , Vue

如果您是刚开始准备阅读Vue.js的源码,建议先看一下本系列的Vue.js源码学习 —— 起步,相信会对您后面的阅读有很大帮助。

这篇文章是承接上一篇Vue.js源码学习 —— 响应系统的设计的,如果没有看过也建议您看一下,有了前面的这些铺垫理解起来今天的内容很轻松很多。

之前在说组件的渲染和生命周期时我们都把组件的更新跳过去了,现在了解了Vue的响应系统是如何设计的了,我们可以来看一下在数据改变时,Vue是如何去触发组件重新渲染的。这里涉及到异步更新队列和nextTick的实现。

我们之前在讲Watcher实例的update方法时,看到有3种情况:

1
2
3
4
5
6
7
8
9
10
11
update () {
/* istanbul ignore else */
if (this.lazy) {
// 计算属性使用
this.dirty = true
} else if (this.sync) {
this.run()
} else {
queueWatcher(this)
}
}

其实呢,大部分情况都会走到最后的else分支,也就是异步地计算表达式的值。所以今天咱们就从queueWatcher函数开始看去。

我不会在文章中大量地粘贴源代码,您还是一定要将Vue工程clone到本地哦。

阅读全文 »
12…8
意林

意林

78 日志
15 分类
91 标签
GitHub 微博 豆瓣
© 2020 意林
由 Hexo 强力驱动
主题 - NexT.Mist