元数据

Vue.js快跑:构建触手可及的高性能Web应用

  •  Vue.js快跑:构建触手可及的高性能Web应用|200
  • 书名: Vue.js快跑:构建触手可及的高性能Web应用
  • 作者: 卡勒姆·麦克雷
  • 简介: 本书是用Vue.js构建Web应用的全方位指南。作者运用细致入微的讲解方式带你领略Vue.js的独特魅力,致力于协助你从零开始基于Vue.js创建一个Web应用。本书共7章:第1章介绍Vue的安装及基本用法,覆盖大量Vue核心技术,诸如响应式原理、生命周期钩子等;第2章到第6章进入Vue高阶世界,通过在丰富的组件特性中遨游,教你使用vue-router和vuex来实现客户端路由和状态管理,以此完善整个Web应用的功能;最后一章介绍如何使用vue-test-utils这一官方测试利器来为组件编写单元测试,从而保证Web应用的正常运行;附录分别介绍vue-cli用法及Vue与React之间的异同。本书适合对HTML和JavaScript已有一定了解,正在准备或已经使用Vue.js进行Web应用开发的从业者,也适合希望通过学习框架使用来提升对其认识的开发人员,有React使用经验的读者同样可从中获得启发。
  • 出版时间 2018-11-01 00:00:00
  • ISBN: 9787121352997
  • 分类: 计算机-编程设计
  • 出版社: 电子工业出版社
  • PC地址:https://weread.qq.com/web/reader/82032410718487828207501

高亮划线

第1章 Vue.js基础

📌 Vue.js是构建强大客户端应用的技术体系中的核心库 ⏱ 2020-11-13 12:03:09

为什么选择Vue.js

📌 如果不使用框架,项目最终会成为一团不可维护的代码, ⏱ 2020-08-24 08:58:07

📌 以下面两段代码为例,它们都实现了同样的功能:使用Ajax下载一个列表数据并在页面上显示。其中,第一段使用jQuery实现,而第二段使用Vue实现。 ⏱ 2020-08-24 08:58:13

📌 vue-router用于路由控制——根据应用的不同URL来显示不同的内容。vuex用于状态管理——通过一个全局数据中心在组件间共享数据 ⏱ 2020-08-26 19:19:32

模板(Template)、数据(Data)和指令(Directive)

📌 在JavaScript中实现业务逻辑,而在template中实现视图逻辑,以这种方式编写代码意味着我们可以对页面上将会显示的内容一目了然 ⏱ 2020-11-20 14:08:27

📌 也可以通过插值的方式将数据传递给模板 ⏱ 2020-11-20 14:08:44

v-if vs v-show

📌 在该示例中如果使用v-if就会正常工作,因为Vue直到v-if语句为真时才会去尝试生成元素的内部内容。 ⏱ 2020-11-20 14:13:49

📌 每次插入或者移除元素时都必须要生成元素内部的DOM树,这在某些时候是非常大的工作量。而v-show除了在初始创建开销时之外没有额外的开销。如果希望频繁地切换某些内容,那么v-show会是最好的选择。 ⏱ 2020-11-20 14:14:10

📌 那么仅使用CSS隐藏父节点可以使浏览器在图片显示之前就加载它, ⏱ 2020-11-20 14:14:23

📌 如果是v-if指令,图片会直到要显示时才开始加载。 ⏱ 2020-11-20 14:14:18

响应式

📌 , Vue还监控data对象的变化,并在数据变化时更新DOM。 ⏱ 2020-11-20 14:20:19

📌 Vue修改了每个添加到data上的对象,当该对象发生变化时Vue会收到通知,从而实现响应式。对象的每个属性会被替换为getter和setter方法,因此可以像使用正常对象一样使用它,但当你修改这个属性时,Vue会知道它发生了变化。 ⏱ 2020-11-20 14:24:17

📌 当userId发生变化时,你如何得知它发生变化了呢?可以存储这个对象的一个副本,然后比较二者,但这并不是最高效的方法。这种方法称为脏检查,也是Angular1所采用的方法。

  • 💭 被称为脏检查的原因:定时检查而不是直接监听属性变化 - ⏱ 2020-11-20 14:24:33

📌 同时Vue还使用代理方法封装了被观察的数组对象上的一些数组方法(例如.splice()),来观察数组方法何时被调用。这也是为什么当你调用.splice()时,Vue知道你更新了数组,并触发了必要的视图更新。 ⏱ 2020-11-20 14:37:02

📌 因为getter/setter方法是在Vue实例初始化的时候添加的,只有已经存在的属性是响应式的;当为对象添加一个新的属性时,直接添加并不会使这个属性成为响应式的: ⏱ 2020-11-20 14:43:12

📌 最简单的办法是在初始化时在对象上定义这个属性,并把它的值设置为undefined。 ⏱ 2020-11-20 14:43:27

📌 或者,也可以使用Object.assign()来创建一个新的对象然后覆盖原有对象,当需要一次性更新多个属性时,这是最有效的办法: ⏱ 2020-11-20 14:44:03

📌 最后,Vue还提供了Vue.set()方法,可以使用它将属性设置为响应式的: ⏱ 2020-11-20 14:43:44

📌 在组件内部也可以使用this.$set来调用这个方法。 ⏱ 2020-11-20 14:43:52

📌 另一种是使用Vue.set(): ⏱ 2020-11-20 15:07:09

双向数据绑定

📌 如果想让上面这个例子按预期运行,就不能使用v-bind:value——使用v-bind只会在inputText值变化时才更新输入框的值,反过来则不行。作为替代,可以使用v-model指令,它作用于输入框元素,将输入框的值绑定到data对象的对应属性上,因此输入框不但会接收data上的初始值,而且当输入内容更新时,data上的属性值也会更新。 ⏱ 2020-11-20 15:10:06

📌 使用v-model时一定要记住,如果设置了value、checked和selected属性,这些属性会被忽略。如果想设置输入元素的初始值,应该在data对象中设置。 ⏱ 2020-11-20 15:32:57

动态设置HTML

📌 比如说调用一个API,这个API返回一些需要显示在页面上的HTML。 ⏱ 2020-11-20 15:39:06

📌 从某个变量中取出HTML并输出到页面上,你可能将自己暴露在XSS[插图]风险中。永远不要将用户输入或者允许用户修改的内容置于v-html中,除非对他们输入的内容提前进行了仔细的校验和转义。不然你可能会一不小心允许了用户在你的网站上执行恶意脚本。记住,只用v-html处理你信任的数据。 ⏱ 2020-11-20 15:39:43

方法

📌 除了在插值中使用方法,还可以在属性绑定中使用它们——实际上,任何可以使用JavaScript表达式的地方都可以使用方法 ⏱ 2020-11-20 15:52:23

📌 在方法中,this指向该方法所属的组件 ⏱ 2020-11-20 15:53:07

计算属性

📌 计算属性介于data对象的属性和方法两者之间:可以像访问data对象的属性那样访问它,但需要以函数的方式定义它。 ⏱ 2020-11-20 15:54:08

📌 首先,计算属性会被缓存:如果在模板中多次调用一个方法,方法中的代码在每一次调用时都会执行一遍;但如果计算属性被多次调用,其中的代码只会执行一次,之后的每次调用都会使用被缓存的值。只有当计算属性的依赖发生变化时,代码才会被再次执行 ⏱ 2020-11-20 15:59:24

📌 因为这种方式可以确保代码只在必要的时刻执行,所以适合处理一些潜在的资源密集型工作。 ⏱ 2020-11-20 16:01:56

📌 计算属性和方法的另外一个区别是,除了能像上例展示的那样获取计算属性的值,还可以设置计算属性的值,并且在设置过程中做一些操作。 ⏱ 2020-11-20 16:03:01

📌 上述每一种选择都有适合的场景,而且最好和其他方式组合使用 ⏱ 2020-11-20 16:03:29

📌 data对象最适合纯粹的数据:如果想将数据放在某处,然后在模板、方法或者计算属性中使用,那么可以把它放在data对象中。后面也许还会更新它 ⏱ 2020-11-20 16:03:38

📌 这些表达式往往太长或者需要频繁地重复使用,所以不想在模板中直接使用。 ⏱ 2020-11-20 16:03:53

侦听器

📌 侦听器可以监听data对象属性或者计算属性的变化。 ⏱ 2020-11-20 16:04:11

📌 和设置数据然后监听它的变化相比,使用一个带有setter的计算属性会是更好的方式。 ⏱ 2020-11-20 16:04:53

📌 尽管大部分简单的例子用不到侦听器,但侦听器很适合用于处理异步操作 ⏱ 2020-11-20 16:19:27

📌 我们在侦听器函数中将this.inputValue赋值给了一个局部变量:因为不这样做,当传递给setTimeout的函数被调用时,this.inputValue有可能已经被更新到最新值了! ⏱ 2020-11-20 16:31:36

📌 有些时候会将一整个对象存储在data对象中。为了监听这个对象的属性变化,可以在侦听器的名称中使用.操作符,就像访问这个对象属性一样: ⏱ 2020-11-20 16:23:06

📌 当监听的属性发生变化时,侦听器会被传入两个参数:所监听属性的当前值和原来的旧值。 ⏱ 2020-11-20 16:31:42

📌 监听整个对象被称作深度监听,通过将deep选项设置为true来开启这一特性 ⏱ 2020-11-20 18:21:55

过滤器

📌 过滤器是一种在模板中处理数据的便捷方式,而且经常会在其他模板语言中见到。它们特别适合对字符串和数字进行简单的显示变化 ⏱ 2020-11-20 18:30:04

📌 这段代码可以正常工作,但是存在很多重复。 ⏱ 2020-11-20 18:30:17

📌 那么可以用{{ productOneCost | round |formatCost}}的方式同时使用两个过滤器。首先会调用round过滤器,它返回的结果会传递给formatCost过滤器进行处理, ⏱ 2020-11-20 18:32:10

📌 另外一个注意事项是只可以在插值和v-bind指令中使用过滤器 ⏱ 2020-11-20 19:50:57

📌 Vue 2取消了这种做法,对于上面这个例子必须使用方法或者计算属性。 ⏱ 2020-11-20 19:50:54

使用ref直接访问元素

📌 有时你会发现需要直接访问一个DOM元素;也许你正在使用一个不支持Vue的第三方库,或者希望做一些Vue自身不能完全处理的事情。可以使用ref直接访问元素,而不需要使用querySelector或者其他选择DOM节点的原生方法。 ⏱ 2020-11-20 19:53:06

输入和事件

📌 如果想要阻止执行事件默认行为——例如,当链接被单击时阻止页面的跳转——可以使用.prevent修饰符: ⏱ 2020-11-21 17:27:31

📌 如果想要阻止事件继续传播,以避免在父级元素上触发事件,可以使用.stop修饰符: ⏱ 2020-11-21 17:27:36

📌 如果想要只在第一次触发事件的时候触发事件侦听器,可以使用.once修饰 ⏱ 2020-11-21 17:28:53

📌 如果想要使用捕获模式,也就是说,事件会在传递到当前元素的下级元素前触发(而在冒泡模式中,事件会先在当前元素上触发,然后沿DOM树向上冒泡),可以使用.capture修饰符: ⏱ 2020-11-21 17:29:04

📌 Vue内置了一种基于修饰符的方式来处理这种情况。可以将按键键值作为修饰符, ⏱ 2020-11-21 17:56:23

📌 如果想在只有被指定的按键被按下但没有其他按键被按下的时候才触发事件侦听器,可以使用.exact修饰符。 ⏱ 2020-11-21 18:08:27

📌 当Enter键被按下,且没其他任何按键 ⏱ 2020-11-21 18:08:32

生命周期钩子

📌 如果将一个函数设置为一个组件或者Vue实例的created属性,它会在组件创建完成时被调用。 ⏱ 2020-11-21 18:09:23

📌 生命周期钩子是一系列会在组件生命周期——从组件被创建并添加到DOM,到组件被销毁的整个过程——的各个阶段被调用的函数。 ⏱ 2020-11-21 18:09:28

📌 虽然Vue有8个生命周期钩子,但是很容易记住,因为其中4个是带有before前缀的钩子,它们会先于其他钩子被调用。 ⏱ 2020-11-21 18:09:34

📌 new Vue()时初始化 ⏱ 2020-11-24 09:55:56

📌 同时响应式功能会被初始化 ⏱ 2020-11-23 11:03:31

📌 带有“before”前缀的钩子会在相关工作开始之前被调用,然后,真正执行相关工作的钩子才会被触发。 ⏱ 2020-11-23 10:59:47

📌 模板内容可以从template或render选项获取,或者从Vue初始化时所挂载元素的outerHTML获取 ⏱ 2020-11-23 11:01:51

📌 在Vue 2.0中,mounted钩子触发时并不保证元素已经被添加到DOM上。如果想保证元素已经被添加,可以调用Vue.nextTick()方法(也可以通过this.$nextTick()调用)并传入一个回调函数,在回调函数中添加需要在元素被添加到DOM之后运行的代码 ⏱ 2020-11-23 11:03:20

📌 。在处理更新前,beforeUpdate钩子函数会被触发,而且在应用更新之后,updated钩子会被触发。 ⏱ 2020-11-24 09:49:39

自定义指令

📌 当你想直接对DOM进行某些操作时,指令非常好用——如果发现自己并不需要访问DOM,那么使用不带指令的组件就好。 ⏱ 2020-11-24 10:05:34

📌 子组件都更新完成后调用。 ⏱ 2020-11-24 10:13:25

过渡和动画

📌 Vue提供了大量功能来为你的Vue应用增加动画和过渡效果 ⏱ 2020-11-24 10:14:31

📌 Vue提供了组件,它会向内部的带有v-if指令的元素添加类名,因此可以使用这个组件来为进入或离开的元素添加CSS过渡动画。 ⏱ 2020-11-24 10:15:58 ^25462658-23-869-948

📌 Vue获取tansition组件的name属性值,然后使用它在过渡的各个节点为包含的元素添加类名。当元素被添加到文档或者从文档中移除时,会分别应用enter和leave两类过渡。以下是会添加的类名: ⏱ 2020-11-24 10:16:33

📌 {name}-enter ⏱ 2020-11-24 10:16:36

📌 {name}-enter-active ⏱ 2020-11-24 10:16:44

📌 {name}-enter-to ⏱ 2020-11-24 10:16:53

📌 {name}-leave ⏱ 2020-11-24 10:16:55

📌 {name}-leave-active ⏱ 2020-11-24 10:16:57

📌 {name}-leave-to ⏱ 2020-11-24 10:16:59

📌 组件还提供了用于实现JavaScript动画的钩子。使用这些钩子,可以使用自己的代码或者类似于GreenSock或者Velocity的库来实现动画。 ⏱ 2020-11-24 10:23:45 ^25462658-23-3843-3935

📌 适合设置初始值。 ⏱ 2020-11-24 10:24:08

第2章 Vue.js组件

📌 组件是一段独立的、代表了页面的一个部分的代码片段。它拥有自己的数据、JavaScript脚本,以及样式标签。组件可以包含其他的组件,并且它们之间可以相互通信。 ⏱ 2020-11-24 10:51:16

📌 负责页面每一部分的代码都很靠近该组件中的其余代码。因此当你想要知道哪个元素有添加事件监听器,不必再在一堆JavaScript文件中搜索相应的选择器 ⏱ 2020-11-24 10:51:48

数据、方法和计算属性

📌 或许你已经注意到了组件与Vue实例之间的一个细微差别:Vue实例中的data属性是一个对象,然而组件中的data属性是一个函数。这是因为一个组件可以在同一个页面上被多次引用,你大概不希望它们共享一个data对象 ⏱ 2020-11-24 10:53:10

传递数据

📌 可以使用props属性来传递数据 ⏱ 2020-11-24 10:53:32

📌 props属性的值表示可以传入组件的属性的名称——这个例子中,就只有color。 ⏱ 2020-11-24 10:54:10

自定义事件

📌 还可以使用emit方法触发一个事件,通过$on方法添加的事件处理函数就会执行。 ⏱ 2020-11-24 11:50:38

📌 这在处理基于Vue的代码与非Vue的代码之间的通信时,极为有用——但总的来说,只要情况允许,vuex往往是更好的选择。 ⏱ 2020-11-24 11:53:58

混入

📌 混入是一种代码组织方式,可以在多个组件间横向复用代码。 ⏱ 2020-11-24 11:55:07

📌 组件间相当多的逻辑代码是共同的 ⏱ 2020-11-24 11:55:14

📌 后两种方式在这个例子中很相似,但是使用混入是一种更加符合Vue习惯的处理方式 ⏱ 2020-11-24 11:55:25

📌 如果混入对象和组件间有重复的选项——比如它们都有一个叫作addUser()的方法或者都有一个created()钩子——根据它们的类型,Vue会分别对待。 ⏱ 2020-11-24 14:12:18

📌 对于重复的方法、计算属性或其他任何非生命周期钩子属性,组件中的属性会覆盖混入对象中的属性 ⏱ 2020-11-24 14:33:34

📌 官方的Vue代码风格指南建议对于混入中的私有属性(不应该在混入之外使用的方法、数据和计算属性),应该在它们的名称前面添加前缀 ⏱ 2020-11-24 14:33:52

vue-loader和.vue文件

📌 vue-loader提供了一种方法,可以在.vue文件中以有条理并且易于理解的语法编写基于单个文件的组件。 ⏱ 2020-11-24 14:34:14

📌 将组件分离到文件可以让你的代码更加容易维护。可以不必将所有的组件放在同一个大文件中,而是将它们分别保存在几个文件中,并放在相关名称的目录下,同时以它们所在的网站部分来命名,或者以组件的类型或规模来命名。 ⏱ 2020-11-24 14:34:43

非Prop属性

📌 组件上的属性会覆盖它内部模板上的属性 ⏱ 2020-11-24 14:36:07

📌 但是class和style稍微聪明一点,同名的值会被合并 ⏱ 2020-11-24 14:36:26

📌 组件属性中的background-color样式覆盖掉了内部模板中的background-color样式。 ⏱ 2020-11-24 14:36:33

组件和v-for指令

📌 click事件的处理函数是通过.native修饰符添加的,因为这就是为组件添加原生DOM事件监听器的方式。 ⏱ 2020-11-24 14:37:14

📌 我经常看到有人将key设置为数组的下标(例如在前面例子中设置:key=“i”)。如果不是什么特殊情况,那么你不会想要这么做的! ⏱ 2020-11-24 14:43:21

总结

📌 组件非常适合将代码分离到逻辑块中,并执行一个特定任务。 ⏱ 2020-11-24 14:43:53

内联样式绑定

📌 Vue会自动将该对象的属性由驼峰命名转为它们对应的CSS属性 ⏱ 2020-11-24 14:56:44

📌 ,Vue会自动为你添加浏览器前缀:如果设置的某个样式需要浏览器兼容性前缀,Vue会自动把它加上。 ⏱ 2020-11-24 14:57:06

📌 还可以使用数组提供多个值,来设置浏览器最终支持的值: ⏱ 2020-11-24 15:02:10

用vue-loader实现Scoped CSS

📌 或者还可以设置webpack将样式提取到一个外部的CSS文件中) ⏱ 2020-11-24 15:56:22

📌 scoped属性 ⏱ 2020-11-24 16:10:09

预处理器

📌 假设想要使用SCSS而不是CSS,以利用诸如嵌套和变量这样的特性。可以通过两个步骤来实现:首先通过npm安装sass-loader和node-sass,然后在style标签上添加lang=“scss”: ⏱ 2020-11-25 10:08:11

子节点

📌 第三个也是最后一个参数是用来设置元素的子节点的。 ⏱ 2020-11-25 10:13:25

总结

📌 你需要用到createElement函数,它接收3个参数:标签名称、数据对象以及元素子节点。也可以使用JSX替代createElement函数调用 ⏱ 2020-11-25 10:15:58

第5章 使用vue-router实现客户端路由

📌 旨在让我们能够在客户端,而非服务端来处理一个应用的路由 ⏱ 2020-11-23 15:48:27

📌 路由就是取一个路径(如users/12345/ports)来确定应该在页面上显示什么内容的行为。 ⏱ 2020-11-25 10:16:37

基本用法

📌 为了对该路由器进行设置,需要赋予它一组路径,以及对应的组件:路径被匹配到时,就会显示对应的组件。 ⏱ 2020-11-25 10:17:39

📌 需要添加一个特殊的组件。 ⏱ 2020-11-25 10:23:12 ^25462658-51-973-1005

动态路由

📌 其中相同的组件会被重用,于是第一章所涉及到的生命周期钩子,诸如mounted,都不会被调用 ⏱ 2020-11-25 15:59:54

链接导航

📌 它就会直接将你带往/user/1234,而无须加载一个新的页面。 ⏱ 2020-11-25 16:02:31

导航守卫

📌 同时你还有一个userAuthenticated()方法用于当用户登录时返回true。 ⏱ 2020-11-25 16:03:59

📌 /account ⏱ 2020-11-25 16:04:41

📌 它就是路由元信息(route meta fields)。你可以在路由上添加一个meta属性,并在守卫那里重新获取它 ⏱ 2020-11-25 16:12:57

路由命名

📌 然后用路由的名称来代替它们的路径 ⏱ 2020-11-25 16:20:01

第6章 使用vuex实现状态管理

📌 不同的组件将会在不同的时间点更新,这就意味着它们会渲染不一样的数据,并且页面所发送的API请求也会远远超过其实际所需。 ⏱ 2020-11-23 11:26:56

📌 vuex应运而生,帮助开发者管理Vue应用中的状态。它提供了一种集中式存储(centralized store),可以在整个应用中使用它来存储和维护全局状态。 ⏱ 2020-11-23 11:27:01

安装

📌 而如果使用的是诸如webpack的打包工具,那么就要像使用vue-router那样,调用Vue.use(): ⏱ 2020-11-23 11:40:36

📌 现在,已经把这个store引入应用中了,并且可以用this.$store来访问它。 ⏱ 2020-11-23 14:02:45

概念

📌 因为在这个例子中并没有进行websocket认证,并且假设了在websocket上获得的服务器响应总是一个合法的JSON ⏱ 2020-11-23 14:01:48

📌 因为每个组件都会打开一个websocket通道,所以就创建了一些不必要的重复连接,并且由于网络延迟,各个组件的更新时间可能会稍稍有点不同。为了解决这个问题,可以把websocket的逻辑放入vuex中。 ⏱ 2020-11-23 14:02:22

State及其辅助函数

📌 如果只是要从state上获取一个属性作为计算属性,也可以只赋予它一个字符串: ⏱ 2020-11-23 15:17:24

Mutation

📌 到目前为止,只见过如何将数据从store中取出,却还没看到如何对数据进行修改。不可以直接修改state对象的值,得使用mutation。 ⏱ 2020-11-23 15:02:00

Promise与Action

📌 改动很小——只是在调用fetch之前加了一个return。 ⏱ 2020-11-23 15:11:37

Module

📌 谈谈如何组织store。 ⏱ 2020-11-23 15:12:05

📌 但是在较大型的应用中,就会显得有点杂乱,因此vuex允许你将你的store拆分到各个模块(module)中。 ⏱ 2020-11-23 15:12:26

📌 而第二个变化则要求我们在Notification组件中对mapState的调用做一点改变。我们可以将模块名称作为mapState的第一个参数: ⏱ 2020-11-23 15:14:32

测试单个组件

📌 · 应当测试被提供的初始通知计数是否被正确地展示。· 应当有一个测试来确保当链接被单击时,通知计数被正确地更新。· 最后,在调用API失败时,组件还应当能够优雅地处理异常错误。 ⏱ 2020-11-25 16:20:53

介绍vue-test-utils

📌 vue-test-utils是一个协助你编写测试的Vue官方库。它提供多种在为组件编写测试时常用的功能,比如查询DOM节点、设置props和data、模拟组件和其他参数、处理事件等。 ⏱ 2020-11-25 16:23:18

读书笔记

v-if vs v-show

划线评论

📌 v-if指令的值为假 ^8292450-7lZW3twlp - 💭 假值包括false、undefined、null、”和NaN - ⏱ 2020-11-20 14:10:47

响应式

划线评论

📌 当userId发生变化时,你如何得知它发生变化了呢?可以存储这个对象的一个副本,然后比较二者,但这并不是最高效的方法。这种方法称为脏检查,也是Angular1所采用的方法。 ^8292450-7lZXnT2sx - 💭 被称为脏检查的原因:定时检查而不是直接监听属性变化 - ⏱ 2020-11-20 14:31:05

本书评论

书评 No.1

把文档换一种表述

⏱ 2020-11-25 16:25:49