0
点赞
收藏
分享

微信扫一扫

《Vue.js实战》读书笔记

若如初梘 2022-12-12 阅读 87


嗯,加油啦!!都是书里的东西,整理了一下,以后复习的时候看.

电子档资源见评论

摘些最近看书的句子:

    迪安却不一样,他为了面包和性爱在社会上使劲打拼。

    我不知道自己究竟是谁了,我远离家乡,旅途劳顿,疲倦不堪,寄身在一个从未讲过的旅馆房间,听到的是外面蒸汽的嘶嘶声....,在最初的奇特的十五分钟里,我真的不知道自己是谁。我并不惊恐;只觉得自己仿佛是另一个人,一个陌生人,我一生困顿,过着幽灵般的生活,

   正因为没有立足之地,他对任何地方都不会感到厌倦,正应为无处可去,他任何地方都可以去,他老是在星光下进行。

                                                                                                                                                                       -------------《在路上》

第1章初识Vuejs

Vue特点:简单小巧,渐进式.

简单小巧是指 Vue.js 压缩后大小仅有 17KB。

所谓渐进式(Progressive),就是你可以一步一 步、有阶段性地来使用 Vue.js,不必一开始就使用所有的东西。Vue 最独特的特性之一,是其非侵入性的响应式系统。比如你可以直接用脚本插入,也可以构建一个前端工程vue-cil。

  • Vue特性:解耦视图和数据,可复用的组件,前端路由,状态管理,虚拟的DOM技术
  • MWM 模式:Model-view-viewModel.模式.mvvm模式是由经典的MVC模式演变而来。当 View (视图层)变化时,会自动更新到 ViewModel (视图模型),反之亦然。 View 和 ViewModel 之间通过双向绑定(tdata-binding)建立联系.
  • Vue.js 是一个渐进式的 JavaScript 框架,根据项目需求,你可以选择从不同的维度来使用它。 

第2章数据绑定和第一个Vue应用

el 用于指定一个页面中己存在的 DOM 元素来挂载 Vue 实例,它可以是 HTMLElement ,也可以是 css 选择器.挂载成功后,

  • 我们可以通过: app.$el 来访问该元素。 Vue提供了很多常用的实例属性与方法, 都以$开头,比如$el
  • Vue 实例的 data 选项,可以声明应用内需要双向绑定的数据.

生命周期:

  • created :实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载, $el 还不可用。 需要初始化处理一些数据时会比较有用
  • mounted :el 挂载到实例上后调用一般我们的第一个业务逻辑会在这里开始。 一般用于页面初始数据的展示.
  • beforeDestroy: 实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等。

插值与表达式:

  • 使用双大括号(Mustache 语法)“{{}}”是最基本的文本插值方法,它会自动将我们双向绑 定的数据实时显示出来,在{{}}中,除了简单的绑定属性值外,还可以使用 JavaScript 表达式进行简单的运算、 三元运算。
  • v-html,v-text 
  • <span v-pre>{{这里的内容是不会被编译的 } }</ span>

过滤器:

  • Vue. js支持在{{}}插值的尾部添加一个管道符 “ ( | )  ” 对数据进行过滤,经常用于格式化文 本,比如字母全部大写、货币千位使用逗号分隔等。过滤的规则是自定义的, 通过给 Vue 实例添 加选项 filters 来设置, 
  • 过滤器可以串联
  • 也可以接收参数

<template>
<div id="add">
{{data | formdate }}
</div>
</template>
<script>
export default {
data () {
return {
date:new Date(),
}
},
filters: {
formdate (value) {
var date = new Date(value);
var year = date.getFullYear();
var month = this.padDate(date.getMonth() + 1);
var day = this.padDate(date.getDate());
var hours = this.padDate(date.getHours());
var minutes = this.padDate(date.getUTCMinutes());
var seconds = this.padDate(date.getSeconds());
return year + '-' + month +'-' + day + ' ' + hours + ':' + minutes
+":" + seconds;
}
},
mounted () {

},
methods: {
padDate (value){
return (value < 10 ? '0' + value : value);
}
}
}
</script>

<style>
</style>


指令与事件:

指令的主要职责就是当其表达式的值改变时,相应地将某些行为应用到 DOM 上,数据驱动 DOM 是 Vue.js 的核心理念,所以不到万不得已时不要主动操作 DOM,你只需要维护好数据, DOM 的事 Vue 会 帮你优雅的处理。Vue. 内置了很多指令,帮助我们快速完成常见的 DOM 操作,比如循环渲染、显示与隐藏等.

  • v-bind(:) 的基本用途是动态更新 HTML 元素上的属性,比如 id、 class 等,
  •  v-on(@) 可以监听原生的 DOM 事件,除了 click 外,还有 dblclick、 keyup, mousemove 等。表达式可以是一个方法名,这些方法都写在 Vue 实例的 methods 属性内,并且是函数的形式

第3章计算属性

在模板中双向绑定一些数据 或表达式了。但是表达式如果过长,或逻辑更为复杂时,就会变得雕肿甚至难以阅读和维护,所以在遇到复杂的逻辑时应该使用计算属性。 

每一个计算属性都包含一个 getter 和一个 setter,我们上面的两个示例都是计算属性的默认用法, 只是利用了 getter 来读取。在你需要时,也可以提供一个 setter 函数, 当手动修改计算属性的 值就像修改一个普通数据那样时,就会触发 setter 函数,执行一些自定义的操作。

计算属性除了上述简单的文本插值外,还经常用于动态地设置元素的样式名称 class 和内联样 式 style.

计算属性还有两个很实用的小技巧容易被忽略:

  • 一是计算属性可以依赖其他计算属性:
  • 二是 计算属性不仅可以依赖当前 Vue 实例的数据,还可以依赖其他实例的数据.

计算属性缓存:

调用 methods 里的方法也可以与计算属性起到同样的 作用,计算属性是基于它的依赖缓存的

一个计算属性所依赖的数据发生变化时,它才会重新取值,所以 text 只要不改变,计算属性也就不更新,对于一个获取当前时间的计算属性,即Data.now(),不是响应式依赖,计算属性的值不会更新,但对于methods的则不同,只要重新渲染,就会被执行.

第4章v-bind及class与style绑定

对象中也可以传入多个属性,来动态切换 class。另外,:class 可以与普通 class 共存.


<div class = "" :class="{}"></div>
<div :class=”{’ active ’: isActive(布尔值) }”></div>


当需要应用多个 class 时, 可以使用数组语法, 给:class 绑定一个数组,应用一个 class 列表.


<div id=” app” > <div :class="[ acti1eCls , errorCls]" ></div> </dvi>


使用 v-bind:style (即:style) 可以给元素绑定内联样式,方法与:class 类似,也有对象语法和 数组语法,看起来很像直接在元素上写 CSS

<div :style ="{’color’: color(red), ’fontSize’:fontSize+'px'}"></div>

第5章内置指令

v-cloak

  • 不需要表达式,它会在 Vue 实例结束编译时从绑定的 HTML 元素上移除, 经常和 css 的 display: none;配合使用.避免{{}}闪现  :[v-cloak]{ display: none; }

v-once

  • 也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或 组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容,

条件渲染指令:v-if、 v-else-if、 v-else:

  • 与 JavaScript 的条件语句 if else、 else if类似, Vue.js 的条件指令可以根据表达式的值在 DOM 中渲染或销毁元素/组件;
  • v-else-if 要紧跟 v-if, v-else 要紧Rli! v-else-if 或 v-if,表达式的值为真时, 当前元素/组件及所 有子节点将被渲染,为假时被移除。如果一次判断的是多个元素,可以在 Vue.js内置的<template> 元素上使用条件指令,最终渲染的结果不会包含该元素,
  • Vue 在渲染元素时,出于效率考虑,会尽可能地复用已有的元素而非重新渲染, 
  • 如果你不希望这样做,可以使用 Vue.jd提供的 key 属性,它可以让你自己决定是否要复用元 素, key的值必须是唯一的

《Vue.js实战》读书笔记_数组

点击切换按钮,虽然 DOM 变了,但是之前在输入框键 入的内容并没有改变,只是替换了 placeholder 的内容,说明<input>元素被复用了。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-card>
<template>
姓名:{{name}} </input>
<template v-if="type ==='name'">
<label>用户名: </label>
<input placeholder=" 输入用户名">
</template>
<template v-else>
<label>邮箱: </label>
<input placeholder="输入邮箱">
</template>
<button @click="handleroggleclick">切换输入类型</button>
</template>
</el-card>
</div>
</body>
<script>
/**
* @description:
* @author: Liruilong
*/
var vm = new Vue({
el: "#app",
data: {
type:'name',
name: "山河无恙",
},
methods: {
handleroggleclick(){
this.type=this.type === 'name'?'mail':'name';
}
},
mounted() {

setTimeout(() => {
this.name = "李瑞龙"
}, 1000)
},
created() {
},
})
;
</script>
<style>
</style>
</html>

v-show 

用法与 v-if基本一致,只不过 v-show 是改变元素的 css 属性 display。当 v-show 表 达式的值为 false 时, 元素会隐藏,查看 DOM 结构会看到元素上加载了内联样式 display: none;,

v-if 与 v-show 的选择

  • v-if和 v-show 具有类似的功能,不过 v-if 才是真正的条件渲染,它会根据表达式适当地销毁 或重建元素及绑定的事件或子组件。若表达式初始值为 false,则一开始元素/组件并不会渲染,只 有当条件第一次变为真时才开始编译。
  • 而 v-show 只是简单的 css 属性切换,无论条件真与否,都会被编译。相比之下, v-if更适合 条件不经常改变的场景,因为它切换开销相对较大,而 v-show 适用于频繁切换条件。

列表渲染指令 v-for:

当需要将一个数组遍历或枚举一个对象循环显示时,就会用到列表渲染指令 v-for。它的表达式需结合 in 来使用,类似 item in items 的形式.遍历对象属性时,有两个可选参数,分别是键名和索引.

数组更新

Vue 的核心是数据与视图的双向绑定,当我们修改数组时, Vue 会检测到数据变化,所以用 v-for 渲染的视图也会立即更新。

  • Vue 包含了一组观察数组变异的方法,使用它们改变数组也会触 发视图更新:push() pop()  shift()  unshift()splice() shift()reverse() 
  • 有些方法不会改变原数组filter() concat() slice() 它们返回的是一个新数组,在使用这些非变异方法时,可以用新数组来替换原数组

Vue 在检测到数组变化时,并不是直接重新渲染整个列表,而是最大化地复用 DOM 元素。替换的数组中,含有相同元素的项不会被重新渲染,因此可以大胆地用新数组来替换旧数组,不用担 心性能问题

有些变动 Vue 是不能检测到的,也不会触发视图更新:

  • 通过索引直接设置项,比如 app.books[3] = { ... }. 
  • 解决第一个问题可以用两种方法实现同样的效果,第一种是使用 Vue 内置的 set 方法:Vue .set(app.books, 3, { ...}) 
  • 如果是在 webpack 中使用组件化的方式,这时 可以使用$set ,例如:this.$set(app.books, 3, { ...}) 
  • 另一种方法:app.books . splice(3, 1 ,{ ...}) 
  • 修改数组长度,比如叩p.books.length = 1. 直接用 splice 来解决:app.books.splice(l); 

过滤与排序

当你不想改变原数组,想通过一个数组的副本来做过滤或排序的显示时,可以使用计算属性 来返回过滤或排序后的数组,计算属性 依赖于列表 ,但是不会修改列表。实现排序也是类似的,

方法与事件

@click

@click的表达式可以直接使用 JavaScript 语句,也可以是一个在 Vue 实例中 methods 选项内 的函数名

  • 在 methods 中定义了我们需要的方法供@click 调用, 需要注意的是,@click 调用的方法名后 可以不跟括号“()” 。 此时,如果该方法有参数,默认会将原生事件对象 event 传入
  • 这种在 HTML 元素上监听事件的设计看似将 DOM 与 JavaScript 紧藕合,违背分离的原理,实则刚好相反。因为通过 HTML 就可以知道调用的是哪个方法,将逻辑与 DOM 解藕,便于维护。
  • 最重要的是, 当 ViewModel 销毁时,所有的事件处理器都会自动删除,无须自己清理Vue 提供了一个特殊变量$event,用于访问原生 DOM 事件

修饰符

在上例使用的 event.preventDefault()也可以用 Vue 事件的修饰符来实现,在@绑定的事件后加 小圆点“.”,再跟一个后缀来使用修饰符。 Vue 支持以下修饰符:

 

  • 阻止单击事件冒泡                 <a @click.stop="handle"></a>
  • 提交事件不再重载页面          <form @submit.prevent="handle"></form>
  • 修饰符可以串联                    <a @click.stop.prevent="handle"></a>
  • 只有修饰符                           <form @submit . prevent></form>
  • 添加事件侦听器时使用事件捕获模式           <div @click. capture="handle" > ... </div>
  • 只当事件在该元素本身(而不是子元素) 触发时触发回调              <div @click.self="handle"> ... </div>
  • 一只触发一次,组件同样适用                                                        <div @click.once="handle"> ... </div> 

在表单元素上监昕键盘事件时,还可以使用按键修饰符,比如按下具体某个键时才调用方法:

  • 只有在 keyCode 是 13 时调用submit()                     <input @keyup.13="submit"〉

 

  • 除了具体的某个 keyCode 外, Vue 还提供了一些快捷名称,以下是全部的别名: .enter  .tab  .delete (捕获“删除”和“退格”键) .esc  .space  .up  .down  .left  .right 
  • 这些按键修饰符也可以组合使用,或和鼠标一起配合使用:.ctrl  .alt  .shift  .meta (Mac 下是 Command 键, Windows 下是窗口键)

例如:

  • <! -- Shift + S --> <input @keyup.shift.83=”handleSave”>
  • <!-- Ctrl + Click --> <div @click.ctrl=”doSomething”>Do something</div> 

第6章表单与v-model

基本用法

Vue.js提供了 v-model 指令,用于在表单类元素上双向绑定数据,

使用 v-model 后,控件显示的值只依赖所绑定的数据,不再关心初始化时的 value 属性,对于在<textarea></textarea> 之间插入的值,也不会生效. 使用 v-model 时,如果是用中文输入法输入中文,一般在没有选定组前,也就是在 拼音阶段, Vue 是不会更新数据的,当敲下汉字时才会触发更新。 如果希望总是实时更新,可以用@input 来替代 v-model.

  • 单选按钮在单独使用时,不需要 v-model,直接使用 v-bind绑定一个布尔类型的值, 为真时 选中, 为否时不选

<div id="app">
<input type="radio" :checked=" picked" />
</div>
<script>
var app = new Vue({
el: "#app",
data() {
picked: true;
},
});
</script>


  • 如果是组合使用来实现互斥选择的效果,就需要 v-model 配合 value 来使用:

复选框:复选框也分单独使用和组合使用,不过用法稍与单选不同。复选框单独使用时,也是用 v-model 来绑定一个布尔值

在选时,数据 checked 的值变为了 true, label 中渲染的内容也会更新。 组合使用时,也是 v-model 与 value 一起,多个勾选框都绑定到同一个数组类型的数据, value 的值在数组当中,就会选中这一项。这一过程也是双向的,在勾选时, value 的值也会自动 push 到 这个数组中,

绑定值:


<div id="  app">
<input type=" radio " v-model=" picked" :value=" value" />
<p>{ { picked }}</p>
<p>{{ value }}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
picked: false,
value: 123,
},
});
</script>


修饰符:

  • .lazy: 在输入框中, v-model 默认是在 input 事件中同步输入框的数据(除了提示中介绍的中文输入法情况外),使用修饰符 .lazy 会转变为在 change 事件中同步,message 并不是实时改变的,而是在失焦或按回车时才更新。
  • .number: 使用修饰符.number 可以将输入转换为 Number 类型,否则虽然你输入的是数字,但它的类型 其实是 String,比如在数字输入框时会比较有用
  • .trim: 修饰符 .trim 可以自动过滤输入的首尾空格,

第7章组件详解

组件(Component)是 Vue. 最核心的功能,也是整个框架设计最精彩的地方.

  • 组件注册后才可以使用。注册有全局注册和局部注册两种方式。全局注册后, 任何 Vue 实例都可以使用。全局注册示例代码如下:

《Vue.js实战》读书笔记_数组_02


my-component 就是注册的组件自定义标签名称,推荐使用小写加减号分割的形式命名。 要在父实例中使用这个组件,必须要在实例创建前注册,之后就可以用<my-component> </my-component>的形式来使用组件了,

template的 DOM 结构必须被一个元素包含, 如果直接写成 “这里是组件的内容”, 不带 “<div></ div>”是无法渲染的:在组件选项中添加 template 就可以显示组件内容了,

《Vue.js实战》读书笔记_数据_03

在 Vue 实例中,使用 components选项可以局部注册组件,注册后的组件只有在该实例作用域 下有效。组件中也可以使用 components 选项来注册组件,使组件可以嵌套。

《Vue.js实战》读书笔记_数组_04

Vue 组件的模板在某些情况下会受到 HTML 的限制,比如<table>内规定只允许是〈tr〉、<td>、 <th>等这些表格元素,所以在<table>内直接使用组件是无效的。 这种情况下,可以使用特殊的 is 属性来挂载组件.tbody 在渲染时, 会被替换为组件的内容。常见的限制元素还有<ul>、<ol>、<select> 。

《Vue.js实战》读书笔记_数据_05

 

除了 template 选项外,组件中还可以像 Vue 实例那样使用其他的选项,比如 data、 computed、 methods 等。但是在使用 data 时, 和实例稍有区别, data 必须是函数,然后将数据 return 出去.

使用 props 传递数据

组件不仅仅是要把模板的内容进行复用,更重要的是组件间要进行通信。通常父组件的模板 中包含子组件,父组件要正向地向子组件传递数据或参数,子组件接收到后根据参数的不同来渲染 不同的内容或执行操作。这个正向传递数据的过程就是通过 props 来实现的。 

在组件中,使用选项 props 来声明需要从父级接收的数据, props 的值可以是两种, 一种是字 符串数组,一种是对象

props 中声明的数据与组件 data 函数 return 的数据主要区别就是 props 的来自父级,而 data 中 的是组件自己的数据,作用域是组件本身,这两种数据都可以在模板 template 及计算属性 computed 和方法 methods 中使用。上例的数据 message 就是通过 props 从父级传递过来的,在组件的自定义 标签上直接写该 props 的名称,如果要传递多个数据,在 props 数组中添加项即可

由于 HTML 特性不区分大小写,当使用 DOM 模板时,驼峰命名 CcamelCase)的 props 名称 要转为短横分隔命名 Ckebab-case)

单向数据流:

Vue2.x 通过 props 传递数据是单向的了, 也就是 父组件数据变化时会传递给子组件,但是反过来不行。而在 Vue l.x 里提供了.sync 修饰符来支持双 向绑定。之所以这样设计,是尽可能将父子组件解藕,避免子组件无意中修改了父组件的状态。

业务中会经常遇到两种需要改变 prop 的情况,一种是父组件传递初始值进来,子组件将它作 为初始值保存起来,在自己的作用域下可以随意使用和修改。这种情况可以在组件 data 内再声明 一个数据,引用父组件的 prop.


<div id=” app” >
<my-component : init-count=”1” ></my- component> </div>
<script>
Vue. component ('my-component’,{ props : [’ initCount ’ ] , template :’<div>{{ count }}</div>’,
data: function () {
return {
count : this.initCount
, )
}
var app =new Vue({ el :’#app’
})
</script>


组件中声明了数据 count, 它在组件初始化时会获取来自父组件的 initCount, 之后就与之无关 了,只用维护 count, 这样就可以避免直接操作 initCount。 另一种情况就是 prop 作为需要被转变的原始值传入。这种情况用计算属性


<div id=” app” >
<my-component :width=” l 0 ”></my-component> </div>
<script>
Vue.component (’my-component’, {
props : [’width ’ ] ,
template : ’ <div : style=” style”〉组件内容</div> ’,
computed: {
style : function () {
return {
width: this.width + ’px’
., }
}
var app = new Vue ({ el :’#app’
}) </script>


在javaScript中对象和数组是引用类型,指向同一个内存空间,所以 props是对象和数组时,在子组件内改变是会影响父组件的。 props 选项的值是对象时,当 prop 需要验证时,就需要对象写法。 一般当你的组件需要提供给别人使用时,推荐都进行数据验证,比如某个数据必须是数字类型,如果传入字符串,就会在控制台弹出警告。 以下是几个 prop 的示例:


Vue.component ( ’ my-component ’, {
props : {
//必须是数字类型
propA: Number,
//必须是字符串或数字类型
propB : [String, Number] ,
//布尔值,如果没有定义,默认值就是 true
propC: { type : Boolean, default : true}
//数字,而且是必传
propD: { type: Number, required: true }
//如果是数组或对象,默认值必须是一个函数来返回
propE: { type : Array, default : function () { return [] ; }
//自定义一个验证函数
propF: { validator: function (value) { return value > 10; ) }


验证的 type 类型可以是:• String • Number • Boolean • Object • Array • Function 

rpe 也可以是一个自定义构造器,使用 instanceof 检测。 当 prop 验证失败时,在开发版本下会在控制台抛出一条警告。
 

组件通信:

《Vue.js实战》读书笔记_Vue_06

组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信.

自定义事件:

子组件用$emit()来触发事件,父组件用$on()来 监听子组件的事件。 父组件也可以直接在子组件的自定义标签上使用 v-on 来监听子组件触发的自定义事件,


<div id= ” app”> <p>总数: {{ total }}</p>
<my- component
@increase=”handleGetTotal”
@reduce= ” handleGetTotal”
>
</my-component>
</div>
<script>
Vue.component (
’ my- component’,
{ template:’\ <div>\ <button @click=”handle Increase” >+l </button>\ <button @click= ” handleReduce” >-1</button>\ </div>’,
data : function () { return { counter : 0 }},
methods : {
handleincrease: function () { this . counter++; this . $emit (’ increase ’,this.counter); } ,
handleReduce: function () { this . counter--; this.$emit (’ reduce ’, this.counter) ; } }
var app =new Vue({
el :’#app ’,
data: {
total: 0
methods : {
handleGetTotal: function (total) { this . total = total;
})
</script>


除了用 v-on 在组件上监听自定义事件外,也可以监听DOM 事件,这时可以用.native 修饰符 表示监听的是一个原生事件,监听的是该组件的根元素,

<my-component v-on:click.native=”handleClick”></my- component> 

使用 v-model
Vue2.x 可以在自定义组件上使用 v-model 指令,我们先来看一个示例:

<div id=”app”>
<p>总数:{ { total }}</p>
<my-component v-model=” total ”></my-component>
</div>
<script> Vue . component (
’my-component’,
{ template :’<button @click=”handleClick”>+l</button>’,
data : function () { return { counter: 0 }},
methods : { handleClick: function () { this.counter++; this . $emit (’input ’, this.counter);
.})}
}
var app =new Vue({ el :’#app’,
data: {
total : 0
}) </script>

仍然是点击按钮加 1 的效果, 不过这次组件$emit()的事件名是特殊的 input, 在使用组件的父 级,井没有在<my-component>上使用@input= “handler”,而是直接用了 v-model 绑定的一个数据 total。这也可以称作是一个语法糖,因为上面的示例可以间接地用自定义事件来实现:

 

非父子组件通信:

在 Vue. 2.x 中 , 推荐使用一个空的 Vue 实例作为中央事件总线(bus),也就是一个中介。 

<div id=” app”> {{message )) 
<component- a ></ component- a> </div>
<script>
var bus= new Vue ();
Vue . component (' component- a ’,
{ template : ’ <button @click=”handleEvent”〉传递事件</button> ’,
methods : { handleEvent: f unction () { bus .$emit (’ on-message’ 来自组件 component-a 的内容 ’ ) ;
., ) }
var app =new Vue ({ el :’#app’, data : { message: ”
} , mounted: function () {
var this = this;
//在实例初始化时,监听来自 bus 实例的事件
bus. $on (’on-message ’, function (msg) { this.message = msg; ., ) }
}) </script>

首先创建了 一个名为 bus 的空 Vue 实例,里面没有任何内容;然后全局定义了组件 component-a;最后创建 Vue 实例 app,在 app 初始化时,也就是在生命周期 mounted 钩子函数里监 听了来自 bus 的事件 on-message,而在组件 component-a 中,点击按钮会通过 bus 把事件 on-message 发出去,此时 app 就会接收到来自 bus 的事件,进而在回调里完成自己的业务逻辑。

父链

在子组件中,使用 this.$parent 可以直接访问该组件的父实例或组件,父组件也可以通过 this.$children 访问它所有的子组件,而且可以递归向上或向下无线访问, 直到根实例或最内层的组 件。

<div id=”app”> ( ( message } } <component-a></ component-a> 
</div> <script> Vue.component (’ component-a’,{

template:’<button @click=”handleEvent”>通过父链直接修改数据</button>’,

methods: { handleEvent: function () { //访问到父链后,可以做任何操作,比如直接修改数据

this.$parent.message =’来自组件 component-a 的内容’;
., ) }
var app =new Vue({
el :’#app’, data: { message:”
})
</script>

子组件索引

当子组件较多时, 通过 this.$children 来一一遍历出我们需要的一个组件实例是比较困难的, 尤其是组件动态渲染时,它们的序列是不固定的。 Vue 提供了子组件索引的方法,用特殊的属性 ref 来为子组件指定一个索引名称

<div id=”app” > <button @click=”handleRef”〉通过 ref 获取子组件实例</button> <component-a ref=” comA” ></component-a> </div> 
<script> 
Vue.component ( ’ component-a’, { template: ’ <div>子组件</div> ’,
data: funct工0口(){
return { message : ’子组件内容’
., ) 

var app =new Vue ({ 
el :’#app ’, methods : { 
handleRef: function () { //通过$refs 来访问指定的实例 var msg = this.$refs.comA.message; console .log (msg) ; 
}) </script> 

在父组件模板中,子组件标签上使用 ref指定一个名称,井在父组件内通过 this.$refs 来访问指 定名称的子组件。 

需要让组件组合使用,混合父组件的内容与子组件的模板时,就会用到 slot,

这个过程叫作 内容分发(transclusion)。

以<app>为例,它有两个特点: • <app>组件不知道它的挂载点会有什么内容。挂载点的内容是由<app>的父组件决定 的. • <app>组件很可能有它自己的模板。 props 传递数据、 events 触发事件和 slot 内容分发就构成了 Vue 组件的 3 个 API 来源,再复 杂的组件也是由这 3 部分构成的。
编译的作用域。

父组件模板的内容是在父组件作用域内编译,子组件模板的内容是在子组件作用域内编译。 

单个 Slot
在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个 slot (插槽),在父组件模板 里,插入在子组件标签内的所有内容将替代子组件的<slot> 标签及它的内容

子组件<slot>内的备用内容,它的作用域是子组件本身.

具名 Slot
给<slot>元素指定一个 name 后可以分发多个内容,具名 Slot 可以与单个 Slot 共存

作用域插槽
作用域插槽是一种特殊的 slot,使用一个可以复用的模板替换己渲染元素。

 

第8章自定义指令 第9章Render函数

Vue.js 2.x 与 Vue扣 1.x 最大的区别就在于 2.x 使用了 Virtual Dom (虚拟 DOM)来更新 DOM 节点,提升擅染性能。 

React 和 Vue 2 都使用了 Virtual Dom 技术, Virtual Dom 并不是真正意义上的 DOM,而是一 个轻量级的 JavaScript 对象,在状态发生变化时, Virtual Dom 会进行 Diff 运算,来更新只需要被 替换的 DOM,而不是全部重绘。 与 DOM 操作相比, Virtual Dom 是基于 JavaScript 计算的,所以开销会小很多

 

《Vue.js实战》读书笔记_Vue_07

 

在 Vue.js 2 中, Virtual Dom 就是通过一种 VNode 类表达的,每个 DOM 元素或组件都对应一 个 VNode 对象

第10章使用webpack

web pack 的主要适用场景是单页面富应用(SPA) 。 SPA 通常是由一个 html 文件和一堆按需 加载的 js 组成,它的 html 结构可能会非常简单

export 和 import 是用来导出和导入模块的。 一个模块就是一个js 文件,它拥有独立的作用域,

II config.js 
var Conf ig = { version :’1. 0. 0 ’
export { Config };
或:
II config.js
export var Conf ig = { version:’1. 0. 0 ’
其他类型( 比如函数、数组、常量等)也可以导出 ,比如导出一个函数:
II add.js
export function add(a, b) {
return a + b;

模块导出后,在需要使用模块的文件使用 import 再导入,就可以在这个文件内使用这些模块 了

,导入的模块名称都是在 export 的文件中设置的,也就是说用户必须预先知道 这个名称叫什么,比如 Config、 add。而有的时候,用户不想去了解名称是什么,只是把模块的功能 拿来使用,或者想自定义名称,这时可以使用 export default 来输出默认的模块.

 

单页面富应用(SPA) ,

而 SPA 的核心就是前 端路由。那什么是路由呢?通俗地讲,就是网址,比如 https://www.iviewui.com/docs/ guide/introduce; 再专业一点, 就是每次 GET.或者 POST 等请求在服务端有一个专门的正则配置列表,然后匹配到具 体的一条路径后,分发到不同的 Controller, 进行各种操作,最终将 htrr 或数据返回给前端,这就完 成了一次 IO。 当然,目前绝大多数的网站都是这种后端路由,也就是多页面的,这样的好处有很多,比如 页面可以在服务端渲染好直接返回给浏览器,不用等待前端加载任何js 和 css 就可以直接显示网页 内容,再比如对 SEO 的友好等。后端路由的缺点也是很明显的,就是模板是由后端来维护或改写 的。 前端开发者需要安装整套的后端服务,必要时还得学习像 Php或 Java 这些非前端语言来改写 html 结构,所以 html 和数据、逻辑混为一谈,维护起来既脆肿又麻烦。 然后就有了

前后端分离的开发模式后端只提供 API 来返回数据,前端通过 Ajax 获取数据后, 再用一定的方式渲染到页面里,这么做的优点就是前后端做的事情分得很清楚,后端专注在数据上, 前端专注在交互和可视化上,如果今后再开发移动 App,那就正好能使用一套 API 了 。当然,缺 点也很明显,就是首屏渲染需要时间来加载 css 和 js.

在 Node.js 出现后,这种现象有了改善,就是所谓的大前端,得益于 Node.js 和 JavaScript 的语 言特性, html 模板可以完全由前端来控制,同步或异步渲染完全由前端自由决定,并且由前端维 护一套模板,这就是为什么在服务端使用 artTemplate、 React 以及 Vue2 的原因。说了这么多,到 底怎样算是 SPA 呢?

其实就是在前后端分离的基础上,加一层前端路由。 前端路由,即由前端来维护一个路由规则。实现有两种,

一种是利用 url 的 hash, 就是常说的 锚点, JavaScrip/通过 hashChange 事件来监听 url 的改变, IE7 及以下需要用轮询:

另一种就是 HTML5 的 History 模式,它使 url 看起来像普通网站那样,以“/”分剖,没有#,但页面并没有 跳转,不过使用这种模式需要服务端支持,服务端在接收到所有的请求后,在fl指向同一个 html 文 件,不然会出现 404。因此, SPA 只有一个 html时,整个网站所有的内容都在这一个 html 里,通过 JavaScript 来处理。 前端路由的优点有很多,比如页面持久性,像大部分音乐网站,你都可以在播放歌曲的同时 跳转到别的页面,而音乐没有中断。再比如前后端彻底分离。

在 ES 6 中,使用 let 和 const 命令来声明变量,代替了 var. let 和 const 的作用域是“块”, 比女口:
let a = l ; var b = 2; 
console . log (b); I I 2 console . log(a); //报错: a is not defined 
con st 与 let 的主要区别是, const 用于声明常量,也就是声明后不能再修改. 如果一时还不了解它们的其他区别,可以先把 let 和 const 当作 var 来理解.

 

, webpack 会把每一个路由都打包为一个js 文件,在请求到该页面时,才去加载这个页面的 js, 也就是异步实现的懒加载(按需加载)

第11章插件

跳转

vue-router 有两种跳转页面的方法,

第一种是使用内置的<router-link>组件,它会被渲染为一个 <a>标签

​vue-router​​ 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

它的用法与一般的组件一样, to 是一个 prop,指定需要跳转的路径,当然也可以用 v-bind 动 态设置。使用<router-link>,在 HTML5 的 History 模式下会拦截点击,避免浏览器重新加载页面。 <router-link>还有其他的一些 prop, 常用的有:

  • • tag tag 可以指定渲染成什么标签,比如<router-link to="/about” tag=”Ii”〉渲染的结果就是<Ii> 。
  • • replace 使用 replace 不会留下 History 记录,所以导航后不能用后退键返回上一个页面,<router-link to=”about” replace>。
  • • active-class 当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个名为 router-link-active 的 class,设置 prop: active-class 可以修改默认的名称。在做类似导航栏时,可以使用该功 能高亮显示当前页面对应的导航菜单项,但是一般不会修改 active-class,直接使用默认值 router-link-active 就可以.

有时候,跳转页面可能需要在 JavaScript 里进行,类似于 window.location.href。这时可以用第 二种跳转方法,使用 router 实例的方法。

。 vue-router 提供了导航钩子 beforeEach 和 afterEach它们会在路由即将改变前和改变后触发,所以设置标题可以在 beforeEach 钩子完成。

导航钩子有 3 个参数:
• to 即将要进入的目标的路由对象。 • form 当前导航即将要离开的路由对象。 • next 调用该方法后,才能进入下一个钩子。
路由列表的 meta z字段可以自定义一些信息,比如我们将每个页面的 title 写入了 meta 来统一 维护, beforeEach 钩子可以从路由对象 to 里获取 meta 信息,从而改变标题。 有了这两个钩子,还能做很多事情来提升用户体验。比如一个页面较长,滚动到某个位置, 再跳转到另一个页面,滚动条默认是在上一个页面停留的位置,而好的体验肯定是能返回顶端。通 过钩子 afterEach 就可以实现:

仓库 store 包含了应用的数据(状态)和操作过程。

Vuex 里的数据都是响应式的,任何组件使 用同- store 的数据时,只要 store 的数据变化,对应的组件也会立即更新。

数据保存在 Vuex 选项的 state 字段内,比如要实现一个计数器,定义一个数据 count,初始值
为 0:

const store= new Vuex.Store({ 
state: {
count: 0
., ) }

在任何组件内,可以直接通过$store.state.count 读取:
 
 

<template> 
<div> <hl>首页<lhl>
{{ $store.state.count )) <I div> <I template>

在组件内,来自 store 的数据只能读取,不能手动改变,改变 store 中数据的唯一途径就是显式 地提交 mutations
mutations 是 Vuex 的第二个选项,用来直接修改 store 里的数据。 我们给计数器增加 2 个 mutations,用来加 l 和减 1:

const store= new Vuex . Store({ 
state: {
count: 0
} ,
mutations: {

increment (state) {
state . count ++;
} ,
decrease (state) {
state.count --;

}}

在组件内,通过 this.$store.commit 方法来执行 mutations。在 indexi 中添加两个按钮用于加 和减:

<template> 
<div> <hl>首页</hl>
{ { count } } <button @click= ” handle Increment” >+l</button> <button @click= ” handle Decrease” >- 1</button>
</div>
</template>
<script> export default {
computed: {
count () { return this . $store . state . count;
methods : { handleincrement () { this.$store.commit (’ increment ’);
handleDecrease () {
this . ♀store.commit (’decrease ’);
</script>

mutations 还可以接受第二个参数,可以是数字、字符串或对象等类型。比如每次增加的不是 1, 而是指定的数量,可以这样改写:
 mutation 里尽量不要异步操作数据。如果异步操作数据了,组件在 commit 后, 数据不能立即改变,而且不知道什么时候会改变。 

高级用法
Vuex 还有其他 3 个选项可以使用: getters(实现数据定制)、 actions、 modules。 

mutation 里不应该异步操作数据,所以有了 actions 选项。 action 与 mutation 很像, 不同的是 action 里面提交的是 mutation, 井且可以异步操作业务逻辑,action 在组件内通过$store.dispatch 触发.

 

mutations、 actions 看起来很相似,可能会觉得不知道该用哪个,但是 Vuex 很像是一种与开发 者的约定,所以涉及改变数据的,就使用 mutations,存在业务逻辑的,就用 actions

最后一个选项是 modules,它用来将 store 分割到不同模块。当你的项目足够大时, store 里的 state、 getters、 mutations、 actions 会非常多,都放在 rnain.js 里显得不是很友好,使用 modules 可以 把它们写到不同的文件中。每个 module 拥有自己的 state、 getters、 mutations、 actions,而且可以 多层嵌套。 

 

第12章iView经典组件剖析

第13章实战:知乎日报项目开发

第14章实战:电商网站项目开发

第15章相关开源项目介绍

举报

相关推荐

Webpack + Vue.js 实战

0 条评论