好,我们来看这道题, will 当中的 def 算法是什么意思?它的工作原理是什么? will 中的 def 算法呢,是一种智能高效的 dom 更新策略,那么只在解决前端框架在状态变化时如何最优化的同步式图的问题。 diff 算法呢,是 will 实现响应式更新和高效性能优化的一个关键技术啊,那么它的一个工作原理是什么呢? 主要有这么几个步骤,第一个呢就是虚拟 dom 比较,第二个呢就是同层级比较和优化策略。第三个三大 核心操作。第四个差异记录和批量更新。 批量更新,那我们先来说第一个虚拟 dom 比较。 will 使用虚拟 dom 作为中介,每当数据发生变化,触发渲染的时候, will 呢,就会先构建一个新的虚拟 dom 数, 并和上一次渲染后的呃这个旧虚拟倒数进行比较。 ok, 首先呢,在比较的时候,它是有呃同层级比较和优化策略,那在这里面它有两点,一个呢是同层 同层比较,还有一个双向双向便利。 will 的 def 算法呢,遵循同层级节点间的比较原则,那么这也就意味着它不会跨层级寻找节点的差异,而是仅在同一层次内查找和匹配节点。 双向便利呢,就说它采用双向便利的方式,从两端开始比较,向中间靠拢。那么这一策略呢,可以有助于在列表类型的节点更新时,更快的找到对应节点位置,减少比较次数。 这个呢就是双向便利。那么三大核心操作呢,就说移动节点更新节点、新增、 新增或删除节点。首先说移动节点,他如果发现节点只是在同层级内移动位置,算法会直接更新节点位置,而非删除并创重新创建。 那更新节点呢?就当节点属性或内容发生改变的时候,仅更新相关属性而不替换整个节点。 然后是新增删除节点。对于新增或消失的节点,算法会相应地在 dom 中添加或移除节点, 这是它的核心操作。那最后一个呃,差异记录和批量更新呢?就是等算算法执行完毕之后, view 呢,会得到一份最小化差异集合,也就是待更新的真实 dom 操作列表。 随后呢, will 一 次性批量应用这些操作到真实的 dom 树上,大大地降低了 dom 操作带来的性能损耗。 那这个 def 算法它有哪些优势呢?咱们再说一下啊,它的优势, will 的 def 算法。 will 的 def 算法之所以这么高效,是因为它能够在大量节点中快速定位差异,精准定位到需要更新的最小力度, 避免了无谓的 dom 重排与重会。那么这一特性呢,就让这个 vivo 应用,呃,即使在大规模数据变化时,仍能够保持一个较高的频率和流畅的用户体验, 同时配合 vivo 的 虚拟 dom 机制。地府算法在跨平台环境下的一个表现呢,同样优秀,保证了开发效率和运行性能的平衡。 这个呢,就是 will do 算法以及它的工作原理,还有它的一些优势,大家一定要掌握好了。
粉丝2022获赞1.6万

好,下面呢,咱们就来自己手写这个 do 算法,那么在这呢,咱分为这么几步去走啊,第一步呢,就是先把虚拟节点这块给他写出来,因为有了虚拟节点,我们才能拿旧的虚拟节点和新的虚拟节点进行对比,从而把新的虚拟节点变为真实的节点啊,渲染到页面上 啊。这是分为这么三步去走,第一步我们需要写迅捷点生成,第二步我们需要写新的以及旧的迅捷点啊,他们进行一个对比,这也是定算法中的核心了。那第三步就是把新的迅捷点呸放到音乐上啊,分为这么三步去走,然后这一步呢,咱们先把这环境搭了,然后呢把那个迅捷点给他生成了,也就是 h 函数。我们这呢要写一下。 好,在我的桌面我先来一个 diss 这样的一个通路,然后呢,我需要把那个环境给他搭了,那就按照之前的这几步去走啊,只不过这的第三步就是那个 starbond, 我就不需要安了,因为我们要自己写了。前两步咱们要搭一下啊, 来到这儿我就进入到我的终端,然后把这儿呢投进去,然后 n p m 以 meet 杠 y 行,然后呢,再去把我们的 y pad 这块儿整个给它下载喽。好,稍微等它一下,然后呢,我把那个地方的 configure 也整个拿过来了。 好,拿过来以后我们看一下那咖啡梗啊。呃,我们的 g s 路口是 s r c 下的 index 加 g s。 来吧, s r c 目录下面有一个 index 加 g s。 好,然后呢,有一个 public 目录,嗯,里边有一个 index 加 t r 行,从而呢,我们需要把那个 g s 给它引入进来,呃,是线下的 index g s。 好,那么引进来以后呢,我一会看一下这儿会不会生效哈啊,当然,下载完事以后我们还需要把这 一个 dv 配置一下啊,这样呢,就方便我们这个启动,没有别的意思,看看 open 好了,按 pm 上 dv 就可以启动了。行,先把这呢稳稳的给他创建完事啊,然后呢,咱再往下一步去走,好,那么一也弹出来了,没有问题, 证明我们的搭建是没有问题的,是吧?小 kiss, 好,然后呢,咱们就开始写这个虚拟节点了,那么到这呢,生成虚拟节点,大家还记得在 sabbob 里面是怎么做的吧?咱 bobble 里面呢,是通过一个 h 函数对吧?啊,比如说我这来一个 let 啊 v note 一,等于, 哎,我写一个 div, 第二是对象,第三个呢,可能 div 里边有内容,比如说你好鸭,你好鸭,我记得你好鸭,看他们都是这个鸭,是吧? 你好呀,这是第一种方式。第二种方式呢,哎,我这有一个 reno 单 u l, 好注意啊,是数组了啊,然后这又有 h a b c 啊,然后你比花花木兰都沉默, 行,你看,就我自己说话,大家都不说话是吧,你以后花木兰花木兰都成花木兰啊,都沉默啊,行,然后呢,你看啊,我分为这么两种情况啊,当然咱们这写的比较简单了,我就说两种情况,第一种情况呢,就是你看到第三个三个是不是字母串类型啊, 然后你再看这样的第三个参数,是不是是一个速度啊?所以说呢,咱们要考虑是 h 函数啊,证明说 h 他是个函数,他所接收的参数有三,是吧?一二三,哎,然后呢,第三个参数的类型还不是那么特别确定,所以说一 一会我们肯定会看到什么第三个参数的类型,你是这个类型,哎,你就怎么样,你是这个类型怎么样?好吧,咱们先知道这事就可以了。那如果说我的这个 v note 一,他的第三个参数为搜串,那我这一旦打印的时候,他应该的格是什么德行?哎,咱们之间其实已经记录过了, 它是不是应该长这个样子,是吧,这儿只不过叫 div 嘛。啊,这个地方我们先不管它啊,然后这儿是不是你好压呀, 对吧,你应该长这个样子,这矛盾吗?各位啊,其实也矛盾,其实也不矛盾,就是你撒撒手,最后我要返回个对象,这个对象呢,有这么多 k 以及 y, 这是我们最终核心的,各位,好吧,那下面呢,咱们就先写这个 h 函数啊,那 h 这个函数搁哪来啊?我一会新建一个目录啊,首先是个到,哎呀哈,怎么变成了这个 demo 动啊,好,然后这里边呢,我来一个 h 点 g s, 然后这呢, sport 的 defent 来一个 function, 这不就是函数了吗,对吧?然后你这儿 import h from, 然后这儿点杠 dom 下的 h, 那么就引入嘞, 对吧?你这传了三个参数好了,那我这接嘛,把 s, e, r 对一下,然后这边再写一个,这是不是三个参数啊?啊,然后这三个参数,那你懂得。我先要判断第三个参数类型啊,如果 type of 说这东西它等于了 string, 那这边什么类型啊?说 h 的 h 函数的第三个参数是自动串类型, 这做上类型也意味着它是意味着它没有 他,没有儿子。哎,就这句话不对,他没有紫元素,就是有点太太不合适了,是吧?好,这是我们这的判断,然后这呢有个 s if, 然后再判断他可能是一个什么数组,对吧?是数组。哎,算了,一会咱们再说。先说这种情况, 如果这种情况的话呢,他会生成成什么呢?生成成这个德行,那这个呢,我教我教给这 v no 的函数去搞吧。 v no 的函数呢?他就是来生成的,好吧,来生成。好,那这呢,我们就需要写一个 v no 的,点击 s, 嗯,来 s part, 别忘了这是一个方形,他也是一个函数啊,他也是个函数啊,你看我这写括号嘛,然后这地方把这个 part vno 给他引入进来, 好,最后它生成的什么样子呢?最后它生成的这个结构也说它返回的是一个对象, 那这一方一定会返回个对象,那返回对象情况下呢?他有几个参数啊?有几个 j k 啊?一二三四五六,好家伙,六。那么那这样呢,我们就给他传六个,这样返回六个就可以了啊,传六个啊,分别是我这有不按照他的顺序了,比如说 s, e, l。 呃,这题 我看一下啊,这地方的这个 k 咱们就先不要了,好吧,后面咱们再加,然后这有一个,呃,这是 date, 然后第三个参数,它的一个 children 是没有的,那所以是 artifact, 然后再返回这个啊,还有一个,你看,好吧,第二个,第三个,第四个啊,分别以此类推啊,最终形成一个,呃,对象,当然你这几个,你反个个其实也可以啊,只是我希望它的格式啊,是这种格式。好,然后到这呢,我们就整个的也给它返回一下, 我们这接一下啊,需要到我们的 vino 这块接到,分别为 s e l date 以及修正和 text 和那个 aunt 啊,然后把这个返回一下 啊,然后这样的话,大家看的这不顺啊, e s 六的简洁表示法,我给它展示成这样, 好,那这就是我们的返回的一个续集点啊,然后这个地方是返回的,好了,咱们在这儿来看一下,是不是如愿所长哈。嗯,来 cons 这儿,他说 h 意思,哎,意思到挺笨的,是在我的盗墓下的 h 啊, 嗯,为什么呢?啊?刚才的问题啊,刷新一下就好了。然后呢,你看生成的它的丘顿是没有啊, 昂尼范的,对吧?然后这次呢?说一个对象啊,然后呢,呃,这个 animus, 这个咱后面再说啊, s e r 是不是 d l a, 然后 cats 是不是你,好呀,对吧?好,然后对应的这个参数咱们再来说一点啊,你看啊,我这儿传过去一二, an e found 三四五啊,一共传过去五个,然后这儿分别会接收 s e l, s e l 是什么?就这个 啊,也就说是这儿传过来 div, 那么 s cl 就是 div 喽,然后这个是哪个呢?这个就是这个空对象,那这儿的 data 和这儿 data 就是那空对象喽,然后第三个呢?是,你好呀,对吧?传过来,你好呀,那证明这儿的这个参数就是你好呀, 啊,这边的这个参数你好压,也就说是在我对象的一二三四,第四个咱们数一下啊,他这的结构是是有点乱的啊,咱们先不管这吧,一二三四,那也就说对应的是这个 text, 对吧,然后这 text 就是你好压啊,剩下的丘震和。 呃,这个 e l m 丘震和 e l m 分别为啊,你看是吧?这是第三个和最后一个啊,第三个和最后一个,那形成了一个虚拟的盗墓。好,当然这是我们的第一种情况,那第二种情况呢?它可能会长这个样子。 好,当长第二样子以后呢?它这儿呢,就什么都不会打印了。为什么呢?是因为我们这儿并没有判断它为数组情况,就第三个参数为数组啊,判断一下 s if 啊,判断数组,判断一个变量。是不是数组方式太多了啊?可以通过呃,这 instead of 对吧?或者说可以通过它的一个原型啊,它的 contractor 是不是 arrow 啊?还可以通过 arrow 的 e, 是吧?通过这样的判断,判断他是不是一个数组,如果说他是一个数组,那我们的秋日里边就应该有,那 对吧?那我们就需要把第三个参数先给他打印出来第三个参数是啥了,就剩一个数组了吗?咱们要把它便利放到丘镇里边。那所以说我这来一个便利 啊,那咱们就通过 light item of of, 然后这有一个第三个参数便利。这个啊,数组便利。数组以后呢,我这写一个变量为求准码 为数数,然后呢,把每一个对象给它铺持到这个数数中,然后最终我们要 return 为 note, 是吧?那么它的 s, e, l 我们要给传过去,这个叫传过去啊,它的第三个参数就是受阻了,就区准了,然后后面就安迪贩子了,就是你的 tax 和 e l m 是奥迪贩子了啊,这是我们传过去的。那传过去以后呢?咱们再来看,刷新一下啊,看这个地方,你的 tax 就给安迪贩子了,对吧? 但是你的秋日里边,哎,又是每一项看到吧,你 l i 为 a 嘛,啊,这就是我们的一个虚拟节点,就算是构建了。那咱们总结一下,虚拟节点呢,其实就是通过 h 函数啊,传递到这个 wenote 啊, wenote 呢,最终生成了一个对象的结构,这就是虚拟节点 啊。然后这地方呢,是判断的啊,这地方啊,判断的 a 是函数的第三个参数是不是数组啊?如果是数组, 把它放到这吧,如果是数字组,那么就意味着,意味着啊,有 子元素啊,有子元素,好,这就是我们这一块整个的一个内容。那么行,这节课呢,咱们就算是把虚拟节点给他构建出来了,分别为两种情况,当然这样呢,咱们写的稍微的简单了一点,其实还可以判断很多很多东西的, 咱们先是以主要的写完啊,并且了解定算法的整个核心为目标往下去走,代码的不严谨呢,咱们就后面后续再去添加,比如哪一块不合理,到时咱们再去添加。当然了,可能他第三个参数,比如传的就是个这个,那么哪都不会进入了,结果呢,就是一个,呃,可能结果就成这个样子,是吧? 所以说呢,这判断并不是那么特别严谨,因为这个判断除了你是不是 string, 可能还说你是不是一个 number 也可以,对吧?那在这呢,咱们就不判断了,就说这么,呃,一个是这个情况,一个是这个情况吧。好吧,行,那本节课呢,咱们针对 h r 就先说到这。

好,下面呢,咱们就来自己手写这个 do 算法,那么在这呢,咱分为这么几步去走啊,第一步呢,就是先把虚拟节点这块给他写出来,因为有了虚拟节点,我们才能拿旧的虚拟节点和新的虚拟节点进行对比,从而把新的虚拟节点变为真实的节点啊,渲染到页面上 啊。这是分为这么三步去走,第一步我们需要写迅捷点的生成,第二步我们需要写新的以及旧的迅捷点啊,他们进行一个对比,这也是地步算法中的核心了。那第三步就是把新的迅捷点砰放到音乐上啊,分为这三步去走, 然后这一个呢,咱们先把这环境搭了,然后呢把那个迅捷键给他生成了,也就是 h 函数。我们这呢要写一下。好了,在我的桌面,我先来一个 diss 这样的一个程录,然后呢,我需要把那个环境给他搭了,那就按照之前的这几步去走啊,只不过这的第三步就是那个 黄的,不,我就不需要安了,因为我们要自己写了,前两步咱们要搭一下啊,来到这我就进入到我的终端,然后把这呢拖进去,然后 n p m eniche gun y 行,然后呢,再去把我们的 wifi 这块整个给它下载喽 啊,稍微等他一下,然后呢,我把那个地方的 configure 也整个拿过来了。 好,拿过来以后我们看一下这咖啡梗啊。呃,我们的 g s 路口是 s r c 下的 index r g s 来吧, s r c 目录下面有一个 index r g s 好,然后呢,有一个 public 目录,嗯,里边有一个 index 点 t r 行,从而呢,我们需要把那个 g s 给它引入进来,呃,是 g s 下的 indesser g s。 好,那么引进来以后呢,我一会看一下这儿会不会生效哈。嗯,当然,下载完事以后我们还需要把这儿的一个 d v 配置一下啊,这儿呢就方便我们这个启动,没有别的意思,看个 open 好了,按 p m r d v 就可以启动了。 行,先把这呢稳稳的给他创建完事啊,然后呢,咱们再往下一步去走,好,那么一也弹出来了,没有问题, 证明我们的搭建是没有问题的,是吧?小 case。 好,然后呢,咱们就开始写这个虚拟结点了,那么到这呢,生成虚拟结点,大家还记得在 sabbob 里面是怎么做的吧? sabbob 里面呢,是通过一个 h 函数对吧?啊,比如说我这来一个 let 啊 v note 一,等于, 哎,我写一个 div, 第二是对象,第三个呢,可能 div 里边有内容,比如说你好鸭,你好鸭,我记得你好鸭,看他们都是这个鸭,是吧? 你好呀,这是第一种方式。第二种方式呢,哎,我这有一个 reno 单 u l, 好注意啊,是数组了啊,然后这又有 h a c, 然后你比花花木兰都沉默,行,就我自己说话,大家都不说话是吧?你说花木兰,花木兰都沉,花木兰啊,都沉默啊,行,然后呢,你看啊,我分为这么两种情况啊,当然咱们这写的比较简单了,我就说两种情况,第一种情况呢,就是你看到第三个插入是不是 字母串类型啊,然后你再看这样的第三个参数,是不是是一个数组啊?所以说呢,咱们要考虑是 h 函数啊,证明说 h 它是个函数,它所接收的参数有三,是吧?一,二三, 哎,然后呢,第三个参数的类型还不是那么特别确定,所以说一会我们肯定会判断什么第三个参数的类型,你是这个类型,哎,你就怎么样,你是这个类型就怎么样。好吧,咱们先知道这事就可以了。 那如果说我的这个 v note 一,它的第三个参数为搜串,那我这一旦打印的时候,它应该的格是什么德行?哎,咱们之前其实已经记录过了,它是不是应该长这个样子, 是吧,这儿只不过叫 div 嘛。啊,这个地方我们先不管了啊,然后这儿是不是你,好,呀呀, 对吧,你应该长这个样子,这矛盾吗?各位啊,其实也矛盾,其实也不矛盾,就是你撒撒数,最后我要返回个对象,这个对象呢,有这么多 k 以及 y, 这是我们最终的核心了,各位,好吧, 那下面呢,咱们就先写这个 h 函数啊,那 h 这个函数搁哪来啊?我一会新建一个目录啊,首先是个 doll, 哎呀,好了,怎么变成了这个 demo 动啊?好,然后这里边呢,我来一个 h, 点 j s, 然后这呢? s pro 的 defunt 来一个 function, 这不就是卡住了吗,对吧?然后你这 import h form, 然后这儿点杠 dom 下的 h, 那么就引入嘞, 对吧?你这传了三个参数好了,那我这接嘛,让 s, e, r, bat, 然后这边再写一个,这是不是三个参数啊?啊,然后这三个参数,那你懂得,我先要判断第三个参数类型啊,如果 type of 说这个东西它等于了 string, 那证明什么类型啊?说 h 的 h 函数的第三个参数是字母串类型,这字母串类型也意味着他是意味着他没有,他没有儿子。哎,就这句话不对,他没有紫元素,这,这有点太太不合适了,是吧?好,这是我们这的判断, 然后这呢有个 s if, 然后再判断他可能是一个什么数组,对吧?是数组。哎,算了,一会咱们再说。先说这种情况, 如果这种情况的话呢,他会生成成什么呢?生成成这个表情,那这个呢?我就要我教给这 v no 的函数去搞吧。 v no 函数呢?他就是来生成的,好吧,来生成。好,那这呢我们就要需要写一个 v no 的点 j s, 嗯,来 s part, 比方这是一个方形,它也是一个函数啊,它也是个函数。好,你看我这写的括号嘛。 啊,这地方把这个 import v note 给它引入进来。好,最后它生成的什么样子呢?最后它生成的这个结构也说它返回的是一个对象啊,那这些方一定会返回一个对象, 那返回对象情况下呢?它有几个参数啊?啊?有几个 j k 啊?一二三四五六,好家伙,六个。那么那这儿呢,我们就给它传六个,这样返回六个就可以了啊。传六个啊,分别是我这有不按照它的顺序了,比如说 s, e, l, 呃,对, 我看一下啊,这地方的这个 k 咱们就先不要了,好吧,后面咱们再加,然后这有一个,呃,这是 date, 然后第三个参数, 它的一个 children 是没有的,那所以是 artifan, 那再返个这个啊,还有一个 artifan, 好吧, 第二个,第三个,第四个啊,分别以此类推啊,最终形成一个,呃,对象,当然你这几个,你反个个其实也可以啊,只是我希望他的格式啊,是这种格式。 好,然后到这呢,我们就整个的也给他返回一下,那我们这接一下啊,需要到我们的 vno 的这块接到分别为 se, l, date 以及修正和 text 和 那个 alex 啊,然后把这个返回一下,嗯,然后这样的话大家看的有点不顺啊, e s 六的简洁表示法,我给他展示成这样,好,那这个是我们的返回的一个续集点啊,然后这个地方是返回的,好了,咱们在这来看一下,是不是如愿所偿哈。 嗯,来抗速这儿他说 h 意思,哎,意思到底办法是在我的盗墓下的 h 啊,嗯,为什么呢?啊?刚才 的问题啊,刷新一下就好了,然后呢,你看生成的他的丘论是没有啊,昂尼范的对吧,然后这次呢?说一个对象啊,然后呢?呃,这个 elem 的这个呢?后面再说啊, s e r 是不是 div, 然后 cats 是不是你,好呀,对吧?好,然后对应的这个参数咱们再来说一点啊,你看啊,我这儿传过去一二, on the fund 三四 五啊,一共传过去五个,然后这儿分别会接收 s e l, s e l 是什么?就这个啊,也就说是这儿传过来 d i v, 那 s e l 就 d i v 喽啊,这个是哪个呢?这个就是这个 空对象,那这儿的 data 和这儿 data 就是那空对象喽,然后第三个呢?是你好呀,对吧?全部是你好呀,那证明这儿的这个参数就是你好呀, 啊,这边的这个参数你好呀,也说是在我对象的一二三四,第四个咱数一下啊,他这的结构是是有点乱的啊,咱们先不管这吧, 一二三四,那也就是说对应的是这个 text 对吧?然后这个 text 就是你好呀,啊,剩下的丘震和,呃,这个 e l m 丘震和 e m 分别为啊,你看 是吧?就是第三个和最后一个啊,第三个和最后一个,那形成了一个虚拟的倒码。好,当然这是我们的第一种情况,那第二种情况呢?他可能会长这个样子。 好,刚长第二样子以后呢?他这呢就什么都不会打印了。为什么呢?是因为我们这并没有判断他为竖组情况,就第三个叉是为竖组啊,判断一下 s if 啊,判断数组,判断一个变量。是不是数组方式太多了啊?可以通过,呃,这 instead of 对吧?或者说可以通过它的一个原型啊,它的 contractor 是不是 arrow 啊?还可以通过 arrow 的意, 是吧?通过这样的判断,判断他是不是一个数组,如果说他是一个数组,那我们的秋日里边就应该有内容了,对吧?那我们就需要把第三个参数 先给他打印出来。第三个三是啥了?就剩一个竖组了吗?咱们要把它便利放到清水里边。那所以说我这来一个便利 啊,那咱们就通过 light item of four, 然后这儿有一个第三个参数便利。这个啊,数组便利。数组以后呢,我这儿写一个变量为求证码 为数组,然后呢,把每一个对象给它铺持到这个数组中,然后最终我们要 return v note, 是吧?那么它的 s e l 我们要给传过去,这次要传过去。好,它的第三个参数 就是数组了,就确认了,然后后面就是安吉范的了,就是你的 text 和 e l m 是安吉范的了啊,这是我们传过去的。那传过去以后呢,咱们再来看,刷新一下啊,看这个地方你的 text 就为安吉范的了,对吧?但是你的邱润里边,哎,又是每一项 啊,你 l i 为 a 码啊,这就是我们的一个虚拟节点,就算是构建了。那咱们总结一下,虚拟节点呢,其实就是通过 h 函数啊,传递到这个微 note 啊,微 note 呢,最后生成了一个对象的结构,这就是虚拟节点啊。然后这地方呢,是判断的啊,这地方啊,判断的 a 是函数的第三个参数是不是数组啊?如果是数组放这吧,如果是数组,那么就意味着意味着啊,有子元素啊,有子元素,好,这个是 是我们这一块整个的一个内容,那么行,这节课呢,咱们就算是把虚拟节点给他构建出来了,分别为两种情况,当然这样呢,咱们写的稍微的简单了一点,其实还可以判断很多很多东西的,咱们先是以主要的 写完啊,并且了解这个算法的整个核心为目标往下走,代码的不严谨呢,咱们就后面后续再去添加,比如哪一块不合理,到时咱们再去添加。当然了,可能他第三个参数,比如传的就是个这个,那么哪都不会进入了,结果呢,就是一个啊,可能结果就是这个样子,是吧。 所以说呢,这判断并不是什么特别严谨,因为这个地方判断除了你是不是 string, 可能还说你是不是一个 number 也可以,对吧?那在这呢,咱们就不判断了,就说这么,呃,一个是这个情况,一个是这个情况吧。好吧,行,那本节课呢,咱们针对 h r 数就先说到这。

如果你的项目里面都是管理系统,没有难点和亮点,那么这个视频我就着重的针对管理系统类的项目有哪些难点和亮点,我给大家总结了十三个, 希望你把这个视频看完,绝对对你面试有帮助。第一,组建的分装什么?这组建的分装,比如说你组建为什么要做分装的?就比如说我们基于 ui 组件库怎么做分装的,表格的分页,表单,日期拆单,我怎么去做分装啊?可以从这里维度。还有复杂的组件, 比如说支持打印、导出, excel 制定密拖拽,还有复杂的业务,比如说可能更多的是这种拖拽啊,生成表单配置啊等等,类似于这地方的像拖拽生成 面板啊,然后我还可以去添加,那这是复杂的封装,这样的话大家可以评论区留言,也可以看一下主页。还有一些实用的功能,就比如说我们 excel 导入导出啊,粘贴的图片上传, 拖拽的文件上传, pdf 的 预览,还有一些特殊功能,可能就类似我们比较好火的这种 ai 对 话术的交互集成, ai 类的接口,前端渲染对话流,包括 webshop 的 通讯, y y t c 的 通讯。大家还有第三方,比如说我们接地图,接买点文本的识别, 第三方的支付接口,还有工具函数的封装,比如说我们的工具函数,时间啊,日期啊,金额啊等等,还有业务相关的 教验,随着地地规啊,塑形结构的渲染,但还有我们自定义组建,利用插件化的设计思想,怎么去自定义指令,还有复杂的一个动画, 还有性能优化相关的,性能优化这地方包含了手屏的优化,怎么玩的,体验的优化,打包的优化,速度的优化,还有共同化,共同化里面的代码规范怎么落地的,还有项目的大姐国际化,还有我们的技校 一些第三方的工具,就比如说基于 ipad 和 win 开发,制定 loader, 制定 plug, 对 吧?开发教程,还有自动化部署 jackson 四 s d 环境的隔离,当然还有我们的性能检测,从这几块,那么具体怎么聊呢? 给大家举个例子,就比如说我这个拖拽面板,我开发了这样拖拽面板的功能,那么我们怎么聊呢?给面试官,我们可以这么聊,那么我开发了一套自主的拖拽, 对吧?然后各种拖拽,拖拽怎么去实现的,怎么写,我就可以这么给你们这么聊,具体进入实现,但这里的代码你要好好看一下怎么去实现的这样的功能。还有表格,比如说表格的行和列的拖拽怎么去做的,然后我可以新增行, 新增行每一项我都可以编辑的,然后进行保存,然后我这地方新增行,就是我这个金额也是实时的进行计算的。 还有 excel 的 导出,这些点都是可以聊的,那么这个话术可以这么写,包括我们的比如说国际化的方案 要怎么去封装呢?我们支持多少种语言,语言包的按需更新,按需加载,包括还有比如说 excel 的 导出,做成这种 excel 啊,功能有多 set 的 导出,自定义表头的样式,还有格式的转换,还能够生成 zippo 捏,但对应的技术你要掌握,比如我们叉二 s 这种第三方库的使用,还有我们 可视化 excel 报表的封装有好多点,我这里面列的哈,就这每一个点里面哈对应的技术你要掌握啊。我讲的所有的内容 其实都整理到这个二零二五年干货进阶 vip 场景项目难两点,真实的简历面试题模板,还有互联网大厂里面的面试题,项目难点和热点可以下到家里面每一个题目点,每一个话术怎么写的, 我希望你完完整整的一定要看懂,看完,如果你真的是管理系统没有难看的,我建议你好好的看一下我这个 vip 干货机的味道好,需要的话大家可以评论区留言,也可以看一下主页。

各位前端小伙伴,今天咱们来聊聊 vivo 三的 ai 算法到底强在哪里?很多人好奇为什么 vivo 三的更新性能比 vivo 二提升那么多,其实核心秘诀就在于它把工作做在了编辑期和运行时两个阶段。 先说说编辑期优化, vivo 三会把模板里的静态内容提前拎出来,就像咱们整理房间时把不常用的东西单独放好, 这样每次更新就不用碰它们了。同时还给动态内容打上补丁标志,告诉运行时这里才需要更新。这就是静态提升加 pos flex 的 组合权, 直接减少了大量不必要的对比工作。再看运行时啊, u 三延续了 u 二的同城对比思想,但做得更聪明。判断节点能不能附用,依然看机和标签名。 但附用的时候可不是一股脑全更新,而是根据编一期打好的 pdf, 精准定位到需要更新的具体属性,就像医生做手术,精准找到病灶,而不是大面积开刀。 最关键的列表, u 三放弃了 u 二的双端对比,改用 p 映色表加最长递增值序列的方案。简单说就是先建个 p 和位置的对应表, 再找出不需要移动的最长序列,剩下的元素根据这个序列来调整位置,这样移动次数就能降到最少。 数据量越大,这个优势越明显,就像排队五时,先让不动的人站好,其他人只需要微调位置。所以总结一下, vivo 三 d i 就 像一个精明的管家, 提前做好规划,编一期优化,干活时又精准高效。运行时 a 静态内容越多,动态绑定越具体,它的性能优势就越突出。 这就是为什么同样的页面溜三跑起来就是更流畅。你们在项目中有没有感受到这种性能提升?欢迎在评论区分享你的体验。

前端小组学 view 三元码系列课程在上一章中,我们把目光拉回到了 patch 阶段,当我们在处理 fragment 的 子节点更新时,渲染器最终会调用一个叫 patch 圈准的函数,这时候 view 面临一个巨大的选择,就是新旧节点到底长什么样,我该怎么更新它们。而今天这一张是整个渲染器最硬核,最精彩,也是面试中最必问的一个章节, def 算法与 dom 移动策略,而我们将彻底拆解 view 三是如何通过精妙的数学算法来实现极致的性能优化的。 那我们现在就开始很多同学一听到 view 算法就会觉得 view 每次更新都在做复杂的数学计算,其实不是的, view 非常聪明,它很懒,能不 def 就 不 def。 在 进入复杂的算法之前, patch tree 其实是一个总调度台, 它其实是会去做一些相对应的一些方法,比如说翻译时优化,如果编一期标记的类型,就直接走快速的路径, 然后在运行时进行一个兜底,如果没有 patch flag, 就 会根据 shift flags 进行判断,只有当新旧节点都是数组时才会进真正进入到 diff 算法。 大家想一想,我们的子节点初准其实主要是有几种形态呢?那就是 test、 array 和 non 三种形态,那么旧节点有三种,新节点也有这三种,三乘三就构成能够我们九宫格的一个策略模型。而这其中 def 算法的最核心的就是新旧节点都是 array, 那么其他边缘情况处理就非常简单,直接替换或者卸载就可以了。现在假设我们进入的数组 vs 数组的战场,如果你的列表没有写入 key, 那 么又会怎么做呢?那它就会采用一种傻瓜式的但非常高效的一个策略,按锁影对齐, 在公共长度内就直接一一对应更新,不进行移动。而最后处理尾部,那就是旧的就会多的就会被删掉,新的多的就会被挂载。我们来看一个具体的实力,在旧列表中是 abc, 新列表中是 c, a b 按 所以进行对齐之后, a 组建就会被强制更新的 c 的 数据, b 就 会更形成 a, c 就 会更形成 b。 虽然但我们更新了,但组建内部的状态,比如说,呃,它的数据库的内容,它其实是会有些错乱的情况,就是一个典型的状态错乱, 那么 patch on kid children 是 其实只适合纯静态无状态的列表。炫了,现在我们给列表加上了 key, 那 么 view 三的核心 def 算法就正式登场了。不同于 view 二的一个双端, vivo 三其实引入的一个预处理的阶段,因为在实际开发过程中,很多时候我们只是在列表的头部或者尾部进行插入或者删除的元素,所以 vivo 三采用的 sign from state 和 sign from end 的 一个策略,那么我们首先看它的同步策略, 同步头部同步策略,时针从头开始变力,如果新旧节点的 key 和 type 相同,那么会直接 patch 时针向后移动,直到预知不同的节点,然后进行停止,这个就是退出的一个 logo, 一个循环,而这优化的列表追加的一个场景。 而尾部处理,那其实就是是从时针一一和一二是从尾部向前变力 同样跳过的相同的节点,比如说目前 c, c 是 匹配上了 b, b 也匹配上了 a 和 e, 那 就匹配不上,那就是会跳出这个循环,而这也 优化了一个尾部插入的一个场景,而经过这两步,大部分简单的更新场景,比如说 push, pop, shift, on shift 就 被完全处理掉了。如果旧列表遍历完了,新列表还剩点东西,那么就直接去挂载 剩下的,那么如果反之,新列表遍历完了,旧列表还剩下点东西,那么就直接进行卸载 剩下的,那就处理的,那假设域处理器搞定的这一切,那么函数就会直接返回,而这首性能是最优秀最优秀的。但是当域处理之后,中间还剩下乱七八糟的一堆节点,那怎么办呢? 那这时候 view 三就开启了通用乱序 def 一个模式。首先 view 三它其实会便利新列表中的剩余节点生成一个 map, 而这就是一个 key to new index map, 而其中它的 key 是 节点的 key a value 就是 节点在新数组的 index, 所以这个非常重要, key 的 value 的 值你就需要一一对应上啊。为什么使用 map 呢?是主要是为了将查找的时间复杂度从 o n 降到 o e。 接着我们去便利旧列表中剩余的节点,拿到它的 key 和上面的 map 里面去找, 如果找不到,那么就说明新列表已经没有了这些旧列表的剩余节点,那就是对旧列表的直接进行删除 on mount 操作,那如果找到了呢?那首先他就会去进行 patch, 去更新内容,记录这个节点,记录这个节点。在新列表的位置 填入一个核心的一个簇,就 new index to old index map 去记录这个映设,而这个簇它其实是记录新节点原本在旧节点中的哪个位置。零表示这个节点是全新的,非零表示它在旧节点的位置。而在这个过程中, wil 它其实会维护一个 max new index for so far 的 变量,就是如果发现当前找到的新位置比上一次找到的位置还小,那就说明出现了一个逆序的一个 一个场景,那么就是需要去移动,而 move 等于 true。 注意到目前为止 view 其实只做了一个 patch, 就 内容更新和标记 on mount 的 一个标记,真正的到幕移动还并没有发生。如果幕等于等于 true, 说明顺序乱了,我们就需要去调整到幕操作。 但是到幕的操作其实是非常昂贵的,我们的首要目的就是为了尽量地减少移动,而这里 就是他对应的一个所有的思路,就是找到那些相对顺序没有变化的节点,找到他们,让他们别动,只移动那些不合群的节点,而这个就叫做相对顺序没变的节点。序列在算法中就叫最长递增子序列。那么最长递增子序列是怎么实现的呢? 在 real 三中,它其实实现了一个 o n log n 的 一个 l i s 算法,它其实是通过贪心算法加二分查找加回数这个去进行一个处理的啊,这个算法有点难懂,所以我尽量带大家去推演一下,但是可能会比较抽象,那如果大家对这个 l i s。 非常 有求知欲望的话,那我到时候会专门去拿一期去讲这个 l i s 的 一个算法流程,这点我们就大致的去过一下它的流程,首先一,它会去进行一个阶段贪心, 如果当前组比 result, 如果当前组比 result 中最后一个对应的值大,那就继续追加,同时用 p 数组去记录前一个缩影,那其次它会去进行一个二分算法 二分查找,就是如果当前值小,那它就会替换掉吕兆中第一个大于等于它的值,让序列增长潜力更大, 最后就回数,因为贪心算法过程中吕兆的顺序可能是乱的,那必须通过 p 数组倒序去进行一个还原。 l i s 的 其实它的本质是什么?本质就是告诉浏览,告诉渲染器,这些节点原本是按照顺序去排动的,它们是队伍中的基准,别动它们去动其他的, 就是尽量的去保持一堆乱序中相对固定的一堆顺序。我们来举一个实际中的例子来去进行一个推演,我们来看输入数组三五二四的推演过程,在初时遇到三,那么会直接放到吕兆特, 然后其次遇到五比三大,那就去追加,遇到二比三小,更有潜力,就是用二替换到三。那此时需需要注意的是,路由对应实际值是二五,虽然不是合法的 a i s, 但长度是对的,那么在下一步中去遇到了四, 那么会在二和五之间来进行替换,掉五来,最终路由的缩影就是二三,对应值是二四,但是这还没有完,此时 p 数组 记录的完整的前驱链路,我们倒序回数,从铝造的最后一个缩影三,也就是它的值是四。开始查到 p 三,发现它的前驱是 是二,那值是二,所以 l i s 的是缩影二三,对应值是二四,这就是为什么铝造的在过程中是可以乱序的,因为 p 才是那个链表保证的顺序的准确性。 拥有了 l i s 序列之后,我们终于可以移动到我们了。 view 采用的是倒序遍历,就是从最后一个前节点往前数,为什么数要倒序呢?因为 insert before 的 api 需要一个 参考节点,就是 ultra。 就 如果我们往从前往后,参考节点可能还在漂泊,位置是不定的,但如果我们往后向前,那最后一个节点之后的参考节点肯定是固定的,或者是 non。 处理完最后一个,它就会变成倒数第二个的参考节点。 这里如果是映射值是为零,说明是全新的节点,直接 mount。 如果是在 l i s 序列中,说明位置相对正确,跳过不不移动,如果不在 l i s 就 需要进行移动。那么我们就来讲一个复杂的例子,是从 a, b, c, d, e, f, g 变成 a, b, c, a, b, e, c, d, h, f, g。 首先我们会去做一个头尾同步,而去搞定了 a 和 b, 然后还有 f 和 g 那 中区的乱序区域,比如说 c, d, e 变成了 e, c, d, h, 那 么我们再进行第二步, 就是构建映射,构建映射发现 a, c, d, e 都在 h 是 新的,那么我们去计算 a, i s, 发现 c, d 的 顺序没有变, 那就会去进行倒序移动, e 需要移动, h 需要挂载, c, d 不 动,那么就完美就实现了一个完整的一个 dom 的 一个操作,就是一个只需要对 e 进行移动,而 h 是 进行一个默认。那我们再来看一下它的原代码, 在 patch 标准中,它的原代码是属于那个呃 render 这个函数,它其实是去进行传输的一些参数,就 旧的 node 等于首次挂载新的为 node 而负容器的 dom, 而 ultra 就是 插动锚点,用于确定插动的位置,就是从后往前插,然后负组建实力,然后负 suspense 的 边界命名空间插槽。还有是否是启动一个 optimize 的 一个优化模式, 它其实就分三步啊。第一步进行快速路径,它首它会根据变音器生成的 patch flag 来进行标记选择优化路径,那是分为带 kid 和不带 kid, 那 对于带 kid, 那 就是会去做一个 patch kid 的 children, 而不带 key 的, 那么就是 patch on key children。 而这个简化的 def 算法其实比较简单,计算公共的一个长度,那首先它会去进行一个,在这里会去计算一个公共的任务公共的一个长度。其次 直接按照锁影进行 patch 就是 便利公共部分按着锁影位置进行 patch 就是 这一步,对于剩下的那就是会去进行一个处理,就比如说旧数组更长,则卸载多余的节点,这是卸载多余旧的,这也去挂载新的 相对的一个函数就 armit armit children, 而这就是一个没有 key 的 一个 children 的 一个环节。而快速路径中如果它是有 key 的, 就是完全 key 或者是 混合 key, 就是 部分有 key, 部分没有 key, 那 么假如走 patch key 的 children, 而这个 patch key 的 children 就是 我们所对应的一个最核心的一个地府算法,通过五个步骤来进行高效的 列表的一个实现,那第一个步骤就是所谓的头部同步来进行一个 where 循环来进行,当发现是一个 some we know 的 type, 那 就是进行对它们进行一个新旧节点的一个 patch, 然后进行尾部同步,然后从后往前遍历对对比相同位置的节点,直到与同不同的节点进行处理, 然后走到一个我们的一个公共序列已经挂载了,如果旧列表已经遍历完了,但新列表还有剩余的,那这个是意味着什么?这个就是新列表全是一个挂载的一个流程,就是一个纯新增场景直接去挂在剩余的新节点, 那如果说是新列表已经遍历完了,但是旧列表还有剩余的,那就是说明是一个纯删除的场景,就直接去卸载剩余的旧节点就可以了。 那假如第四份都已经处理了,那新对剩下的一些,还有新旧节点都还剩余一些节点的话,那就是进行未知序的处理。那就进行一个非常复杂的一个地府逻辑, 首先为新节点自营建立 key 的 一个锁影音设,用于快速查找旧节点在新列表中的位置,然后便利旧节点去尝试 patch 匹配的节点,并移除不再存在的节点,这就是用于也就是用于确定最长稳定子序列的, 这就是它接下来一个流程,就像我们刚刚提到的一个 l i s 算法的一个流程,这就是移动和挂载去进行挂载。一个新节点如果没有移动就进行一个处理, 而最后就节点就进行一个移动的一个统一个调度,那它负责什么?它负责将 node 重新插入到目标位置,处理所有类型节点的一个移动逻辑, 就比方说他支持的一个节点其实有这么多, component, suspense, teleport, fragment, etcetera 还有 element, 同时他会去做对一些 element 节点进行一些过度动画处理, enter, leave, reorder, 还有包括一些移动类型的 mode tab, enter, leave 啊复位之类的。而这里其实就是调用它对应的一些你可以理解为一个渲染器的一些操作 api 来进行对应的一些操作。那我们再回到 patch change, 刚刚我们已经聊到了它是走一个快速路径, 那么他会去,如果没有快速路径的话,那么他就会去走一个对应的一些处理,去查看他的 shop flag。 那 如果说是 children 有 三种可能性, test oral children, 那 假设他是一个 test children 的 话, 它会直接进行一个操作,是我们刚说的一个九宫格的一个操作。而这里就是我们提到的新旧节点都是一个数组,那它就会去走一个全量的一个 def, 而这个 def 就是 我们所提到的刚刚所描述到的一个场景,其实其实所有的场景都是一样的。 对,到此为止就是 patch change, 它的整个流程就已经完全的讲解,讲解完毕了,那我们再回到我们这里所说的 六三的 def 算法,其实是一个性能优化的一个非常的一个典范,它并没有一上来就搞复杂的计算,而是通过层层的演变,就比如说编程时的优化, patch flags, 标志,九宫格的判断,去快速处理掉双数组的非双数组的情况,然后再对 双数组来进行处理,就比如说是双端预处理,解决常见的头尾增生啊,再通过 l i s 来去最小化移动那个 dom 的 一个操作,这就是为什么 real 三在面对大量的数据更新时依然保持丝滑流畅的原因。那本章我们掌握了 real 三的 def 算法,如何通过预处理 和 a i s 实现最小化盗墓操作。但是有个问题就是当响应式数据变化时,是谁触发了这一切? patch 函数是谁调用的?为什么数据变了 试图自动更新了?那下一章我们将进入 real 三的心脏,就是组建的响应式更新机制和调度系统, 我们就会看到 effect 是 如何工作的,以及 view 是 如何通过异步队列来辨来避免重复渲染的啊。请务必关注我的频道前端小组。如果这篇文章对你有帮助,且点赞、收藏、转发,这对我非常重要,那我们下期视频再见,谢谢大家!

好,那么在 vaper mode 的 这个模式下呢,点 view 文件,也就是我们说的这个单文件组建啊,叫 s f s f c single file component。 s f c 文件呢,会在编的阶段就会被深度优化,比如说在静态分析这一步啊,它会便利所有的模板识别出有动态绑定的。呃,刚才有朋友说 vcombine 或者中框, 呃,算一部分,还有呢,像这种语法啊,这个呢,就是取值语法对吧?就是我们这里写的这种取值语法,还有呢就是冒号 id 这种,其实就是 v 杠啊, v 杠 bind 星,对吧?就是所有的这个地方,只要涉及到 v 杠 bind, 什么都可以,什么 a, b, c, d, e, f, g 这些都可以啊, v 杠 bind 星, 有这种语法的,它其实也算是动态绑定,还有就是 v 杠, if, v 杠 show 等等等,所有的啊,所有的这些内容都会设计啊,这我先把它删掉了, 这是静态分析这一步,静态分析完之后,接下来我们就要去深层对应的指令式代码,这些指令式代码呢,最后需要包裹在响应式副作用中间来去执行的 啊,好,这个我这里有一部分伪代码,大家可以简单看一下,这个代码我保证能够跑啊,但是是为了给大家去说明这个原理, 最终产出的代码呢,不再是一个简单的 v node 的 渲染函数,我们可以把它理解成 h 函数,对吧?这个渲染函数,而是类似于以下这种形式的,我们可以给大家看一下。呃,我们前面呢是结构,刚才给大家看的是那个屁标签,什么 hello 这一堆,但是呢,它在时创建的时候伪代码啊,就是以这个例子举例啊,就是屁标签里面套个 m s g 处理,是怎么会处理成什么样子呢?我们从这里可以看得出来,我们呢创建一个 element p 标签,然后呢创建一个文本节点,然后呢再把这个文本节点去 append 到它这个 element 里面。假设我们现在把它插入到 dom 里面 啊,那么一旦我发生发现了这个 html 里面的内容呢?它的状态发生了变化,这个 m s g 啊,发生了变化,一旦发生了变化,我就只需要把这个 text node 里面的 text content 去更新一下就可以了。 所以你看我们中间如果说省掉了一个对比的环节,好直接,就像就比如说你,呃,真的啊,大家在这个 期待爱情的时候,对吧你,你很多同学其实比较喜欢去暗恋别人,没有必要,你中间还要有一个这个 这个这个这个传性的,或者说是呃撮合你们俩的这样一个角色呢,其实并不需要,你就直接一点啊,爱就大胆说出来。你看我们现在如果说把虚拟 dom 中间的这个环节省掉了之后,其实你只用去考虑什么样的数据会引起我们对应 dom 的 变化, 那么这个 text node 呢?其实就是我对应 dom 里面的数据,对吧?它的数据在发生变化的时候,我就只需要直接去操作之后这个 dom 就 可以了。 这个伪代码其实就是呃,这个 vapor mode 这种形式的最核心的一个原理啊,最核心的原理啊,大家可以从这里去看一下。那其实以前我们在给大家讲那个 view 的 呃这个原码的时候给大家说过, 如果说涉及到还有虚拟 dom 这一层,那这第一步这个呢,可能它都是偏厚的,它不需要去在呃这个静态模板这一块去考虑它的这个创建,而是先做整个 dom 的 diff, 就是就是我们说的这个虚拟 dom 的 diff, diff 完之后我们才会去做这个 patch 的 更新,对吧?来去看它的 dom 节点这些内容是怎么去做更新的啊?是该删掉的还是该新增的,还是该做替换的等等处理, 并且呢我们在前面,对吧?大家去面试的时候涉及到虚拟 dom 的 diff, 就是 就是我们说这个 diff 算法啊,还会涉及到什么快速 diff, 还有呢双端 diff 等等,这些其实都是没有必要的啊,都是没有必要,我们只需要在 编辑的时候做好这个标记,然后呢知道这个状态变更之后,需要去通知哪个节点,以什么样的方式去改它里面的内容就可以了。 这个思路是不是简单?这有同学说这不是又回到了原始的操作当中了吗?是的,很多技术啊,它就是这样最终返璞归真了啊。其实绕了一大圈,你会发现在当初我们都一直在用的这些技术,呃掌握的这些方向,其实它可能反倒是最好的, 但是我们做技术的其实呃可以不留遗憾,对吧?但是这其实也有一个这个叫叫叫叫叫, 但是大家在生活里面啊,或者是在平常的工作里面啊,或者是在这个大家身边,如果说呢,你 vivo 现在不是这样的, vivo 现在的话不是这样啊, vivo 现在目前的话还是虚拟端的这种形式。 目前方式的缺点给大家刚才说了啊,主要是如果是涉涉及大数据样的这个数据表格的渲染,还有呢?呃,极致的动画体验的要求他做不到,我们都需要去直接转向,用原声来做,原声,做完之后再去跟当前的框架去做一个对接啊,一定需要有这样一个环节。

大家好,这里是和前端小组一起学 view 三原码系列课程。本章节将讲解 dom 系统的第一章, runtime dom 设计。 view 它其实是一个响异式的一个 ui 框架,开发者描述界面应该是什么? view 负责将这个描述变成真实的 dom, 但是 real 它其实并不仅仅只是一个限于浏览器渲染,它希望能运行在任何的平台。这就引起了一个核心的架构设计,就是渲染什么和如何渲染进行一个分离, 而其中渲染什么就是 runtime core 和如何渲染就是 runtime dom。 runtime core 就是 定义的 diff 算法以及组建生命周期以及通用逻辑等等。而 runtime library 它其实是定义的 dom 操作事件绑定, 这就是浏览器特有的一些行为。这种分离带来了非常巨大的一个灵活性,就是同样的 run time query, 配合不同的平台,实现可以渲染到浏览器的 dom canvas, 原生移动端甚至是终端平台。 而本章节我们将聚焦于浏览器平台,看看 run time dom 是 如何将 view 的 抽象渲染能力落地到一个真实的一个 dom 的。 每个 view 的 应用都从 create a p p 开始,这也就是我们日常最常见的一个 api。 那 么 create a p p 变后代码到底发生了什么啊?我们可以看一下它这个原代码的一个实践。在这一中我们需要注意的是 app 它里面它调用的 ensure, 它是什么?它是它。其实 ensure 它保证了渲染器只创建一次,并且它是一个惰性创建的过程。对,在这它是一个惰性创建的一个过程,只会去创建一次,然后它会返回一个 app, 并且它还会去将 mount 给重写的,就 app 的 mount 好 像是给重写的,它里面去增加了一个容器解析,就 memorize 清空容器,做一些数据属性的一些标题,去做了一些这样子的一个动作。这就是个 create app, 它内部的具体的一个实现。为什么它是要通过 ensure 这个函数去做处理呢?它是它采用的惰性触式化渲染器,只在第一次调用 create app 的 时候创建,它主要是为了一些 tree shopping 就是 如果用户只使用响应式的 api 而不需要渲染层, 那么渲染器代码可以被完全的移除,大幅度的减小了包的一个体积。又提供了两个创建应用的函数,一个是刚刚我们提到的 create app, 一个是 create ssr app。 二者的区别其实非常简单,就 create a p p 使用 ensure render, 它挂载是清空容器, hydrating 就是 force a create a p p 就是 使用 ensure hydration render, 就 保留保留的容器内容,就是附用 h t m 的 hydrating 就是 true。 在 之前我们提到的 normalize container 就是 容器解析, 在这里它其实它 mesh container, 它支持自创选择器 dom element shadowroot, 同时这的 result resultroot name space, 它是会自动地去识别 svg 和 mass massmail, 去确保紫元素在创建时使用的正确的。 create element name space 这里我们需要注意的是,这个 memorize container 自动选择器就是我们最常见的方法,就是井号 a p p 会使用 document script 去查找元素,而 element 是 什么就直接传到 dom 元素,比如说 document 点 get element 百 id a p p, 然后 shared root 是 什么?就是支持挂载到 shared dom 中,而这对于 web browsers 是 非常重要的。 o p s note o p s。 是 run time dom 的 核心,它封装了所有底层的 dom 的 操作,大家可以看到它其实它这边暴露了非常多的一个呃 dom 的 一些方法。 insert remove create element test set element test parent node nest parent data 它其实它只是对一个 dom 的 一个 api 进行一个二次的封装,去结合 view 的 一些内部属性,为什么要去封装它们呢? 这是为了去做一些跨平台的一个抽象能力以及命名空间的处理,还有特殊元素的处理。在这里我们可以看到它其实内部,它 其实内部它去做了一些将平台无关的 carry 逻辑与平台特定的 dom 进行操作。就渲染器它需要两类操作,就是 node op 就是 元素级别的侦查改杀 patch proper 就是 元属性级别的更新,而这两者进行一个有机的一个结合,去将平台无光源 query 逻辑与平台 dom 的 dom 操作去 结合,而这里就是通过 instant 去传递给 query 的。 create render run time query, 它其实根本不关心节点是 dom element 还是 canvas 对 象,它只调用住读的 note a p s 接口, 就是 render, 就是 渲染层,它其实是 core 加 node ops, 而对于 dom 就是 浏览器来说, node ops 其实就是 runtime core runtime dom 在 刚刚我们可以看到 我们是有一些特殊的一些 dom 的 一些操作,那其中这里面会有个非常重要的性能,就是我们性能优化。我们面试中经常问到的就是编辑器,它会识识别模板中的静态内容,就是我我们之前他在编辑器中提到的静态提升的一个作用, 它其实它会去将它们提升为自常量。自创首次渲染就是解析 html, 自创 tabloud 缓存命中的时候,就是后续渲染就直接会刻入 node, 就 大幅度提升了大量静态内容上的性能。 需要特别提到一点, destet types 就 安全策略,而这个一点我们会将下一个章节会着重去讲。现在的浏览器,它其实支持 trace trishtypes, 这是一种防止叉 s s 攻击的安全机制,它要求所有处理 in the html 的 值都必须经过性能处理。在这里我们可以看到 view 它其实做了什么,它其实它是输出 web, 就是 如果浏览器支持的话,它其实去创建那个一个名为 view 的 trishtype 策略。 当设置 in the html 的 时候,通过 serve to trishtype 来去包装值,这里这里返回的 create html 实现 是简单的,返回的原值就是 real, 它其实是假设传输的内容是可信的,就是来自编曲生成的静态内容。如果 c s p 策略不允许创建重复的策略名,它会去捕获到错误,并在开发中去反警告。 real 三中对 reference 它其实有非常友好的支持度,就 define custom element, 可以 将 real 组建转换为文原生的 cost element。 大家可以看到在这个章节中就 it's cost element, 它其实就定义的就是 如果当在 view 中使用第三方 costemaster, 需要配置编辑器,告诉 view 知识原生标签不需要尝试解析成一个 view 的 组建,而这里它有个非常,而这个就是一个缩减器创建 流程的一个核心,那个逻辑就是 create a p p in sharer 不 存在就可以的去注入 node o p s a patch, purpose 等等,然后包括它的 a p p 重写, mount, mount normalized container, 清孔笼器,执行挂载等等的操作。 time dom, 它是位于浏览器 dom 之间的一个桥梁,它通过 node o p s 封装底层的 dom 操作,通过 patch proper 去处理属性更新,将这家平台的相关实现注入到了 runtime core 的 通用渲染器中, 并且它 create a p p 的 延迟模式对程序员非常友好。这些分层的设计其实是使得 feel 具有了跨平台能力,同时在浏览器平台上保持了高效的盗木操作。而下一章节,我们将深入地去做 hash proper, 去看 cast trace 是 如何被高效地进行更新的。 那我们有些思考题就是用什么 create a p p 设计成以延迟创建缓存机制,它是何时失效的 close shared route 的 问题。 好的,那本次节目就我们到此结束了。好的,本期内容就到此结束了啊,欢迎大家订阅分享以及关注我的频道,我们下期节目再见,我是前头小猪。

刚刚面试了一个四年前端,简历上写着精通 v o s 开发。我问用户打开一个 v o i 应用,从始化到销毁,中间经历了哪些阶段?每个阶段适合做什么?他回答, before creator creator before mount mounted before updated updated before unmount unmount。 我 追问具体每个阶段能访问什么? d o m 在 哪个阶段可用,亦不请求应该在哪个阶段发。服务端渲染时哪些钩子不执行? keep alive 组建多了什么钩子?组合式 api 里这些钩子怎么用?它开始背钩子名称, 但分不清时机和用途。很多四年的开发者只知道生命周期勾子的名字,却不理解每个阶段的执行时机和最佳实践。面试到此结束,了解的还是不够多,这其实是一个很多中级前端都会踩到的坑。如果这道题目你也不会回答的话,我整理了让大厂 hr 沉默的必考题库, 包含 v o 灵魂拷问、 react 高频陷阱、 js 十连问、点个赞,评论区甩六六六,打包带走 nice, 系统性的掌握 v o 三、生命周期需要打赢这四场战役。第一战役,出土化阶段,组建诞生 before create 特点,实力出土化完毕,但数据观测、事件配置还未开始,能访问,无 实战价值,极少使用可用于插件开发时的特殊逻辑组合式 api 对 应,没有直接对应 script step 默认在 step 阶段 created 特点,数据观测属性方法计算属性已完成,但 d o m 未生成,能访问 data props computed methods, 不能访问 d o m 元素 a l e。 实战价值,发起异步,请求驶驶化,非响应式数据监听事件。注意,服务端渲染时也会执行,避免操作。浏览器 api 组合式 api 中的对应 type 的 函数本身就是这些阶段的整合 执行时机。 before crease 之前可以访问 props, 但还没有 dis。 第二战役挂载阶段, d o m。 登场 before mount 特点,模板编印完成,即将首次渲染到 d o m。 能访问模板已编印但尚未插入 d o m。 实战价值,极少使用最后一次修改数据的机会。注意,服务端渲染不执行。 mounted 特点,组建挂载完成 d o m。 已生成能访问 d o m 元素 e l。 子组件实战价值,操作 d o m。 第三方库出尺画图表渲染,访问或修改子组件, 添加事件监听 resize scroll 发起依赖 d o m。 的 异步请求。注意,不能保证所有子组件都已挂载,用 next tick 或嵌套 mounted。 组合式 e p i unmounted。 第三战役更新阶段,变化响应 before update 特点,数据变化后, dom 更新前能访问最新的数据。旧的 dom。 实战价值,在 dom 更新前获取旧状态,手动移除或修改即将变化的内容,避免频繁更新的优化。注意,避免在此阶段修改数据。 updated 特点,数据变化导致 dom 重新渲染完成,能访问最新的数据和 dom 实战价值,依赖 d o m。 更新的操作,监听数据变化后的副作用坑点,不要在 update 的 中修改数据,每次数据变化都会触发。注意性能,组合式 api un updated 性能优化, 避免不必要的更新。 vmail should updated 批量更新多次数据修改合并为一次更新。第四战役销毁阶段,组建谢幕 before unmount 特点,组建即将销毁,但还完全可用,能访问所有数据。方法 d o m 实战价值清理定时器,取消网络请求,移除事件监听,保存临时状态到上层或存储 vo 二中叫 before destroy amount 特点,组建已销毁所有指令,解绑事件监听,移除能访问,已无法访问。组建实力,实战价值最终清理通知, 副组建或局建立实战价值最终清理通知副组建或局建立。实战价值最终清理通知副组建或局建立。实战价值最终清理通知,副组建或局建立。实战价值最终清理通知。 api on amount keep alive 专属钩子 unactivator 组建被激活 undactivator 组建被缓存 场景标签页切换时保持状态,列表页返回时恢复滚动位置。实战案例,复杂表格页的生命周期设计需求,表格页需要初步加载数据,监听窗口 reset, 调整表格列宽,定时刷新数据离开时清理。 设计 created, 发起出示数据请求 mounted, 注册 resize 事件监听驶驶化表格 d o m 操作 before update 表格数据变化前记录当前滚动位置。 updated, 数据加载完成后恢复滚动位置 unactivated, 重新注册 resize 监听 auto captured 捕获子组建错误降级显示或上报。这个就叫专业。 这道题考察的是对 v o i 组建生命周期的深刻理解,以及在不同阶段做出正确操作的能力,是四年前端写出高质量无坑代码的基石。最后,你遇到过生命周期使用不当导致的 bug 吗?是怎么发现和解决的?

ps 四四折腾版 ps 四十三点零零与 ue 折腾教程那么上一期的视频我给大家介绍了,如果你的 ps 四已经可以折腾了,就是在十二点五二以下的版本,我们不管是用 u 盘折腾,还是网站折腾, 还是玩科云全能折腾器, esp 三二还是光盘折腾,我们都是已经可以折腾的机器,如何改用 ue 来折腾的教程, 当然这就是给大家提供了多一个的折腾方法。那么今天我说的第二种情况就是,如果你的机器是十三点零零,它不能够使用其他的折腾方法,那么只能使用 ve 的 折腾方案,那该如何进行操作?那么目前对十三点零零的机器, ve 是 它唯一的折腾方案啊,十三点零零以上目前是没有办法折腾的, 那么你正巧是十三点零零,那么我们就可以使用这个 v u e 来折腾它,当然这个方案也可以支持到七点零零到十三点零零的其他版本。首先这个方案呢,意味着你的机器原来里面的所有游戏,包括你的游戏的账号存档全部会丢失, 所以在使用这个方案之前,你要确认你已经愿意放弃你之前所有的游戏数据。当然以后如果回到正版,你的账号和存档还是可以用的,那么如果你之前下过数字版,那么这些游戏是不能再用了,包括存档。那如果你是有光盘版的游戏呢?折腾之后呢,还是可以用光盘版再来安装一遍,仍然是可以进行游戏的, 只是存档没有了。所以我们在折腾之前要有这样的个心理准备啊。那总结一下,十三点零零的版本只能用今天这一期的 vue 方案,而七点零零到十二点五二的可以用,上一期我给大家介绍的就是其他折腾方案,改成 vue 的 折腾,那它可以保留你原来折腾中的所有的游戏和存档。 好,那么接下来我就给大家具体操作一下。首先我们准备一个 u 盘,将它格式化成 exfit 格式, 然后把我提供的这个 v u e 的 补丁包拖到我们的 u 盘中,同时把这个配乐的点宾这个文件也拖到我们这个 u 盘中,这个配乐的宾就是我们最新的 good bye。 那 么这两个文件拖过来之后呢,我们就把这个 u 盘拔下来啊,插到我们的 ps 四主机上,你现在来到我们的 ps 四主机,进入设定中的系统,在这边选择备份或还原 点,进来之后呢,我们这边使用的是还原 ps 四,那么在这里呢,我们就看到它让你选择还原的数据,也就是我们刚才拷到 u 盘上的这些数据。好,接下去就是确定是系统就开始还原了,这个时候我们就耐心等待它还原数据, 那还原结束之后呢,它就会提示你让你按 ps 四手柄上的 ps 键,我们按下 ps 键之后呢,就可以选择我们的用户了,这个时候我们就可以看见它多了一个 vue user 这样一个用户,我们就使用这个用户来登录我们的 ps 四,而进到系统首页,我们就看到现在这个 vue 应用已经存在了。好,那么我们先不去管它,先进到设定,把我们的语言恢复成中文, 在设定中选择 language 就是 语言第一个选项啊,拖到 简体中文确认之后呢,我们的系统呢就会恢复到简体中文状态。好,那么我们继续进入设定,在这里自动下载, 进去之后这三个钩要把它去掉啊,防止系统自动下载,这个已经是常规操作了啊,大家都知道的。然后这里是重点,一定要把你的网络的外网,也就是连接到互联网的这个网线暂时先拔掉, 防止你的 ps。 四,连接到互联网,注意这一步很重要啊,因为如果你连在互联网上,你的 v o e 可能会自动下载更新版本,那我们这个 v o e 的 折腾就没有用。把网线拔掉之后,我们进到设定中的网络,这边连接互联网,打上勾 进入设定互联网,那在这边我们就可以连我们家里的 wifi, 这边选择定制,连上我们家庭的 wifi, 在这里选择自动不设定 dns 的 设定,一定要使用手动, 在这里我们设置一个首选 dns, 注意看一下这个 ip 地址,一定要跟着我的视频上的 ip 地址完全一致, 设置好之后我们继续自动不使用,设置完了之后,我们返回查看一下连接状态,这个时候如果我们的 ip 地址已经可以获得了,并且我们的首选 dns 跟刚才设置的一样,就说明我们的网络设置好了。好返回首页,这时我们开始运行 vue 的 这个应用程序, 注意应用程序是使用大叉来确定的,进来以后呢,它会有一个提示,直接大叉确定 好,他就会进到我们的 vue 折腾界面。这个时候呢,通常我们不需要设置任何的内容,直接是点第一个 越狱系统就会执行越狱程序,那他会显示一个画面啊,首先上面有一句红颜色的英文,然后有一个向下的大拇指,那就表示这次他的 vue 折腾失败了,那么如果出现失败的话,我们就重启我们的 ps 四再来一遍啊,进到 vue 还是刚才 这种界面,然后直接点预好,当我们出现这个绿颜色的字,并且有一个大拇指向上的姿势的时候,那就表示我们这次折腾成功。那我们只要返回首页,我们就会看到,哎,这个 go 的 图标又出来,然后进了系统,我们也可以看到最新 go 的 版本, 这样我们整个折腾就完成了。那为了测试一下它的稳定性啊,我就是反复重启以后使用我们的 voe 来折腾,那按照我的经验就是前几趟可能确实会出现这种失败的,可能甚至会出现死机和重启的问题, 那随着你的不断折腾,它的 voe 的 成功率会越来越高。那我到后期呢,基本上已经非常顺了啊,基本上就是五次里面大概有一次会失败 啊,他的成功率还是相当高的。那么只要你的 voe 折腾成功一次,今后呢,你的外网仍然是可以连上去的,也就说以后再连着外网用 voe 也没有问题。但是我个人的建议呢,还是尽量不要连到外网去,因为可能会出现系统自动下载更新你的固件的问题。 好,这就是我们十三点零零系统在不能使用其他方式的情况下,如何去折腾我们的 ve。 那 么这两期我都给大家介绍了关于如何使用 ve 来折腾我们 ps 四的方案, 那么上一期讲的是你原来已经可以折腾了,那么改成 ve 怎么去折腾的方案?今天讲的是重置系统使用 ve 的 方案,因为目前十三点零零是没有办法用其他方法去折腾的啊,所以你只能用今天的方案。 视频中相对应的工具和软件都可以到我的主页粉丝群,我是无偿分享给大家的。好,那么今天视频就到这里,我是老王韩语,喜欢我的视频点赞关注,我们下期再见!

来到和前端小组一起学 real 三元码,本章节我们将讲解属性系统。属性系统看起来非常简单,但实则暗藏玄机, 它里面有处理有一些核心的问题,比如说 class 应该使用 class name 还是 set attribute style? 如何高效地 def this able? 是 设置 dom 属性还是 html 属性? 为什么表达元素需要双重设置?这些问题的答案都会在章节中进行得到详细的解析。 在上一章节我们看到的 render options, 它是由 not apply patch proper 去两部分去组成的,而其中 patch proper 是 负责属性的设置与更新,当 view 需要去更新一个元素的 class style 事件或者其他属性时,都会调用 patch proper。 而这一章节我们就将沿着 patch proper 的 分发路径去从先盼什么后盼什么入手, 把属性系统的关键决策点去逐个拆解。而 patch proper 是 属性处理的路口,它根据函数名的特征,将处理分发给不同的专门的函数,其中我们就可以看到它这里是去 patch style patch class, 然后去处理一个 event 以及对应的一个表单元素的设置,这也是它对应的一个 tag 和 custom element 的 特殊处理。以及最后是一个 patchdom 的 proper。 屏幕看起来就代码有点少, 所以看的不是很清楚,但是没有关系。在接下来章节中,在接下来章节中,我们将会一一去解析这些函数。 patch proper 的 分发顺序是非常有讲究的 啊,比如说它首先对一个 class 是 最常用的属性,它是会优先处理,而 style 第二常用,它需要特殊的 def 逻辑,而对于事件就是 on, 是 以 on 开头的属性去交给事件系统。而对于 dom 属性和 html 属性,它会根据 should setup as proper 去进行一个判断。这里有个值得非常提前记住的点,就事件分支算在 purpose, 你只是转发给了 patchevent, 但它背后决定了事件更新的性能上线就为什么要保存 in worker, 为什么我们尽量避免 频繁的 a, d, d 和 remove。 而这一块我们先按下不表,后面一个章节会将门进行展开。这个模板是支持点 proper 和 auto 修饰符去强制指定属性的设置方式。大家可以看到它是会有这两种修饰符, 而编辑器会将这些修饰符保留在属性名中去运行,通过检手手字母来去进行一个识别。大家可以看到它是运行时通过检查手字母来去识别。 而这里是巧妙地运用了一个表逗号的一个表达式,就比如说是这 key, key 等于 key 的 status 一, 就先去掉修饰符前缀,再返回布尔值去决定走了哪个分支。我们了解了修饰符的处理逻辑,现在我们来进入一个高频分支,就是 class 的 处理。 class 绑定是 view 中最常用的动态绑定之一,而 view 它其实是支持三种绑定方式,就在 templar 上是有冒号 class 自创一个是还有包括一个对象,甚至包括一个数值。就无论是哪种方式,最终都会被规范化为可直接应用到 dom 的 形态。就 模板编辑阶段,会尽量把 class 归一化,运行时也会在需要时去做兜底。例如在 n 的 函数中去闯入一个对象簇时会走 normalize class, 因此 patch class 接受的 value 通常是就是最终的 class 字母串。大家可以看到这就是一个 patch class 的 一个最终处理方式, 它这里有几个关,非常关键的点就是过度 class 的 合并,就是这里有个处理过度动画的临时 class, 当元素处于过度动画时, transition 组间会在元素上去添加这些临时的 class, 比如说 to interactive 这些 class 去存储在 adder, 会存储在 adder await 信息 key 中,而 patch class 需要将它们与用户绑定的 class 合并。第二个就是 classname 和 set attribute, 这对于普通的 html 元素中,它就直接去设置 e l 点, classname 比 set attribute class value 会更快,但 sv 机必须使用 set attribute, 所以 它这里有个判断,就是 is sv 机它会去通过 set attribute 形式来去 做。同时大家可以看到为什么不用 classlist, 就是 通过 classlist 的 a, d 和 remove 需要足够去操作 a class name 可以 去一次性设置整个 class 的 字母创,就当 class 变化较大时去直接赋能会更加的高效。理解了 class 的 整创 替换之后,再去看 style 的 就会发现它的复杂点就来自两个点,一个是它贴呢,是箭指队的集合,第二个就是它还承载了 will, 杠, show 等行为层面的协助需求。因此 patch style 的 核心不只是设置,而是以最小代价去维护一致 style 的 绑定比 class 复杂的多,它支持字幕创和对象两种方式,需要处理 class cs 变量,浏览器前缀或者 unimportant 的 等特殊的情况。 大家可以看到这样子的一个方式,呃,这就是一个 patch style 的 一个智能 def。 首先它对于一个对象形式的时候,它是需要去做一个 def, 就是 旧址也是对象,它会去移除不再存在的属性,而旧址是函数创,它会是解析后去移除不再需要存在的属性, 然后它就会去设置一个新的属性,最后它就是去做一些函数,向量等等。这样的方式是 style 的 def 的 算法, 它其实是采用两步的形式,就当新旧值都是对象的时候,它会去一首先去移除旧属性,就避利旧对象,如果某个属性在新对象中不存在,将其设置为空字母串。第二步就设置新属性,去便利一个新对象去设置所有的属性。而这种算法的时间复杂度是 o m 加 n, 其中 m 和 n 分 别是新旧对象的一个属性的数量,其中 set style 它就是属性设置的一个细节点。首先如果是以宿主形式的,它就会依次地设置去用于 cs 回退值。 其次,如果是使用 cs 变量的话,它是必须要通过啊 set property, 如果它是 important 的 话,它也是必须要通过 set property 去做处理的。 大家刚看到这个 set style 的 一个特殊处理,其实它这里面是有两个,一个是 cs 变量,那 cs 变量它是怎么去做识别呢?就是以杠杠开头的属性是 cs 自定义属性值必须要使使用 set property 来设置,不能直接复制而杠。而 important 的 值也是必须使用 set property, 并将 杠 important 作为第三个参数去做传录。同时数对于数值值的 style 值用于 cs 回退来进行处理啊。请注意它这里有个非常点,就是 autprefix, 刚刚我们看到它会进行一个自动添加浏览器前缀, 那它是怎么做的呢?它首先 prefix 会检测浏览器是否支持某个 cs 路径,如果不支持,那它就会去尝试添加 web webkit mode ms 前缀,它的结果会被缓存去避免去重复的检测。而请需要注意的是, freet 属性会被特殊处理,即使浏览器支持无前缀的 freet 也会去做尝试添加前缀,这是因为某些旧版本的浏览器的 freeet 行为不一致。除了浏览器前缀之外, patch style 还出需要去处理一个非常重要的一个协助, 那就是指定就 vga show。 当元素存在冒 style 动态 style 和绑定和 vga show 的 时候,如果 style 动态 style 设置 display, vga show 显示时应该恢复。这时如果 vga show 隐藏元素 display now 应该覆盖 vga style 这样子一个值。 而这是怎么去实现的?那这是去通过 visual origin display 和 visual hand 这两个标记去做一个实现的。大家可以看到,在这里 visual 的 时候,它去做一个,两个标记去做一个实现。 到这里我们就已经分别看完了 class 和 style 两种最常见的快度镜。接下来进入到一个更加通用,也更加容易踩坑的部分,就同一个键,到底是应该写在到米属性里面,还是写在 html 属性里面呢?而这个就是我们的 should set as proper 该设置哪一个? 需要注意的是, html 元素的属性有两种设置方式,一种是 dom 属性, proper 就是 l 点 value 等于 hero。 还有另外一种是 html 属性,就是 attribute, 就 l 点 set attribute variable 对 应的一个 value 值,大部分 情况两者项目相同,但某些元素属性必须使用特定的方式,而 should set as proper 去决定哪应该去使用哪种,大家一看到它就是对应我们的一个具体的方式,而 should set as proper 去决定哪应该去使用哪种,大家一看到它就是对应的方式,而 should set as proper 就 分为两段。 首先我们来进行一个一对一的讲解,对于 svg 来说, svg 元素大多数属性都必须使用 set attribute, 而对于布尔类型的属性,就比如说 spell, trick, dragon label, a translator creator, 它必须使用 set attribute, 而 i framed setbox 必须使用 attribute, 而 form 属性只读必须使用 set attribute, 而 input 点 list 也是必须使用 set attribute。 test tab 也是使用 set attribute, 而媒体元素,比如说 the west hat 必须使用 set attribute, 那 同时原声事件的再加字母串值也必须使用 attribute。 最有什么呢?如果是盗门属性就用是盗门属性,而刚刚那些只是错掉一看。现在我们来对这些特殊的属性来进行一个讲解。 首先第一个就是每每举值的一个不二属性,像 spin, trick, joy, able, trace, state, out, current 这些属性的到某属性必须是不二值,但 h, t, m, l 属性是每举字母串就 to 和 force 它是一个字母串,那如果是使用到某属性去设置成一个字母串的话,那么会被转为成一个 自创 force 会被转为 true 啊 true 化,所以必须使用 set attribute。 同时 fm 的 sendbox 这个属性去控制 fm 的 安全属性就设置,如果你设置到我们属性为 null, 就 会变成自创 null, 而设置成空自创会使用最严格的杀伤模式,而只有通过 set attribute 和 ensure attribute 才能够正确的处理。下一个就是 input 点 list, input 的 list 它是只关联一个 data data list 属性,而到某属性 a r 点 list 是 只读的返回关联的 data list 是 不能直接复制的,而 form 元素里面 表单元素的 form 属性也是只读的去返回索取的 form 元素,所以这些属性不能直接复制,必须使用 set attribute。 对于一些媒体元素的 words 和 size。 什么是媒体元素?就是 image, video, canvas 和 source 点框高,必须使用 attribute 的 设置。盗墓属性的设置可能是不生效的, 就盗墓属性设置行为不一致而 show set as proper 的 本质是什么?本质是在为后续的两条分支选路。 走到某属性分支意味着更加贴近浏览器对象模型,可能带来类型转换与指读限制。而走 attribute 分 支则更加贴近序列表的 html 表达,就更容易与表单重置,第三方读取逻辑对齐。先把这个选择记住,再看两边的具体时间就比较清晰了。 所以我们来看一下到母属性的设置,就是当 should set as proper 返回 true 时,用 patch down proper 去设置到母属性。大家来看到这是一个 inner html 和 test content 的 一个设置,而下面就是一个 value 属性的特殊处理,对应的这是 这是一些空值处理,以及布尔值就是空字副状场为刚呢,就是我们所看到的一个 value 属性的一个特殊处理, 请注意 value 是 最复杂的盗木属性,因为什么它首先它具有一个比较优化,就只有当新旧值不同时才会去设置,避免不必要的盗木操作。同时 option 处理特殊处理, option 的 value 属性如果没有设置的话会回退到其文本内容,所以是比较时要用 get attribute value 而不是 array value。 同时 check box 的 默认值是 on 而不是空字不串,同时它还会去存储原始值, 非字母串值会被 dom 转为字母串,而 will 会将原始值存在 a r 点杠 value 中去共 v 杠 model 去做实体。 而在上一步我们看到中去设置 in the html 表中, will 会去使用 on serve to transfer html 表包装值去以支持 trusted types 安全策略。而正在上一章章我们就建 已经介绍过了,所以在此我们就不再去追溯了。看完到我们属性的设置,我们来再看看 htm 表的是如何去做处理的,就当 should set as proper 去访问 force 的 时候,我们会去通过 patch or true 来去设置 htm 表属性。首先啊,这是 svg 叉 link 的 命名空间 去做,对那个处理危机中的某些属性必须要叉 link 秘密空间,就比如说啊叉 link, 杠 herf 这些属性必须使用 set attribute n s 设置 set attribute n s 而对于而对于布尔值处理的话, 首先需要注意的是,它存在即表示 true, 不 存在表示 false。 设置值 true 或者空字不算,就是 set attribute key 等于冒号,而 false 或者 null 的 时候属于 null。 attribute key 需要注意它是 including or true 函数,判断一个值是否应该包含不小于属性,而这两种方法需要注意,我们这两种方法的写法是等价的, 走路到 patch or true 这里时,已经覆盖了绝大多数使用需要写入 attribute 的 场景。普通键值,叉令、可秘密空间以及不小于 unk 属性,这是有或者无极帧的特殊语义。但 patch proper 还有一种 不适合直接缩略为字母串的例外,就比如说 real element 需要把复杂值当做属性传递, real 跟 model 相关的 true force value 也需要额外的存储,这就是 real 的 custom element 特殊处理。就当元素是 real 定义的 custom element 的 时候,属性处理是有特殊的逻辑的。在这里我们可以看到 custom element 是 通过 its view c e 标识去识别,对于这些元素包含,它会去做这样子处理,就是包含大写字母的属性值会被转为驼峰形式,非字母串的值会作为盗门属性设置,而不是缩列为字不串。 这使得 view 组键可以通过 custom element 去接收复杂的 purpose 值。而除了 custom element, view 杠 model 在 script 上的真自定义真假值也需要特殊的存储。 在这里我们可以看到六杠 model 在 支持自定义的真假值,这也是通过 achieve variable 等于 yes, force 等于杠 value。 这些值并不是标准的 html 属性,不能通过 set attribute 设置 will 将它们存储在原数的自定义属性上。去 这里我们就可以看到了,它是通过啊 r 点杠去 value elegant 点杠 force value 去存储在元素的自定义属性上。 view 杠 model 指定会在处理 check box 上自动去读取这些值,哎,最后我们来看看表单元素为什么需要特殊的双重设置策略。对于 value, 去 tricked, selected 这三个属性 view, 它会去同时设置 dom 属性。 html 属性为什么需要双龙设置呢?这是因为表达了重置,比如说 input type and reset 会将表达元素重置为 html 属性值,同时为了去做一些第三方库的一个接龙,就比如说某些库或者浏览器扩展 可能会去读取 html 属性,而不是 dom 属性。注意,需要注意的是, custom element 标签名包含杠会被排除在外。最后我们再看一个属性处理流程图。 首先,对于一个 patch proper, 它会去读它的 key, key 是 什么?就是它对应的是 class style, on 还是其他的,那对于 class, 它会进行 patch class 对 于 style, 它会进行 patch style。 对 于 on, 是 v 杠 model 兼容器,它会去做。 如果是否他会去做一个 patch event, 而 patch event 将会是我们下节章节的重点,而如果是的话,请跳过。对于检查修饰符,如果是点 proper, 如果是 attribute, 如果是无修饰符,去分别的去对应它进行下一步的操作。对啊,屏幕有点小,可能看不全。 如果将它当成一个流水线来看,前半段主要负责高频而确定的快捷操作,而后半段主要是负责低频但必须正确的边界接龙,而事件系统 则是一个被单独隔离的出来的高频模块。而下一章我们会去看它为什么需要这样设计,那我们来看一下本章节的一个小结。 patch proper 是 real 属性的核心,它根据属性类型将处理分发给专门的函数 a patch class, 利用 class name 直接复制实现高效的更新。 a patch style 它会去通过智能的 def 去避免不必要的到幕操作。 a should set as proper 会去处理到幕属性与 html 的 复杂边界情况。这套系统体现了 view 对 性能的极致追求,能用盗门属性就不用 set attribute, 能直接赋值就不用 casteist。 同时它还处理了大量的边界情况,确保在各种场景都能够正常工作。下面我来回看一下本章节的深入思考。 首先,一为什么 input list 等于 data list 杠低,必须使用 set attribute 而不能用 dom 属性呢?如果强制使用 dom 会发生什么问题?二就是 patch style 的 diff 算法在什么情况下效率最高,在什么情况下效率最低呢?有没有什么优化的空间? 第三点就是 should set as proper 中为什么 fframe 的 data box 属性需要特殊处理?第四个是为什么 will 为什么要在表单元素上去同时设置 dom 属性和 html 属性呢?好的,我们本章节就到此结束了,欢迎大家点阅、点赞、订阅以及分享我的频道,我们下期节目再见!

前端面试题全网搜到眼花,海量资料越刷越迷茫,别再走弯路了,我花了半年时间整理筛选录制了这套前端面试高频核心题,高频考点精讲加载码实战,看这一套就够了,为你配备了全套题目 pdf 三连后留言前端带走学习。 哈喽,大家好,我是方格,上一节课呢,我们介绍了 vivo 的 叉槽,今天呢,我们就来聊一下 vivo 叉槽里面经常让人困惑的一个问题啊,就是座右 很多人在使用叉槽时会遇到数据访问不到的情况,其实呢,这就是啊,数据作用域归属的问题。我们来看两个常见的痛点,一个是叉槽的内容里面访问不到子组件的数据。 第二个痛点呢,就是这个,不清楚到底该用哪个组件的数据啊,我们一起今天这节课呢,我们就一起来理清这个概念 啊。首先这里有个关键的原则啊啊,叉槽的内容,它的作用域归属于父主键,而不是子主键。 简单来说呢,就是你在这个叉槽里的写的代码,像啊,就像在父主键,就像写在父主键里一样, 只能访问副主键的数据。叉槽在子主键里面只是一个占位符,相当相当于说啊,这里以后会放东西,但是具体放什么,放的数据从哪里来,都是从副主键里面决定的。 我们用一个用一段代码来具体看一下,现在我们首先来看这段副主键的代码 啊,注意看这里啊,当我们啊在这个 template 里面去写用了这个 try 的 component 是 吧,然后在这个操槽里面直接写了这个 parent message, 这是一个父祖键的数据啊,它这段这段这行代码是可以 正常访问的,但是呢,呃,如果你尝试在叉槽里面去访问这个子组键里面的 try 的 data 就 会报错,因为 try data 就 属于子组键的作用域。 我们来看一下这个例子,大家可以看到啊,这个实际的运行势例里面呢,副主键啊,这个来自副主键的数据啊,在叉槽里面是可以正常显示的, 但是啊,当我们在这访问这个 try 的 data 时啊,这个页面上并没有显示,说明这个数据是 unify 的, 那么这就证明了叉槽内容确实是在副主键的作用域里面。 所以从刚才的例子里呢,我们可以总结出三个关键点,第一,这个叉槽的内容 呃的作用域在副主键,所以只能访问副主键的数据。第二呢,叉槽的渲染位置在子主键,但是作用力不变。第三,这个数据流是单向的,副主键的数据可以流向叉槽,但是子主键的数据不能直接访问, 那么有什么呃,解决办法呢?我们看看怎么解决这个问题啊, 我们现在看一下这个子主键的代码,注意这里有个关键变化,我们在 slot 标签上加上了这个呃, child data 和 child method, mail child data 和 mail child method 这两个方法, 那么这就是作用域叉槽的核心用法,通过这样的绑定子主键就把自己的数据给暴露给了副主键,我们现在来看看副主键里面怎么使用它。 那么大家现在看这段副主键的代码啊,这里展示了两种叉槽的用法,一,上面是啊, 上面是普通的叉槽,然后下面呢啊是作用于叉槽,我们可以看一下这个下面的写法 啊,这里有个警号 default, 然后定义了一个 slot props, 这里的 slot props 就是 我们给接收参数起的名字, 当我们这样写时, will 就 会自动地把这个子组键通过 slot 属性绑定的所有数据都收集到这个啊一个对象里,然后传给这个 slot props 这个参数。 所以在这个作用域叉槽里面,作用域叉槽里面,我们就可以通过 slot props 访问它们的 try data 和 try method 这样的数据和方法了, 所以你可以把它理解成一个数据包裹,里面装着子组件暴露出来的所有方法和内容。 那么这就是解决作用于问题的标准方法。好理解了,方法呢,我们现在来看一下使用他们的最佳实践。那么在实际开发中,我们要遵循几个设计原则,首先呢,要明确数据的归属,谁的数据谁负责。 其次呢,要啊避免作用与污染,不要在这个叉槽里访问不该访问的数据。最后呢,就是保持主键的独立性,通过 props 和事件来通信。嗯, 呃,那么大家可能在开发里面可能会有一些常见的错误啊,我们这里也总结一下啊,第一就是数据没有定义的错误啊,比如说在这个叉槽里直接访问子主键的数据。 第二呢,就是 props 传递的错误,你忘记在 store 上绑定属性啊,你可能就会导致传传输错误,那这些错误就会导都会导致运行时的异常啊,需要特别注意。嗯, 所以为了避免这些错误呢,我们在写这个相关代码时,都会要问自己三个问题,第一,你的叉槽内容用的是谁的数据?如果是子主键的数据,就要用作用域叉槽 啊。第二呢,就是子主键的数据是如何传递的啊,通过 slots 属性绑定。 第三就是这个啊,作用边界是否是清晰的啊,不要让这个数据访问变得混乱,这就是我们写代码时经常要注意的点。 好,今天啊,我们学习了这个叉槽的一些作用域,今天,呃,让我们现在来回顾一下今天学习的重点, 他的核心概念就是啊,插槽的内容的作用域属于副主键,这是最基本的原则。那么正确的使用模式就是通过插作用域插槽来访问子主键的数据。 我们还要避免一些常见的陷阱,比如说啊,直接访问子主键的数据啊,导啊,忘记绑定,忘记绑定数据了, 那么记住这个原则,你使用叉槽时就会更加得心应手了啊。好,以上就是本节课的内容啊,我是方格,今天的内容就讲到这,如果觉得你啊,对你有帮助的话,欢迎点个赞啊,我们下节课再见!拜拜!

大家注意全部这俩字啊,现在他的位置是正常的,但是如果选了一个选项,就张三看看就错位了,这个问题我复现了好久,终于在这个呆萌里给他复现出来哈,那什么原因呢?哈,其实不是什么样,是设置了什么高度来注意,我双击一下这个地方,大家注意看 他这块竟然有空格,还有换行,我把这个空格换行都删掉看看就没问题了,我再刷新一下还得回来。 但是也很奇怪,因为正常来说 h tm 标签是会忽略里边的换行的哈,它又不是 pre 标签,如果是 pre 标签还能理解。后来我发现其实是 v x e tab 在 表头里做了一个样式,就是这种 v x e style 里边它有一个 y space, 这个 在这里 white space 等于 pre light, 当然除了这个还有几个其他的值哈,但是大概意思就是有点像 pre 标签,打开我把它去掉,哎,就好了, 加上就可以了。但是这还没完,我们仔细思考会发现为什么,就是为什么这里边会有换行和空格,我们来看一下原码啊。在这里 就是如果他选择了一个,就是这个是张三,那张三放在这相当于这个空格和换行,还有这一部分都没有被编辑器去掉,而这个全部没有问题,那我们可以在这个页面的上面再试一下,比如我们写个 db 啊, 加两个换行 test, 你 看一下在这里打开 他还是没有被去掉,所以到这呢问题就可以定位到是全局的配置问题了哈,那这个就比较有意思了,我们看一下这个 vivo 的 配置啊,这个还跟呃 vivo 的 版本有关系,就是 vivo 二点五之前他只有一个这个配置, 这个位置是干啥的呢?他是去掉两个标签中间的空格用的。我们举个例子哈,比如现在这个 dna 里边写两个 spa 吧, a、 b, c, 然后这两个换行,再来一次半 b, c, d, 就是 这中间是有几个换行和空格的哈,然后他默认呢?他是不保留的,就是默认他是 false 不 保留的。我们先看下效果吧, 我们选到这个属性,就选到它负一级的这个,然后在这用到了零点叉幺的 note, 但这有两个,对吧?但如果我把它配置成处,这个需要重启一下啊,我们再刷新一下,大家看啊, 我选择这,这还是看不出来,我们需要用这种方法,大家看它中间就多了一个 text 标签,相当于这个 text 的 还不会保留下来了, 但是呢,即使我们把它改成 false, 就是 不保留,就恢复到它的默认值啊,大家看啊,这个问题也解决不了,看看这里边的空格,他是不会被去掉的,他只会去掉像这种 两个标签中间的这个空格。然后在 vivo 二点六以后呢, 就多了这么一个配置,这个 white space。 那 有了这个以后,其实上面这个就不用了啊,他默认是 preserve, 就是 保留的,我们可以把它改成 can, 改成这个。 这个的话呢,其实就是他会这个也会去掉,像原来的这种他也会去掉,然后页面里这种他也会去掉,我们重启一下项目啊, 看一下,大家看,首先这个去掉了没有?那个 text 了,咱们再看这个 他也会被去掉的啊,已经对齐了,他也不是去掉,他也会变成一个的啊,两边这有一个空格,但这已经没有问题了。然后还有一个比较有意思的地方啊,就是如果我都不配他默认,刚才说了他默认是 这个配置啊,其实也不一定,或者说从表现层面来说,它默认不一定是这个哈,因为它最终还要取决于这 client server, 它在内部它掉的时候它会传来什么参数。这 client server 如果你用四点零以上的版本,然后你这个配置你不配,它也会自动默认是 contents, 就是 它会压缩空格,然后在四点零以下的版本,三点九几啊,这种 他默认就会保留空格,这个我们可以试一下,比如现在是我不配他了,注视掉了,然后把它改成四点零点零,然后这个四点零点零我们重启一下,重新下载一下, 现在换成四点零的版本了,然后现在呢也没有配置这两个属性,大家看表现啊, 这样就没有问题了。所以具体大家在操作的时候关注一下自己的这个 client server 的 这个版本,看是否大于四点零,然后回到最开始那个问题啊,其实最好的 习惯就是把这,我们把它这样写,像这种比较简单的,这样他就一定没有问题了。

应该有了吧。啊,好,那这就其实就是我们第一个大的一个探头点啊,那我们再去细化一下, 细化一下啊,就是如果是 view 的 同学,你的整个 ai 全站的体系, ai 全栈的进阶体系,应该是什么样子的?好,我这里快速给大家去梳理一下前端的框架,那这个不用说了, view 对 吧,因为都是 view 的 同学嘛。然后呢,在前端到服务端中间的这一层桥接和过渡,你就用 next g s 来去过渡 next g s 过渡 啊,那你的这个打包构建呢?这些呢,你都可以先不考虑,那这个是在前端那一层去开发的时候需要考虑的,比如 wait, 现在你就直接把 wait 学精通就完了,不要学 webpack 学 wait 啊,把 wait 学精通, wait 的 打包构建,优化,那个插件化开发,还有 wait 的 原理全部了解就行了。好,然后再在这个基础上 next 再去进阶。哪几部分呢?一个是数据库, 数据库的应用层啊,数据库应用层我们一般称之为 o r m, 这是最大目前最低成本的学习的一个方向。在呢,数据库的选择,大家无老去压 postgrad circle 啊,现在直接去往 postgrad circle 去学习就行了,不要去看什么 mongol db, 还有什么 my circle, 大家千万不要相信了啊,直接相信我的 postgrad circle。 为什么大家去看一看 github training, 还有呢?看一下整个技术圈的一些趋势大家就知道了, pg 现在是毫无疑问的 number one, 然后呢,你想一想, pg 的 一个 d 代码我不知道大家听说过没有,就是有个 pg 的 那个 pg d 代码就是 no code, no code platform 叫什么呢?叫 superbase, 我 不知道大家有没有听说过的同学, superbase 啊? superbase 应该大家听说过吧, superbase 啊,好,所以呢,大家一定啊,就是相信我的往 pg 这个方向去学,因为 pg 它不仅是能够做业务的数据存储,业务的叫, 呃,那个 circle 存储啊,我们就称之为 circle 存储吧,还可以去做业务的 no circle 存储, no circle 大家应该知道什么?一个是关于数据库,一个是非关于数据库这些点啊,还有呢,包括向量型 p g vector, 它就是个六边形战士啊,这个一个精通,个个通,这种感觉。你再如果说在特定的领域,比如说你在向量数据库矢量存储这一块儿,你要去考虑最优的方案,那可以啊,你还有别的选择,比如说我们再给大家去讲这个内扣子 defy 的 这个项目的时候,给大家讲了 qugent 啊,讲了这个 qugent, 然后呢给大家还讲了,比如说像,呃, mevis, mevis, mevis, 这个我好像打错了, mevis mevis, 那这个其实就是更厉害的了啊,做这个向量存储的,大家就往这个方向去学习去看,当然了,如果说你现在你的阶段具体到了哪一步,如果说跟我这里说的呢,其实有 有超出的这个情况的话,那大家如果说加入进来之后,还可以有更多的帮大家去做一些你现在已有的 ai 方向或者业务方向的一些探索和探讨啊,给大家一些比如说,呃,以我过往 这个近两三年啊,基本上前前后后呢,有负责过了将近一二十个 ai, 直接去那个嵌入的,或者说有 ai 相关业务这种产品啊,到时候可以给大家去呃,探讨探讨,给大家一些方案。好,这是在数据库层,然后呢,再往底层绝对的要学习的一个东西是什么呢? docker, 当然这个上面呢,我忘记还说了一个点啊,这个其实是每位同学,如果,如果你现在还在纠结我到底还要不要学 type script 的 话, 那你有这个想法的,这这一刻你就已经落后了啊,因为什么呢?大家可以看现在的所有的 ai 的 这个框架,我给大家看一眼啊,比如说我随便给大家打开一个 ai 框架啊,比如说我们看一个 nunchaku 吧, 我不说话,大家只看语言支持就行了。同学们,卡吗?卡的同学扣个一,不卡的同学扣个二, 不卡吧,不卡的同学扣个二啊,不卡的同学扣个二。好,那应该不卡啊。同学,如果你卡的话,可以刷新一下,或者检查一下你的网络之后重新再进一下啊, 咱们看到了吗?像比如说 nunchain, 那 python 跟 python 这两个方向,这这两个是官方推荐,也是官方维护的 python 版本和 python 版本跟 python 版本,所以你看,不管是 nunchain 攀 graph 版,你看 python 攀, 大家知道 typescript 重要性了吗?如果你还不知道的话,那我还随便给你来一个第三方的 ai 框架,比如说这个 master, 你 看看这个 master 它用的什么来去开发,那同样也是用 typescript 来开发,对吧?也同样是用 typescript, 你 看 next 也可以, next 也可以啊,这些选择 就是按照我们给他去讲的这个方向,那安装包括呢?最后开发开发的这个过程怎么来去实现?怎么来做?怎么来去定义这些?那个 test agent 来去做这个 agent 的 开发,包括结构化输出等等,大家可以看到啊。所以如果你现在还在纠结要不要学 t s 的 话,那我给你一个建议,或者直接给你下个结论,就是百分百要学 这个,不学的话,那真的会落伍的啊。你现在可以看到开源的那些 ai 的 项目,比如说大家现在知道的,我随便给大家再举个例子啊,大家最近听说过 open code 很 火吧? open code, 那 你看 open code 是 不是源码用 type script 来开吧,它不会用 javascript 的 啊,不会用 javascript, 你 看百分之九十八十六是用的 type script, 对 吧?这种 open code 的 我给大家简单的演示一下都可以。我打开一个项目 啊,比如说我直接 c d 到我,我现在这个项目啊,我现在这个项目叫妙码,呃, 好,在这个项目里面,然后比如说在这儿我直接新,呃,打开 open code, 我 直接让它编码啊,比如说 编写一个,呃, hello world, 不是 not just hello world, 好,直接边写,那这个百分之八十六的代码都是用的它的来写的。然后其次是 cs, 这个呢是它的打包工具,这跟它无关啊, rust 零点五的成分,所以大家知道了这个 t s 的 重要性了吧。大家看下这个 star, 大家就知道这个项目到底火到什么程度,现在只要是涉及到 ai 的 项目呢,都很火,但是 ai 跟前端结合的那也非常多。 好,他现在正在创建这个项目,正在帮我编辑,我来看一下这个编辑完了没有。 helloworld js, 你 看是不是帮我写完了啊?当然这就是个简单的事例啊,帮,我已经写完了。好,那我现在比如说再给他改成 type script 版本,他自己再重新帮我写,我们待会儿等他写完之后我们直接来看就行了啊,这个项目是用的 type script 来写的。那大家知道的还有一个叫 cloud bot 啊,这个是号称可以直接去 那个硅谷的,硅谷最近开发了这个,这个发布了还没多久,叫 cloud boot。 这个呢,可以直接去操控你的电脑完成任何事情啊,比如说操控你的这个 mac, 或者操控你的 linux 来去做任何事情。那你可以看一下这个项目点进去之后,你其实也会发现它的 type script 成分也很高,看到没有八十二点五 啊,这个项目也是八十二点五,里面呢只也只是用了少量的这个,其他的什么 swift 和这些就是做 micros 端的一些差异化的抹平,其他的都是基于 type script。 好,那这里我不再不多说了啊,再不多说了,这个项目呢,同样,呃,开源呢,也才可能一周左右的时间吧,应该 现在 star 数六万多啊,大家也可以去下的试一试。虽然说那个用起来的感觉就好像是只会一个七十岁的老头来操作你的电脑,但是呢,这也是未来一个趋势,等到你哪一天不需要去考虑 tucker 的 消耗,不需要考虑算力的消耗的时候,这种产品终将是未来的一个趋势 啊。它能够去帮你做任何事情,帮你处理 word 文档,帮帮你处理 pdf, 帮你剪视频,帮你回邮件,帮你去发信息,什么所有所有的你只需要在手机上面发个指令,它在电脑端全部帮你去完成啊,就这样的一个项目,这也是基于这个 astropic 跟 open ai 的, 这个大家也可以去了解一下啊。 那所以这个我用实际的例子来告诉了大家,为什么现在要学习 ts, 就是 实实在在的这个例子啊, ts 百分百要学,然后再比如什么 docker 等等啊,那 docker 这个例子呢?也毫无疑问,你看每个项目都会有自己的 docker file, docker file sandbox 和 docker file sandbox browser, 一定会有他的打包构建,所有的这些逻辑都是基于多克,因为大家要想好啊,以后在开发的时候呢,以前啊,同学们,同学们开发不会关注怎么将那个项目设计的好, 我跟你说设计的好的几个标准是什么呢?第一个是环境无关。好,这个环境无关,那就相当于在我的这个环境和在你的电脑上面可以立马能够跑起来,它最终的产物啊,产物环境无关,那这个必须得上虚拟化技术,比如说我们说的容器化技术,对吧? 容器化技术,也就是这个 dk 好, 还要考虑点呢,就是能够尽量的去微内核。什么是微内核呢?就是你本身的主体框架, 主体框架少量代码,然后呢定义对应的插件接入规则,这样的话相当于你可以把你的生态的定制,生态的一个扩展 交给开发者,或者说交给插件开发。有哪些势力呢?我随便举个例子, webpack 本身它的内核很小,但是 webpack 的 内核很小,但是 web 的 插件一大堆, bbc 的 内核很小, bbc 的 插件一大堆。好,然后我们要联系到 ai 相关的一些技术了,大家都听说过 m c p, 对 吧? m c p, 那 其实啊,从早期的 tools 啊,从早期的定义一系列的工具,这些就是 ai tools 工具,它其实也是微类和设计的一种体现。在这个基础上,如果你想把这些工具做到远程,做到服务端,做到远程调用,远程的拉取,或者远程的这个使用,那你就需要上 m c p, 对吧?上了 m c p 以后,如果说你想能够更灵活地通过这种自然语言,或者说通过极设的一些 prompt 来去做它的优化,这就是前段时间火起来的这个 skills 啊,这几个点大家一定要学会,这样去把你的整个思维从前端贯穿到服务端,再从服务端再能够又体现在你的 ai 的 这些体系的开发上面,这个其实才是真正的 提升啊。不是说我学一两个框架,学一两个技术,你就把自己的任督二脉打通了,不是,而是你要去把这些技术点,把它的设计思维,把它里面的架构的这些要点能够融汇贯通,你甚至你随便换个语言,换一个新的表现形式,他底层的原理你是相通的 啊,好,那所以我认为的啊,就是如果从两个点来去概括的话,第一个是容器化技术,第二个是微类核架构,这两个是最重要的。所以呢,容器化技术这个在我们的像那个整个客人的介绍里面呢,也有关于 docker 这部分的介绍啊, docker 准备 docker 的 使用,我们所有的项目的部署和开发和相关的一些那个内容呢?都是基于 docker, 都是基于 docker 啊, 然后呢还有就是这里给大家说的微类和架构设计思想这块呢,也是,如果说要去呃更好的去开发,那我们其实就需要有微类和插件化设计思想的这个储备啊。如何去设计 微类和插件化啊?整个核心的思想是什么?还有呢它的应用包括呢一些开源的优秀的微类和插件化设计思想的一些实力啊。好,这是这部分给大家去说明的点。

ok, 那 我们刚刚看了上一个问题,对吧?直接给一个数值项进行赋值, will 不 会监测到变化,那我们接着就来看,那怎么办呢?也许面试官问完你以上一个问题,他会就会接着问你,那这种情况你是怎么处理的,对吧?那怎么办呢?或者假如没有问上一个问题,他直接问你, will are 的 dollar set 你 是否用过呢? 你有没有用过啊?对吧?这个就是我们关于呃这个 will are 的 第二个问题。首先我们先来看它是干嘛的,好吧,那 dollar set 这个东西哈,我给大家在这写一个这个 dollar size 它是干嘛的呢?这个 api, 它呢是用于向响应式对象中添加新的属性,或者更改现有属性的值,并确保这些变化能被 view 的 响应式系统检测到, 对吧?我们刚刚说了,直接去更改的话,它不会检测到,那这个 dollar size 就是 为了解决这个问题,你看它可以解决,你直接给一个对象或者添加一个新属性,或者 是给一个数组改变它下标原有的值,这个新的值不会被 real 的 响应式系统自动跟踪,也就是这个新的属性发生的变化,试图不会进行更新,对吧?那它呢?就用来改变这个的,那我们来看,我们还按刚刚的例子来看 items, 好 吧,还来看我们的这例子, item area 呢,等于 a, b, c, 对 吧?那我们点击按钮呢,刚刚是直接给它改到下标,对吧?这种的话,我们说了 view 它不会去监测到,对吧?那我们就可以使用 this 点 set 给它去进行一个更新,比如说哈, 我 this 点 set, 然后 this 点 array, array 第二个是什么呢?就是它的,嗯, k 就是 对于对象来说,就是它的属性嘛,对吧?那对于数,嗯,数组来说,就是它的下标,你要改成什么呢?比如说你要改成 d d, d, 我 们还按刚刚的指示来看,哈,那我们再来看 abc, 对 吧?我点击按钮,你看它不仅变了,而且它能被 view 监测到,对吧?它只,而且它就会更新到我们的矢图上了。所以呢,这个 dollar set 就是 为了解决你直接去给一个对象或者呃,修改它原有的属性,或者添加个新的属性, 或者说你直接给数组下标改变一个值,对吧?那它不会被 view 跟踪到,你看不会被 view 系统自动跟踪,那它就不会去 在试图上有任何的变化。那我们这个呢,就是为了解决就让它,哎,我这个东西就是这个 api, 就是 通知系统你要自动跟踪我这个属性,哦,然后呢, 跟踪了之后,我们试图层也就会跟着发生变化了,对吧?所以呢,这个就是我们 dollar set 它的一个使用,以及它的呃,作用是为了来干嘛的?好吧,那 ok, 那 我们今天关于 dollar set 这节课就给大家分享到这里。