明天的内容书接上回,同样是 vue 的外围根底局部,明天偏差于理论性,特地是 vue 对于数据对象的监测那一块,刚开始推敲了半天,这股劲一过,当初好了解多了
10.watch 和 computed 比照
计算属性案例(watch 来做)
在减少一条需要输出姓后要反馈一秒后再响应
computed
== 区别 == :
- computed 能实现的性能,watch 都能够实现
- watch 能够实现的性能,computed 不肯定能实现,就比方 watch 这里能够异步操作,computed 就不行,<u>因为 computed 外面咱们靠的就是那个返回值让他的 getter 返回值就会等于 fullname 这个计算属性,所以如果返回值给了定时器,那么我的 fullname 就没有失去返回值,然而 watch 不一样,watch 是对值做操作,在定时器外面就曾经实现了赋值的操作,不须要你返回给我</u>
== 留神 == :
- 后面都说被 vue 所治理的函数最好别写箭头函数,然而这里的定时器必须写为箭头函数,因为如果是一般函数那么他的 this 就为 window,定时器的 this 自身就是为 window,然而如果这里是箭头函数,都晓得,箭头函数的 this 是定义它地位的中央的 this,所以就是监督这个属性外面的 this 就是 vm 实例
- 被 vue 所治理的函数最好写成一般函数,== 不被 vue 所治理的函数(定时器、ajax 回调、promise 的回调)最好写成箭头函数 ==
11. 绑定 class 款式
-
字符串写法,实用于:== 款式类名不确定,须要动静指定 ==
留神一下这里的生成随机整数是怎么的写法
-
数组写法:== 实用于:个数不确定,类名也不确定的时候 ==,个数我当前 可能有一百个可能有几个,名字可能叫这个可能叫那个
-
对象写法:== 实用于个数确定,类名也确定 ==,我只有这两个,也只叫这个名字
-
绑定 style 款式(理解)这是对象写法,同样也有数组写法,就是 fontsize 写在这个对象,background 写在那个对象,数组写法就是将两个对象联合起来【obj1,obj2】
12. 条件渲染
管制元素的暗藏显示
全新指令语法:==v-show、v-if== 他们两个都能够实现显示暗藏,v-show 底层实现是 display:none,v-if 间接把元素都删没了,所以当咱们须要频繁切换显示暗藏的时候倡议 v -show
案例:
==v-else-if== 跟 v -if 是一组的判断,如果后面达成条件前面就不再做判断
==v-else== 留神 v -else 前面就不跟条件了间接写上 v -else,出了条件外的都显示他
== 留神 ==v-if 判断是一个整体,包含 else if、else,两头不能写其余的来打断
==v-if 与 template 配合应用 ==
我要实现这么一个界面当点击达到 1 的时候显示进去
这种做法是不是有点冗余,每个都要去判断一下,所以就有一个标签 template,== 只能配合 v -if 应用 ==,它最大的益处就是不会影响页面标签布局
13. 列表渲染
全新 == 指令语法 v -for==
- 遍历数组
首先用了 v -for 咱们有多少数据,就主动会遍历出多少 li,而后 v -for 每个 li 是必须 配置一个:key 的动静属性的 ,咱们的遍历能够写多个参数,写多少个的时候 后面示意这个对象,前面示意这个对象在数组外面的索引号,而咱们的 key 就能够配置为 p.id 或者是 index 这个索引号
-
遍历对象
遍历对象要留神,== 遍历的值和咱们的数据是反的,后面是咱们的数据,前面变成了值,而且遍历对象,key 就为这个属性名,==
==v-for 除了能够用 in 用 of 也是一样的成果 ==
-
遍历字符串
字符串就是能够把每一个字符遍历进去,后面是值,前面是下标
-
遍历指定次数(不罕用)
13.1 key 作用与原理(面试)
首先要晓得咱们动静生成的 key 并不是拿在页面上来出现的,能够看到最终生成的实在 DOM 是没有这个属性的,它是用来 vue 拿来用的
当咱们用 index 作为 key 的值会呈现的问题:
有一个需要当咱们点击按钮会在下面新增条数据老六
是不是就呈现问题了,剖析一下上面这个图就晓得问题在哪了
这个就是咱们后面所说的 vue 的一大长处,虚构 DOM 加 Diff 算法,就在这里体现了。首先咱们初始化的数据,关上网页 vue 会先在内存生成虚构 DOM,同时 key 是咱们的 index,而后失常将虚构 DOM 转为实在 DOM,转到页面上来了,咱们失常在 input 框输出内容,这个时候咱们去点击新增老六这个按钮,相当于让数据变成了咱们的新数据款式,而后又会在内存生成虚构 DOM,这个时候因为是第二次生成了,所以 Diff 算法就来了,vue 会拿咱们新的虚构 dom 和旧的虚构 dom 进行比拟,而比拟的根据就是 ==key==,当咱们比拟第一条数据的时候,key 对上了之后,先去比拟文本发现文本不一样,那么就不能复用,就会以新的虚构 dom 为准,接着回去比拟 input 标签,留神这个时候比拟 input 标签会发现是一样的,为什么,因为都是 input 标签,都是 text 格局,咱们在外面输出的内容切实实在 dom 输出的跟虚构 dom 没有关系,所以比拟进去是一样的,既然一样我就能够去 key=0,以前曾经生成过实在 dom 了吧,那我就间接去拿来复用了,所以最终造成的后果就是,新增的文本就上咱们旧的 input,以此类推,所以就导致了咱们最终出现的成果有问题
这是用 index 作为 key 的问题一,还有一个问题就是效率变低了,为什么,因为咱们原来原本能够复用的数据,他给我从新生成了实在 dom 必定效率低了
当咱们用 id 作为 key 时
首先比拟 key=004 发现没有,没有那就间接新增,前面的都发现有,而且数据也对的上那就间接复用
开发中如何抉择 key
- 最好是用每条数据的惟一标识(id、手机号、身份证号、学号等)
- 如果不存在对数据的逆序增加、逆序删除等毁坏程序的操作,或者渲染列表仅用于展现(没有新增删除),应用 index 作为 key 还是没问题的,程序增加删除应用它还是能够的
13.2 列表过滤
也就是含糊搜寻,先实现能过滤的性能(== 留神数组和字符串的办法 ==)
这么做的话就会损坏原数据,咱们的原数据是不能动的,因为要确保,不搜寻了还能回去
定义一个新数组,让新数组去接管搜寻进去的值,同时原数组也没有改变所以能够始终搜寻,不会像原来一样越搜数据越少的状况,同时要把遍历的 v -for 批改为新数组,然而当初就有一个问题新数组为空,那咱们刚开始的时候就看不到列表了
== 这里有一个很重要的概念,字符串的 indexOf 办法对于空字符串的查找是找失去的,意思就是任何字符串.indexOf(”)都不会返回 -1,都是有值的 ==
所以只须要开启初始化就监督一下即可,这个时候 keyword 为空字符串,那么数据外面的每条数据都有空字符串,那就会把全副数据输入进去
== 计算属性实现 ==
计算属性能实现的,watch 必定能实现,watch 能实现的只有不波及到异步工作,计算属性个别也能实现
就这一段代码即可实现,为什么间接就能渲染,认为 watch 默认是要先搜寻再去执行 handler,这里一来就会执行,一来就是空字符串,为什么不必自定义一个新的数组,因为计算属性就相当于一个新的数组了
13.3 列表排序
关键点在于利用计算属性外面的任何一个依赖数据产生变动都会从新运算计算节点
- 数组排序参数是谁
- 排序和过滤是密不可分的,我还须要在过滤出来的根底上排序,不是一点排序就回到了原数据列表
- 之所以点击原程序能够回去,关键点就在于计算属性外面每一个依赖数据产生变动,都会从新计算从新渲染,所以一点击原程序 sortType 就变动了,从新依据关键字去过滤数组,得进去的满足不了排序的 if 就间接输入 arr 了
13.4 vue 监测数据扭转的原理
先看到一个数据更新时的问题
点击后没反馈,vue 管理工具也没有数据更新
13.4.1 vue 对象监测原理
先看一张图,这里有点绕,有点难以了解,我在那里捋了四五十分钟靠近一个小时,vue 的一个对象检测原理就是,咱们说过咱们的 data 数据最终会出现在 vm 实例的_data 上,vue 对于对象数据的检测就是定义了一个构造函数,这个构造函数会把咱们的数据的属性名全副拿过去而后做一个遍历,在遍历外面,是最重要的逻辑,用对象定义属性的办法,对象为 this,这里的 this 指的就是这个构造函数的实例,同时给他下面定义属性,当拜访到这个构造函数实例的这个属性的时候就把 obj 对应的属性的值给到他(也就是 data 下面对应的值),其实这里就是做了一个数据代理,咱们读取和写入尽管是在这个实例下面我就说 \_data 下面吧, 插值语法之所以可能间接写 name 是因为前面又给 vm 做了一个数据代理,其实 vue 的读写都是基于这个 \_data 的,读通过 \_data 来读,批改尽管是批改的 \_data 然而会把 val 给到 data 数据自身。总结就是:vue 对于对象数据的监测就是通过一个构造函数,目标是加工 data 来给 \_data 赋值,真正的逻辑在于外面的 defineProperty 这个办法,真正的监测原理就是通过这外面的 getter 和 setter 来读和写咱们的 data,而后再 setter 作进一步的逻辑,既然是 setter 那就是值变动了,就回去从新解析模板,diff 比拟虚构 DOM 看哪些能复用,再把咱们批改的值渲染下来
一句话总结:==vue 监测原理就靠这个 setter==
13.4.2 vue.set()的应用
这个案例首先要留神一点,在 vue 外面如果 == 值为 undefined,并不会报错,只是没有文字显示进去而已,这里的 age 没有赋值,所以 undefined,在页面上并不会报错,只是一片空白没有数据 ==
一个需要,我如果想通过将它间接赋值让页面呈现他的性别:
能够看到页面并没有显示,而且咱们的数据也有,然而是写死的并不是响应式的,咱们之前钻研过 vue 的监测原理靠的就是那个 setter,这里没有给她做 setter 所以天然也不会映射到页面上来
-
==Vue.set()==vue 提供的的 api,能够让咱们在前面增加的数据,也可能实现响应式数据,也有属于本人的 getter 和 setter
三个参数:第一个参数往哪里增加这个属性,第二个参数属性名,第三个参数值
-
第二种写法:==vm.$set(参数跟下面一样三个)==
-
== 局限性 ==
该办法不能间接给 data 和 vm 增加属性
13.4.3 vue 数组监测原理
vue 外面不能间接以数组索引去批改值
能够看到咱们数组的值都变了,然而 vue 监测不到,所以页面不会变,== 不能间接通过数组索引去批改值 ==
在 vue 外面数组能被监测到的只能是能够批改数组自身的七种办法
所以当初就能够对咱们 13.4 那里的案例做出回应了
问题:为什么 vue 晓得咱们应用了这些办法
因为 vue 对这些办法做出了包装,不是 Array 原来的那七个办法了,实现逻辑必定还是原来那种只是增加了一些逻辑(办法实现后会去从新解析模板,从新 diff 虚构 DOM)
== 让数组被监测到办法二 ==:
Vue.set 这个 api 也能够
13.4.4 总结 vue 数据监测
看下总结案例(如何实现性别在未增加之前为暗藏、批改数组外面的对象不须要数组的办法)
- vue 会监督 data 中所有档次的数据
- 对象中通过 setter 实现监督,且要在定义 data 时就传入数据,如果是在之后增加的数据,须要 Vue.set 或者是 vm.$set 来实现监督
- 数组中的数据通过包裹数组的七种办法实现
-
vue 数组中批改元素大多数要通过七种办法或者 set 两个 api
七种办法为变更办法,然而也有非变更办法如(==filter、concat、slice 这些会返回新数组的办法,能够让返回的新数组替换掉旧数组,同样能够受到监督,页面同样会被更改 ==)
- 最初留神一下 set 两个 api 不能给 vm 和 data 跟数据对象增加属性
- == 数据劫持 ==:就是后面说的对象监测原理,把一个完整的 data 数据变成了 setter 的形式,我如果要批改 student 的值,霎时就被 setter 劫持到了,去做了其余解析模板等操作,这就叫数据劫持