开工大吉,送你22个实用的Vue3技巧(2)

对于大多数数据的 id 都是唯一的,这无疑的一个 key 的优选答案。对于任何大多数情况使用 id 作为 key 都不会出现上面 bug。但是如果你需要考虑性能问题,那就就要思考是否应该使用原地复用了。

同样是上面的分页数据展示,如果使用 id 作为 key ,可想而知每一页的每一条数据 id 都是不一样的,所以当换页时两颗 虚拟DOM树 的节点的 key 完全不一致,vue 就会移除原来的节点然后创建新的节点。可想而知效率会更加低下。但是他也有它的优点。唯一的 key 可以帮助 diff 更加精确的为我们绑定状态,这尤其适合数据有独立的状态的场景,例如带输入框或者单选框的列表数据。

所以何时使用 id 作为 key?只有一点:

  1. 无法使用 index 作为 key 的时候

v-if/v-else-if/v-else 中使用 key

可能很多人都会忽略这个点

原因:默认情况下,Vue 会尽可能高效的更新 DOM。这意味着其在相同类型的元素之间切换时,会修补已存在的元素,而不是将旧的元素移除然后在同一位置添加一个新元素。如果本不相同的元素被识别为相同,则会出现意料之外的副作用。

如果只有一个 v-if ,没有 v-else 或者 v-if-else的话,就没有必要加 key 了

相对于 v-for 的 key, v-if/v-else-if/v-else 中的 key 相对简单,我们可以直接写入固定的字符串或者数组即可

<button

v-if=“isEditing”

v-on:click=“isEditing = false”

Save

<button

v-else

v-on:click=“isEditing = true”

Edit

.v-enter-active, .v-leave-active {

transition: all 1s;

}

.v-enter, .v-leave-to {

opacity: 0;

transform: translateY(30px);

}

.v-leave-active {

position: absolute;

}

例如对于上面的代码, 你会发现虽然对 button 添加了 过渡效果, 但是如果不添加 key 切换时是无法触发过渡的

v-for 和 v-if 不要一起使用(Vue2)

此优化技巧仅限于Vue2,Vue3 中对 v-for 和 v-if 的优先级做了调整

这个大家都知道

永远不要把 v-if 和 v-for 同时用在同一个元素上。 引至 Vue2.x风格指南[1]

原因是 v-for 的 优先级高于 v-if,所以当它们使用再同一个标签上是,每一个渲染都会先循环再进行条件判断

注意: Vue3 中 v-if 优先级高于 v-for,所以当 v-for 和 v-if 一起使用时效果类似于 Vue2 中把 v-if 上提的效果

例如下面这段代码在 Vue2 中是不被推荐的,Vue 也会给出对应的警告

    • {{ user.name }}

      我们应该尽量将 v-if 移动到上级 或者 使用 计算属性来处理数据

      • {{ user.name }}

        如果你不想让循环的内容多出一个无需有的上级容器,那么你可以选择使用 template 来作为其父元素,template 不会被浏览器渲染为 DOM 节点

        如果我想要判断遍历对象里面每一项的内容来选择渲染的数据的话,可以使用 computed 来对遍历对象进行过滤

        // js

        let usersActive = computed(()=>users.filter(user => user.active))

        // template

        • {{ user.name }}

          合理的选择 v-if 和 v-show

          v-if 和 v-show 的区别相比大家都非常熟悉了;v-if 通过直接操作 DOM 的删除和添加来控制元素的显示和隐藏;v-show 是通过控制 DOM 的 display CSS熟悉来控制元素的显示和隐藏

          由于对 DOM 的 添加/删除 操作性能远远低于操作 DOM 的 CSS 属性

          所以当元素需要频繁的 显示/隐藏 变化时,我们使用 v-show 来提高性能。

          当元素不需要频繁的 显示/隐藏 变化时,我们通过 v-if 来移除 DOM 可以节约掉浏览器渲染这个的一部分DOM需要的资源

          使用简单的 计算属性

          应该把复杂计算属性分割为尽可能多的更简单的 property。

          • 易于测试
          当每个计算属性都包含一个非常简单且很少依赖的表达式时,撰写测试以确保其正确工作就会更加容易。
          
          • 易于阅读
          简化计算属性要求你为每一个值都起一个描述性的名称,即便它不可复用。这使得其他开发者 (以及未来的你) 更容易专注在他们关心的代码上并搞清楚发生了什么。
          
          • 更好的“拥抱变化”
          任何能够命名的值都可能用在视图上。举个例子,我们可能打算展示一个信息,告诉用户他们存了多少钱;也可能打算计算税费,但是可能会分开展现,而不是作为总价的一部分。
          
          小的、专注的计算属性减少了信息使用时的假设性限制,所以需求变更时也用不着那么多重构了。
          

          引至 Vue2风格指南[2]

          computed 大家后很熟悉, 它会在其表达式中依赖的响应式数据发送变化时重新计算。如果我们在一个计算属性中书写了比较复杂的表达式,那么其依赖的响应式数据也任意变得更多。当其中任何一个依赖项变化时整个表达式都需要重新计算

          let price = computed(()=>{

          let basePrice = manufactureCost / (1 - profitMargin)

          return (

          basePrice -

          basePrice * (discountPercent || 0)

          )

          })

          当 manufactureCost、profitMargin、discountPercent 中任何一个变化时都会重新计算整个 price。

          但是如果我们改成下面这样

          let basePrice = computed(() => manufactureCost / (1 - profitMargin))

          let discount = computed(() => basePrice * (discountPercent || 0))

          let finalPrice = computed(() => basePrice - discount)

          如果当 discountPercent 变化时,只会 重新计算 discount 和 finalPrice,由于 computed 的缓存特性,不会重新计算 basePrice

          functional 函数式组件(Vue2)

          注意,这仅仅在 Vue2 中被作为一种优化手段,在 3.x 中,有状态组件和函数式组件之间的性能差异已经大大减少,并且在大多数用例中是微不足道的。因此,在 SFCs 上使用 functional 的开发人员的迁移路径是删除该 attribute,并将 props 的所有引用重命名为 $props,将 attrs 重命名为 $attrs

          优化前

          优化后

          • 没有this(没有实例)

          • 没有响应式数据

          拆分组件

          什么?你写的一个vue文件有一千多行代码?🤔

          合理的拆分组件不仅仅可以优化性能,还能够让代码更清晰可读。单一功能原则嘛

          源自 slides.com/akryum/vuec…[3]

          优化前

          {{ heavy() }}

          优化后

          由于 Vue 的更新是组件粒度的,虽然每一帧都通过数据修改导致了父组件的重新渲染,但是 ChildComp 却不会重新渲染,因为它的内部也没有任何响应式数据的变化。所以优化后的组件不会在每次渲染都执行耗时任务

          使用局部变量

          优化前

          {{ result }}

          优化后

          {{ result }}

          这里主要是优化前后的组件的计算属性 result 的实现差异,优化前的组件多次在计算过程中访问 this.base,而优化后的组件会在计算前先用局部变量 base,缓存 this.base,后面直接访问 base

          那么为啥这个差异会造成性能上的差异呢,原因是你每次访问 this.base 的时候,由于 this.base 是一个响应式对象,所以会触发它的 getter,进而会执行依赖收集相关逻辑代码。类似的逻辑执行多了,像示例这样,几百次循环更新几百个组件,每个组件触发 computed 重新计算,然后又多次执行依赖收集相关逻辑,性能自然就下降了。

          从需求上来说,this.base 执行一次依赖收集就够了,把它的 getter 求值结果返回给局部变量 base,后续再次访问 base 的时候就不会触发 getter,也不会走依赖收集的逻辑了,性能自然就得到了提升。

          引至 揭秘 Vue.js 九个性能优化技巧[4]

          使用 KeepAlive

          在一些渲染成本比较高的组件需要被经常切换时,可以使用 keep-alive 来缓存这个组件

          而在使用 keep-alive 后,被 keep-alive 包裹的组件在经过第一次渲染后,的 vnode 以及 DOM 都会被缓存起来,然后再下一次再次渲染该组件的时候,直接从缓存中拿到对应的 vnode 和 DOM,然后渲染,并不需要再走一次组件初始化,render 和 patch 等一系列流程,减少了 script 的执行时间,性能更好。

          注意: 滥用 keep-alive 只会让你的应用变得更加卡顿,因为他会长期占用较大的内存

          事件的销毁

          当一个组件被销毁时,我们应该清除组件中添加的 全局事件 和 定时器 等来防止内存泄漏

          Vue3 的 HOOK 可以让我们将事件的声明和销毁写在一起,更加可读

          function scrollFun(){ /* … */}

          document.addEventListener(“scroll”, scrollFun)

          onBeforeUnmount(()=>{

          document.removeEventListener(“scroll”, scrollFun)

          })

          Vue2 依然可以通过 $once 来做到这样的效果,当然你也可以在 optionsAPI beforeDestroy 中销毁事件,但是我更加推荐前者的写法,因为后者会让相同功能的代码更分散

          ES6

          • 列举常用的ES6特性:

          • 箭头函数需要注意哪些地方?

          • let、const、var

          • 拓展:var方式定义的变量有什么样的bug?

          • Set数据结构

          • 拓展:数组去重的方法

          • 箭头函数this的指向。

          • 手写ES6 class继承。

          开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

          微信小程序

          • 简单描述一下微信小程序的相关文件类型?

          • 你是怎么封装微信小程序的数据请求?

          • 有哪些参数传值的方法?

          • 你使用过哪些方法,来提高微信小程序的应用速度?

          • 小程序和原生App哪个好?

          • 简述微信小程序原理?

          • 分析微信小程序的优劣势

          • 怎么解决小程序的异步请求问题?

          其他知识点面试

          • webpack的原理

          • webpack的loader和plugin的区别?

          • 怎么使用webpack对项目进行优化?

          • 防抖、节流

          • 浏览器的缓存机制

          • 描述一下二叉树, 并说明二叉树的几种遍历方式?

          • 项目类问题

          • 笔试编程题:

          最后

          技术栈比较搭,基本用过的东西都是一模一样的。快手终面喜欢问智力题,校招也是终面问智力题,大家要准备一下一些经典智力题。如果排列组合、概率论这些基础忘了,建议回去补一下。

        • 18
          点赞
        • 29
          收藏
          觉得还不错? 一键收藏
        • 0
          评论
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

        当前余额3.43前往充值 >
        需支付:10.00
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包
        实付
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

        1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
        2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

        余额充值