• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

今天的内容本也是vue的核心和基础部分,今天更倾向于理论化,尤其是vue对数据对象的监控部分。一开始我想了很久,但是经过这次努力,现在明白了很多。

10.watch和computed对比

计算属性格(看着做)

image-20220502094002770

添加一个需求,输入姓氏,然后回复一秒。

image-20220502094249940

计算

image-20220502094916097

区分:

手表能做计算机能做的所有功能。

手表能完成的功能,电脑可能完成不了。例如,手表可以异步操作,但计算不能,因为computed里面我们靠的就是那个返回值让他的getter返回值就会等于fullname这个计算属性,所以如果返回值给了定时器,那么我的fullname就没有得到返回值,但是watch不一样,watch是对值做操作,在定时器里面就已经完成了赋值的操作,不需要你返回给我.

关注3360

都说vue管理的函数最好不要写arrow函数,但是这里的timer一定要写成arrow函数,因为如果是普通的函数,那么他的this就是window,timer的this本身就是window,但是如果这里是arrow函数,大家都知道arrow函数的this就是它的位置定义的this,所以是vm实例来监控这个属性。

vue管理的函数最好写成普通函数,不被vue管理的(定时器、ajax回调、promise回调)最好写成箭头函数。

11.绑定class样式

字符串编写,适用于:样式类名不确定,需要动态指定。

注意如何在这里写随机整数。

image-20220502103751418

数组的写法:适用于:数不确定,类名不确定的情况下,将来数可能是一百,也可能是几,名可能是这个,也可能是那个。

image-20220502111554149

对象的编写方法:适用于确定对象的个数和类名。我只有这两个,而且只叫这个名字。

image-20220502111752617

绑定风格(理解)这是对象写方法,还有就是数组写方法,就是fontsize写在这个对象里,background写在那个对象里,数组写方法就是组合两个对象[obj1,obj2]

2233414638-1827378302.png"/>

12.条件渲染

控制元素的隐藏显示

image-20220502115318542

全新指令语法:v-show、v-if他们两个都可以实现显示隐藏,v-show底层实现是display:none,v-if直接把元素都删没了,所以当我们需要频繁切换显示隐藏的时候建议v-show

案例:

image-20220502115658200

image-20220502115907897

v-else-if跟v-if是一组的判断,如果前面达成条件后面就不再做判断

image-20220502120013903

v-else 注意v-else后面就不跟条件了直接写上v-else,出了条件外的都显示他

注意v-if判断是一个整体,包括else if、else,中间不能写其他的来打断

image-20220502120331959

v-if与template配合使用

我要完成这么一个界面当点击达到1的时候显示出来

image-20220502120749720

这种做法是不是有点冗余,每个都要去判断一下,所以就有一个标签template,只能配合v-if使用,它最大的好处就是不会影响页面标签布局

image-20220502121001331

image-20220502120940070

13.列表渲染

全新指令语法v-for

  • 遍历数组

image-20220502143214849

首先用了v-for我们有多少数据,就自动会遍历出多少li,然后v-for每个li是必须配置一个:key的动态属性的,我们的遍历可以写多个参数,写多少个的时候前面表示这个对象,后面表示这个对象在数组里面的索引号,而我们的key就可以配置为p.id或者是index这个索引号

image-20220502143739139

  • 遍历对象

    遍历对象要注意,遍历的值和我们的数据是反的,前面是我们的数据,后面变成了值,而且遍历对象,key就为这个属性名,

    v-for除了可以用in 用 of也是一样的效果

    image-20220502144708887

  • 遍历字符串

    字符串就是可以把每一个字符遍历出来,前面是值,后面是下标

    image-20220502145121719

  • 遍历指定次数(不常用)

    image-20220502145319747

    image-20220502145253535

13.1 key作用与原理(面试)

首先要知道我们动态生成的key并不是拿在页面上来呈现的,可以看到最终生成的真实DOM是没有这个属性的,它是用来vue拿来用的

当我们用index作为key的值会出现的问题:

有一个需求当我们点击按钮会在上面新增条数据老六

image-20220502151644843

image-20220502151717954

image-20220502151730657

是不是就出现问题了,分析一下下面这个图就知道问题在哪了

image-20220502151527517

这个就是我们前面所说的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时

image-20220502153008703

首先比较key=004发现没有,没有那就直接新增,后面的都发现有,而且数据也对的上那就直接复用

开发中如何选择key

  • 最好是用每条数据的唯一标识(id、手机号、身份证号、学号等)
  • 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,或者渲染列表仅用于展示(没有新增删除),使用index作为key还是没问题的,顺序添加删除使用它还是可以的

13.2 列表过滤

也就是模糊搜索,先完成能过滤的功能(注意数组和字符串的方法)

image-20220502162517761

这么做的话就会损坏原数据,我们的原数据是不能动的,因为要确保,不搜索了还能回去

定义一个新数组,让新数组去接收搜索出来的值,同时原数组也没有改动所以可以一直搜索,不会像原来一样越搜数据越少的情况,同时要把遍历的v-for修改为新数组,但是现在就有一个问题新数组为空,那我们刚开始的时候就看不到列表了

这里有一个很重要的概念,字符串的indexOf方法对于空字符串的查找是找得到的,意思就是任何字符串.indexOf('')都不会返回-1,都是有值的

所以只需要开启初始化就监视一下即可,这个时候keyword为空字符串,那么数据里面的每条数据都有空字符串,那就会把全部数据输出出来

image-20220502164118910

计算属性实现

计算属性能实现的,watch肯定能实现,watch能实现的只要不涉及到异步任务,计算属性一般也能实现

image-20220502164936245

就这一段代码即可实现,为什么直接就能渲染,以为watch默认是要先搜索再去执行handler,这里一来就会执行,一来就是空字符串,为什么不用自定义一个新的数组,因为计算属性就相当于一个新的数组了

13.3 列表排序

关键点在于利用计算属性里面的任何一个依赖数据发生变动都会重新运算计算节点

image-20220502171541009

  • 数组排序参数是谁
  • 排序和过滤是密不可分的,我还需要在过滤出来的基础上排序,不是一点排序就回到了原数据列表
  • 之所以点击原顺序可以回去,关键点就在于计算属性里面每一个依赖数据发生变动,都会重新计算重新渲染,所以一点击原顺序sortType就变动了,重新根据关键字去过滤数组,得出来的满足不了排序的if就直接输出arr了

13.4 vue监测数据改变的原理

先看到一个数据更新时的问题

image-20220502173642254

点击后没反应,vue管理工具也没有数据更新

image-20220502173705825

13.4.1 vue对象监测原理

image-20220502183328244

先看一张图,这里有点绕,有点难以理解,我在那里捋了四五十分钟接近一个小时,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()的使用

image-20220502205726136

这个案例首先要注意一点,在vue里面如果值为undefined,并不会报错,只是没有文字显示出来而已,这里的age没有赋值,所以undefined,在页面上并不会报错,只是一片空白没有数据

一个需求,我如果想通过将它直接赋值让页面出现他的性别:

image-20220502205930276

可以看到页面并没有显示,而且我们的数据也有,但是是写死的并不是响应式的,我们之前研究过vue的监测原理靠的就是那个setter,这里没有给她做setter所以自然也不会映射到页面上来

image-20220502210054209

  • Vue.set()vue提供的的api,可以让我们在后面添加的数据,也能够完成响应式数据,也有属于自己的getter和setter

    三个参数:第一个参数往哪里添加这个属性,第二个参数属性名,第三个参数值

image-20220502210603960

  • 第二种写法:vm.$set(参数跟上面一样三个)

    image-20220502210636767

  • 局限性

    该方法不能直接给data和vm添加属性

13.4.3 vue数组监测原理

vue里面不能直接以数组索引去修改值

image-20220502211658540

image-20220502211803257

可以看到我们数组的值都变了,但是vue监测不到,所以页面不会变,不能直接通过数组索引去修改值

在vue里面数组能被监测到的只能是可以修改数组本身的七种方法

image-20220502211917770

image-20220502212112830

所以现在就可以对我们13.4那里的案例做出回应了

image-20220502212619452

问题:为什么vue知道我们使用了这些方法

因为vue对这些方法做出了包装,不是Array原来的那七个方法了,实现逻辑肯定还是原来那种只是添加了一些逻辑(方法完成后会去重新解析模板,重新diff虚拟DOM)

让数组被监测到方法二:

Vue.set这个api也可以

image-20220502213125791

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劫持到了,去做了其他解析模板等操作,这就叫数据劫持

  • image-20220502215557912

Link to comment
Share on other sites