深入浅出学 Vue 开发

课程介绍

前端技术日新月异,每一种新的思想出现,都代表了一种技术的跃进、架构的变化,那么对于目前的前端技术而言,MVVM 的思想已经可以代表当今前端领域的前沿思想理念,Angular、React、Vue 等基于 MVVM 思想的具体实现框架,也成为了人们争相学习的一个热点。而 Vue 作为其中唯一没有大公司支持但却能与它们并驾齐驱并且隐隐有超越同类的趋势,不得不说这种增长让人感到惊奇。

本系列课程内容将会带领大家由浅入深的学习 Vue 的基础知识,了解 Vue 的源码设计和实现原理,和大家一起看一下尤雨溪先生的编程思想、架构设计以及如何进行代码实现。本系列课程内容主要分为三大部分:

  • Vue 的基础知识:在这一部分将学习 Vue 的基础语法及其源码的实现。例如,Vue 的生命周期钩子如何设计?当声明了一个 directive 时,Vue 究竟执行了什么?为什么只有通过 vue.set 函数才能为响应式对象添加响应式属性?如果我们自己要实现一个响应式的框架的话,应该如何下手、如何思考等。
  • Vue 的周边生态:在这一部分将学习 Vue 的周边生态圈,包括有哪些 UI 库可以和 Vue 配合快速构建界面、如何使用 vue-router 构建前端路由、如何使用 Vuex 进行状态管理、如何使用 Axios 进行网络请求、如何使用 Webpack、使用 vue-cli 构建出的项目里的各种配置有什么意义?
  • 项目实战:在这一部分将会通过一个有意思的自动对话系统来进行项目实战,争取通过这个小项目把学到的知识点进行一个整合。

作者介绍

刘国栋,资深软件开发工程师、慕课网认证讲师、开源爱好者,目前就职于济南某国企,并且成立了个人工作室,负责前端和移动端的工作。拥有 5 年前端、移动端开发经验,在 JS、Android、iOS 领域有独特的见解,统筹过的多个项目用户数已过千万。

课程内容

导读:为什么选择 Vue

读者朋友们好,很高兴选择这门课程来学习,作为撰写者的我,也感到非常的荣幸。

程序人生

我们选择了这个 IT 行业,自然希望能够在这里走得更远。我相信没有任何一个人会甘于平庸,大家都希望能够在自己所处的行业以及所处的领域中有所建树,希望可以实现自己的价值,以获取社会的认可。而如果要实现这个目标的话,我们将要投入更多的时间和精力,才能博得更多的机会。在成长的过程中,不可避免的会踩一些坑、走一些弯路,那么有没有办法可以避免少踩一些坑、少走一些弯路呢?万幸的是,答案是有的。

站在巨人的肩膀上,我们可以看得更远,约翰 · 雷西格发布了 jQuery 的第一个版本,从此让我们进入了 jQuery 时代;尤雨溪创造了 Vue,使我们正式迈入 Vue 的时代。这些领军者,让我们能够看得更远,让我们的工作和生活变得更加简单。我与这些领军者相去甚远,微不足道,但依然希望可以尽自己的一些能力来帮助到一些人,让大家可以少走一些弯路、少踩一些坑。怀揣着这样的一个梦想,我开设了这一门课程。

框架为什么会存在

这个世界上任何事物的存在,必然是解决了世界上的一些问题。同样的道理,框架为什么会存在呢?框架的存在也必然是解决了某一个或某一类的问题,这里引入一下 Vue 的作者尤雨溪说过的话:框架的存在是为了帮助我们应对复杂度。框架作为一个工具用来帮助我们应对一类复杂的问题,我想这就是框架的定义了。

当然框架本身一样存在着复杂度,就好像我们使用扳手去拧螺丝时,扳手就是框架,它是一个工具,这个工具本身一样有学习成本,只不过它的学习成本比较低,我们使用这个工具来去解决拧螺丝这样一个如果没有扳手会变得相当复杂的问题,这和使用前端框架去解决在工作中遇到的一个复杂项目的时候所经历的过程是一样的。

所以,很自然的就会在我们使用的框架(工具——扳手)和想要去解决的问题(复杂度——拧螺丝)之间进行抉择,我们会更趋向于使用一个简单的工具来去解决一个复杂的问题,这就是框架存在的意义了。

所以我们本能的希望框架变得越来越简单,而它能够解决的问题越来越复杂。万幸的是:这个时代正在按照我们的希望来发展

主流框架

目前讨论比较多的前端框架主要有三个:

Angular React Vue

通过它们在 GitHub 的 Star 历史和 NPM 的下载趋势图来看一下。

Angular、React 和 Vue 的 GitHub Star 历史:

这里写图片描述

npm 的下载趋势图:

这里写图片描述

可以看到在 GitHub 上面,Vue 的数据上升最快,并且在 2018 年 6 月 28 日已经超过了 React,成为了最受欢迎的前端框架。而在 npm 中,React 的数据遥遥领先,这得益于 React 强大的社区力量,我们无法否认,React 社区作为当前最活跃的前端社区,提供出了特别多优秀的想法和理念,它们为 React 提供了强大的生态支持,同时也让我们在选择周边框架的时候需要进行更多的选择。

当然这三个框架都非常的优秀,我们不去讨论它们的优劣,我们的选择都只是基于我们的取舍:我们希望工具足够简单,而它可以解决的问题却要足够复杂。这就够了,不是吗?

Angular:Angular 期望做的事情非常多,比如说它会包含着它自己的路由,这让我们决定去使用 Angular 的时候,就必须要接受它的全部,这就使得学习成本变得更高,但同时选择变得会更少,不过有时候选择少了并非是一件坏事,它可以让我们更加专注。

React 与 Vue:React 与 Vue 一样都是专注只做界面,而其他的所有一切都会有各种配套的工具,比如说路由,或者状态管理工具,所以说使用它们的话你可能需要做更多的选择,而这种方式则使得它们本身(React、Vue)的学习曲线相对平缓。

从上面的分析可以看出,Angular 提供了一个复杂的工具,用于解决一整套复杂的问题。而 React 与 Vue 则专注于解决一个特定的问题,而把其他的问题交给了它们的生态圈来处理,这样做的同时也会让我们花更多的时间来选择合适的周边工具。

所以说这些框架各有优劣,并没有绝对的谁好谁坏之分,我们选择什么样的工具,取决于我们面对了什么样的问题。没有人会喜欢用大炮去打蚊子,也没有人会想到用苍蝇拍来打大象。我们喜欢刚刚好,追求事半功倍,如果你也是这么想的,那么至少我们的底层观念是一致的。

Vue 的特点

经过了那么多的铺垫,总算到了本次课程内容的重点:Vue,它到底有什么魅力?为什么值得我们花费时间去学习?先来看一下 Vue 到底拥有什么样的特点。

我们会从以下8个方面来对 Vue 进行分析:

  • MVVM 框架
  • 单页面应用程序
  • 轻量化与易学习
  • 渐进式与兼容性
  • 视图组件化
  • 虚拟 DOM(Virtual DOM)
  • 社区支持
  • 未来的 Vue 走向

(1)MVVM 框架

所谓 MVVM 框架就是:Model-View-ViewModel,就像下面这样:

这里写图片描述

那么这个 MVVM 框架,应该怎么去理解呢?它的第一个 View,相当于页面中的 DOM,最后一个 Model 相当于数据源,就像下面这个样子:

这里写图片描述

其中,a 标签就是 DOM,data 对象就是数据源,这两者之间永远不会直接通信,它们所有的联系都是通过 ViewModel,也就是监控者来进行的。监控者会去负责检测数据的变化,然后把数据实时展示在页面中。例如,把 text 的内容更改为 “Hello Vue” 的话,那么 a 标签中展示的内容,也会自动变为 “Hello Vue”。这样就不需要手动的操作 DOM,所有对 DOM 操作都会通过监控者来完成。如果以前写过复杂的 DOM 操作的话(如 **.parent().parent().parent()...),就会发现这种方式带来的便利。

Vue 正是使用了这种 MVVM 的框架形式,并且通过声明式渲染响应式数据绑定的方式来帮助我们完全避免了对 DOM 的操作。

(2)单页面应用程序

单页面应用程序(SPA),一般指为:一个页面就是一个应用(或子应用)。随着技术的发展,现在的前端网页早已不只局限于在浏览器上展示了,手机 App 上、微信公众号上都有了越来越多的展示机会。

那么如果把传统的多页面应用形式放入到我们的手机上面会是什么样子呢?当进行页面跳转打开一个新的页面的时候,它会变成这样:

这里写图片描述

等的花儿都谢了 有没有?

而如果使用单页面的形式来开发的话,就不会出现这样一种情况。因为我们的整个应用就只有一个页面,当我们的这一个单页被加载进来之后,就不会在进行关于页面的网络请求。Vue 配合生态圈中的 Vue-Router 就可以非常方便的开发复杂的单页应用。

(3)轻量化与易学习

我们知道网页中引入的 JS 体积越大,那么加载所需要耗费的时间就越长,反之体积越小,则越节省时间。所以我们会更倾向于使用体积更小的 JS 文件,这也是为什么在生产版本会引入 .min 的 JS 的原因。下面是我从 Vue 官网的截图:

这里写图片描述

目前 Vue 的最新稳定版本为 2.5.16,从截图中可以看到 Vue 的生产版本只有 30.90KB 的大小,几乎不会对我们的网页加载速度产生影响。同时因为 Vue 只专注于视图层,单独的 Vue 就像一个库一样,所以使我们的学习成本变得非常低。

(4)渐进式与兼容性

渐进式框架就是:我只做分内的事情,并且不会对你要求太多。

Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

这是 Vue 官网上面的一句话,正如在上面所说的,Vue 只做界面,而把其他的一切都交给了它的周边生态来做处理,这就要求 Vue 必须要对其他的框架拥有最大程度的兼容性。

例如,一开始只想做一个静态站,那么可以只引入 Vue 来去构建界面,过了一段时间,你想在网站上加入访问网络的功能,那么你可以再引入 axios(Vue 官方推荐)或者其他的(哪怕是 jQuery)网络请求框架,而后来随着你的网站越做越大,你想要把你的网站变成一个大型的 Web 应用的时候,可以引入一些其他你需要的 JS 文件,如 Loadsh.js、Velocity.js 等。

(5)视图组件化

所谓视图组件化就是把我们的网页拆分为一个个的组件,就像下面这样:

这里写图片描述

Vue 允许通过组件来去拼装一个页面,每个组件都是一个可复用的 Vue 实例,组件里面可以包含自己的数据,视图和代码逻辑。比如说:

这里写图片描述

CSDN 的这个个人资料模块,大家都已经不陌生了吧,当我们的 Web 应用中有多个页面都使用到这个个人资料模块的时候,就可以把它封装成一个组件,这个组件拥有单独的代码逻辑、CSS 样式、数据等,在任何一个我们需要使用到它的地方,就可以通过

Vue.component('component-name', {    ...});

这种方式来直接引入了。

(6)Virtual DOM

Virtual DOM 也就是虚拟 DOM,大家知道浏览器去处理 DOM 操作时,是存在性能问题的,这也是我们在使用 jQuery 或者原生 JavaScript 来去频繁操作 DOM 进行数据渲染的时候,我们的页面经常出现卡顿的原因。

而虚拟 DOM 则是预先通过 JavaScript 的各种运算,把最终需要生成的 DOM 计算出来,并且进行优化,在计算完成之后才会将计算出的 DOM 放到我们的 DOM 树中。由于这种操作的方式并没有进行真实的 DOM 操作,所以才会叫它虚拟 DOM。

我们在前面说过:

Vue 是通过声明式渲染响应式数据绑定的方式来帮助我们完全避免了对 DOM 的操作。

Vue 之所以可以完全避免对 DOM 的操作,就是因为 Vue 采用了虚拟 DOM 的方式,不但避免了我们对 DOM 的复杂操作,并且大大的加快了我们应用的运行速度。

(7)来自社区的支持

虽然在全球中 Vue 的社区并没有 React 社区那么的繁华,但得益于 Vue 的本土化身份(Vue 的作者为国人尤雨溪),再加上 Vue 本身的强大,所以涌现出了特别多的国内社区,如 https://www.vue-js.com/、https://vuejs.com.cn/ 等。这种情况在其他的框架身上是没有出现过的,这使得我们在学习或者使用 Vue 的时候,可以获得更多的帮助。

(8)未来 Vue 的走向

Vue 是由国人尤雨溪在 Google 工作的时候,为了方便自己的工作而开发出来的一个库,而在 Vue 被使用的过程中,突然发现越来越多的人喜欢上了它。所以尤雨溪就进入了一个边工作、边维护的状态,在这种情况下 Vue 依然迅速的发展。

而现在尤雨溪已经正式辞去了 Google 的工作,开始专职维护 Vue,同时加入进来的还有几十位优秀的开发者,他们致力于把 Vue 打造为最受欢迎的前端框架。事实证明 Vue 确实在往越来越好的方向发展了(从 Angular、React、Vue 的对比图中可以看出 Vue 的势头)。所以我觉得完全不需要担心未来 Vue 的发展,至少在没有新的颠覆性创新出来之前,Vue 都会越做越好。

本课能够帮你些什么

说了那么多,大家应该已经对 Vue 有了一个基础的了解了,那么我们看一下,这节课的主要内容。

本课将从基础语法、生态系统、项目实战这三个部分来帮助大家详细的了解 Vue 的知识,看一下下面的脑图。

深入浅出学 Vue 开发_第1张图片

这就是我们本课将要学习的所有内容,我们会通过一个对话项目完成课程的学习,教你真正掌握 Vue 开发。扫描以下二维码查看项目。

be4e1810-8b00-11e8-9fe1-c1b3d2332fb0

通过本次课程可以学习到:

  • Vue 的基础语法
  • Vue 的实现原理
  • Vue 的周边生态
  • Webpack 模块打包器
  • vue-cli 脚手架解析
  • 如何通过 vue-cli + Webpack 来开发我们的自动聊天系统

因为本次课程涉及到了 Vue 的一些实现原理,同时也会对使用 vue-cli + Webpack 构建出来的代码进行解析,所以在学习本课程之前需要具备 JavaScript 的基础知识,如果对 Vue 已经有了一些了解或者已经使用 Vue 开发过一两个项目的话,那么我相信你会在本次课程中拥有更大的收获!

点击了解更多《深入浅出学 Vue 开发》

第01课:初探 Vue

在正式开始学习 Vue 的知识之前,我们需要先对 Vue 的整体有一个大致的了解。为了达到这个目的,首先了解以下内容:

  • Vue 对移动端和浏览器版本的支持
  • 如何初始化一个 Vue 的项目
  • Vue 的代码结构

Vue 对移动端和浏览器版本的支持

因为 Vue 本身使用了 ECMAScript 5 特性,所以 Vue 支持所有兼容 ECMAScript 5 的浏览器。我们根据下面的图示来解释一下,数据来自-caniuse.com。

深入浅出学 Vue 开发_第2张图片

红色:几乎不支持

黄色:大部分支持(有很小的可能会影响使用)

绿色:几乎全部支持(不影响使用)

由上面的图示可以看出,对 IE 来说,在 IE 8 及其以下的时候,是不支持 ECMAScript 5 的,也就是说,是无法使用 Vue 的,我们看一下对 IE 8 的描述。

深入浅出学 Vue 开发_第3张图片

IE 8 几乎没有 ES 5 支持,仅支持对字符串的 Object.defineProperty、Object.getOwnPropertyDescriptor、JSON 解析和属性访问。

所以说对使用了 ECMAScript 5 特性的 Vue 来说,是没有办法在 IE 8 及以下使用的。IE 8 作为天坑的分界线,其实是一直被大家所诟病的,那么 IE 9 呢?从图示中可以看出,IE 9 的背景为黄色,也就是说大部分支持,那么不支持的部分是哪些呢?我们来看一下。

深入浅出学 Vue 开发_第4张图片

可以看到,对 IE 9 来说,它不支持严格模式,这对我们使用 Vue 的影响就已经很小了,所以说可以在 IE 9 及以上可以安全的使用 Vue。

而对于其他的浏览器和移动端来说,对 ECMAScript 5 的支持还是非常不错的,Chrome 和 Firefox 都对 ECMAScript 5 早早的提供了支持,而 iOS 6 和 Android 4.4 以上也都对 ECMAScript 5 的支持非常完善了,也就是说我们可以在这些浏览器上面放心地使用 Vue 了。

如果大家对这些数据比较感兴趣,也可以点击这里,自己来看一下,这里就不再过度赘述了。

如何初始化一个 Vue 的项目

然后我们来看一下,应该如何去初始化一个 Vue 的项目。引入 Vue 的方式主要有两种:

  • 直接通过 // 生产版本,删除了警告,30.90KB min+gzip。 // 下载地址:https://vuejs.org/js/vue.min.js // CDN引入方式,版本号为2.5.16。 // 你也可以直接通过 https://cdn.jsdelivr.net/npm/vue/ 这个地址来查看Vue的源码 // 如果你想要引入生产版本的话,那么只需要把最后的vue.js改为vue.min.js

    通过这种方式来引入 Vue,就可以在 .js 文件或者 .vue 文件(需要对 .vue 文件进行解析,比如使用 vue-loader)中直接使用 Vue 的语法了。

    通过 npm 的方式引入

    第二种方式为通过 npm 来直接引入。对于 npm,大家如果有过前端开发经验的话,那应该已经不陌生了。npm 作为在前端被广泛使用的包管理工具,Vue 自然也是需要提供支持的,可以直接使用如下命令来安装 Vue 的最新版本。

    npm install vue

    两种方式的对比

    Vue 的官网推荐我们在用 Vue 去构建大型项目时,使用 npm 的方式去安装,但是说的却并不是很详细,先来看一下官网的说法:

    在用 Vue 构建大型应用时推荐使用 npm 安装。npm 能很好地和诸如 Webpack 或 Browserify 模块打包器配合使用,同时 Vue 也提供配套工具来开发单文件组件。

    翻译一下官网的意思:之所以推荐使用 npm 的方式来安装 Vue,是因为:

    • 使用 npm 的方式可以更好的配合模块打包器(Webpack 或者 Browserify);
    • 可以更方便的使用单文件组件(.vue 文件)。

    上面两点就是推荐使用 npm 方式的原因,关于模块打包器(Webpack)和单文件组件(.vue 文件),在后面的篇幅中会详细讲解,如果大家现在就想对 Webpack 或者单文件组件进行详细了解,也可以点击链接到它们的官网来详细了解。我们在这里只大概的说一下,目的是让大家更清楚的了解 Vue 引入方式的区别。

    一般在使用 Vue 来构建大型项目的时候,通常会通过npm + vue-cli + webpack的方式进行项目初始化。

    我们需要安装好 npm,可以点击这里下载最新的 Node 版本。

    然后使用 npm install -g vue-cli 指令下载最新的 vue-cli。

    然后通过vue init 这种方式初始化我们的项目,是模块打包器,是项目名称;比如可以通过 vue init webpack my-project 构建一个名字叫做 my-project 的项目。

    一路回车之后,就可以得到一个使用npm + vue-cli + webpack构建出的项目了,来看一下项目的结构:

    ├── README.md├── build├── config├── index.html├── node_modules├── package.json├── src├── static└── test

    在 package.json 文件下,可以看到一个dependencies:{"vue": "版本号"},这个 vue 就是通过 npm 来引入的 Vue,在 src 文件夹下面也已经生成了 .vue 的单文件组件。

    我们可以直接通过npm run dev的方式在本地运行这个项目,也可以通过 npm run build 对这个项目进行打包。

    那么是不是通过npm + vue-cli + webpack方式生成的项目就不能通过 这种方式来引入 vue,从而尽量减少服务器的压力。

    就像在导读中说的:我们选择什么样的工具,取决于我们面对了什么样的问题。没有任何一种工具或者方式是在任何一种情况下都完全适用的。

    Vue 的代码结构

    在使用 Vue 开发项目时,我们的代码一般会写到两种文件中,分别是:

    • 非单文件组件(.js 文件);
    • 单文件组件(.vue 文件)。

    通过这两种文件来看一下 Vue 的代码结构是什么样子的。

    非单文件组件(.js 文件)

    非单文件组件就是我们正常的 js 文件,js 文件是可以直接被浏览器解析的,可以在 js 文件中,直接通过(可以直接新建一个 html 文件,通过

    每一个 .vue 文件都会被当成使一个“组件”,每个“组件”中都有其单独的 html、css、js,然后再把这些“组件”拼装成一个完整的项目(如果大家对这一块不了解,可以看一下导读中提到的组件化知识)。

    使用这种单文件组件(.vue 文件)的优势非常明显,它使得项目组件化,因为每个模块的功能都被单独分割,所以代码耦合性变得更低,也更利于团队开发日后维护(这块会在项目实战中实地展示这种方式的优势)。

    但是 .vue 文件浏览器是无法直接解析的,需要使用到一些解析工具把 .vue 文件解析成浏览器能够看懂的 html、css 和 js 文件。干这个事的工具一般为vue-loader(就好像我们去解析 .less 文件的 Koala,不同的是vue-loader并不是一个单独的应用),而我们去使用vue-loader也都会配合 Webpack 来使用,这也是为什么构建正式大型项目的时候,一般都会使用npm + vue-cli + webpack方式的原因之一。

    然后再看一下,在刚才通过npm + vue-cli + webpack来生成的my-project项目,通过这个项目来大体的认识一下单文件组件(.vue 文件)

    分别打开/src/App.vue/src/main.js这两个文件,为了防止过多的代码对大家造成困扰,我把这些代码进行了一些简化。

    App.vue:

    main.js:

    import Vue from 'vue'import App from './App'new Vue({  el: '#app',  components: { App },  template: ''})

    大家可以把这两部分的代码复制到项目中,然后执行npm run dev,通过浏览器打开http://localhost:8080/#/,则可以看到一个 Vue 的图标和“Hello Vue”的一串文字。

    如果可以正常运行,那么来看一下这些代码的具体含义。

    main.js里面它通过 ES6 的方式引入了 Vue 和 App.vue 两个文件,然后在初始化 Vue 的时候,通过 el 指定最外层的 div 为id为app的

    ,然后指定了 App.vue 作为 Vue 的一个组件 components,并且给他指定了模板 template 为

    然后在 App.vue 中,它在